using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using GameAnvil;
using GameAnvil.Defines;
using RPSGame = Com.Nhn.Sample.Protocol;
using static GameAnvil.GameAnvilManager;

public class GameAnvilManagerTester : MonoBehaviour
{
    private GameAnvilManager gameAnvilManager;
    private UIManager UI;
    
    public string managerIp
    {
        get => UI.managerIpInputField.text;
        set => UI.managerIpInputField.text = value;
    }

    public int managerPort
    {
        get => int.Parse(UI.managerPortInputField.text);
        set => UI.managerPortInputField.text = value.ToString();
    }
    
    public string managerAccountId
    {
        get => UI.managerAccountIdInputField.text;
        set => UI.managerAccountIdInputField.text = value;
    }

    public string managerPassword
    {
        get => UI.managerPasswordInputField.text;
        set => UI.managerPasswordInputField.text = value;
    }

    public string managerDeviceId
    {
        get => UI.managerDeviceIdInputField.text;
        set => UI.managerDeviceIdInputField.text = value;
    }

    public string managerServiceName
    {
        get => UI.managerServiceNameInputField.text;
        set => UI.managerServiceNameInputField.text = value;
    }
    
    public string managerUserType
    {
        get => UI.managerUserTypeInputField.text;
        set => UI.managerUserTypeInputField.text = value;
    }

    public string managerChannelId
    {
        get => UI.managerChannelIdInputField.text;
        set => UI.managerChannelIdInputField.text = string.IsNullOrEmpty(value) ? "" : value;
    }
    
    public string managerRoomType
    {
        get => UI.managerRoomTypeInputField.text;
        set => UI.managerRoomTypeInputField.text = value;
    }

    public int managerRoomId
    {
        get => int.Parse(UI.managerRoomIdInputField.text);
        set => UI.managerRoomIdInputField.text = value.ToString();
    }
    
    void Start()
    {
        UI = GameObject.FindWithTag("UIManager").GetComponent<UIManager>();
        
        gameAnvilManager = GameAnvilManager.Instance;
        gameAnvilManager.onStateChange.AddListener(OnManagerStateChanged);
        
        UI.managerLoginButton.onClick.AddListener(ManagerLogin);
        UI.managerLogoutButton.onClick.AddListener(ManagerLogout);
        UI.managerCreateRoomButton.onClick.AddListener(ManagerCreateRoom);
        UI.managerJoinRoomButton.onClick.AddListener(ManagerJoinRoom);
        UI.managerLeaveRoomButton.onClick.AddListener(ManagerLeaveRoom);
        UI.managerUserMatchMakingButton.onClick.AddListener(ManagerMatchUserStart);
        UI.managerRoomMatchMakingButton.onClick.AddListener(ManagerMatchRoom);
        UI.managerCancelMatchMakingButton.onClick.AddListener(ManagerCancelMatchMaking);
    }

    void Update()
    {
        UI.managerLoginState.Set(gameAnvilManager.State == GameAnvilManager.LoginState.LOGIN_COMPLETE);
        UI.managerJoinedRoomState.Set(gameAnvilManager.UserController != null && gameAnvilManager.UserController.IsJoinedRoom);
    }
    
    public void OnManagerStateChanged(GameAnvilManager.LoginState oldState, GameAnvilManager.LoginState newState)
    {
        UI.consoleInputField.text += newState.ToString() + '\n';
    }
    
    public async void ManagerLogin()
    {
        gameAnvilManager.ip = managerIp;
        gameAnvilManager.port = managerPort;
        gameAnvilManager.accountId = managerAccountId;
        gameAnvilManager.deviceId = managerDeviceId;
        gameAnvilManager.password = managerPassword;
        gameAnvilManager.userType = managerUserType;
        gameAnvilManager.channelId = managerChannelId;
        gameAnvilManager.serviceName = managerServiceName;

        try
        {
            var result = await gameAnvilManager.Login(null);
            UI.managerResultCodeInputField.text = result.loginResultCode.ToString();
            UI.managerExceptionInputField.text = null;
            if (result.loginResultCode != LoginResultCode.SUCCESS)
                UI.consoleInputField.text += result.loginResultCode.ToString() + '\n';
            UI.consoleInputField.text += result.loginResultCode.ToString() + '\n';
        }
        catch (Exception e)
        {
            UI.managerResultCodeInputField.text = null;
            UI.managerExceptionInputField.text = e.ToString();
            UI.consoleInputField.text += e.ToString() + '\n';
        }
    }

    public async void ManagerLogout()
    {
        await gameAnvilManager.Logout();
    }
    
    public async void ManagerCreateRoom()
    {
        try
        {
            var result = await gameAnvilManager.UserController.CreateRoom(string.Empty, managerRoomType, ConstantManager.channelId);
            UI.managerRoomResultInputField.text = result.ResultCode.ToString();
            UI.managerRoomIdResultInputField.text = result.Data.RoomId.ToString();
            UI.managerRoomExceptionInputField.text = null;
            UI.consoleInputField.text += result.ResultCode.ToString() + '\n';
            UI.consoleInputField.text += "Room Id : " + result.Data.RoomId + '\n';

            if (result.ResultCode == ResultCodeCreateRoom.CREATE_ROOM_SUCCESS)
            {
                OnEnterRoom();
            }
        }
        catch(Exception e)
        {
            UI.managerRoomResultInputField.text = null;
            UI.managerRoomIdResultInputField.text = null;
            UI.managerRoomExceptionInputField.text = e.ToString();
            UI.consoleInputField.text += e.ToString() + '\n';
        }
    }

    public async void ManagerJoinRoom()
    {
        try
        {
            var result = await gameAnvilManager.UserController.JoinRoom(managerRoomType, managerRoomId, string.Empty);
            UI.managerRoomResultInputField.text = result.ResultCode.ToString();
            UI.managerRoomIdResultInputField.text = result.Data.RoomId.ToString();
            UI.managerRoomExceptionInputField.text = null;
            UI.consoleInputField.text += result.ResultCode.ToString() + '\n';
            UI.consoleInputField.text += "Room Id : " + result.Data.RoomId + '\n';
            
            if (result.ResultCode == ResultCodeJoinRoom.JOIN_ROOM_SUCCESS)
            {
                OnEnterRoom();
            }
        }
        catch (Exception e)
        {
            UI.managerRoomResultInputField.text = null;
            UI.managerRoomIdResultInputField.text = null;
            UI.managerRoomExceptionInputField.text = e.ToString();
            UI.consoleInputField.text += e.ToString() + '\n';
        }
    }
    
    public async void ManagerLeaveRoom()
    {
        try
        {
            var result = await gameAnvilManager.UserController.LeaveRoom();
            UI.managerRoomResultInputField.text = result.ResultCode.ToString();
            UI.managerRoomIdResultInputField.text = null;
            UI.managerRoomExceptionInputField.text = null;
            UI.consoleInputField.text += result.ResultCode.ToString() + '\n';
        }
        catch (Exception e)
        {
            UI.managerRoomResultInputField.text = null;
            UI.managerRoomExceptionInputField.text = e.ToString();
            UI.consoleInputField.text += e.ToString() + '\n';
        }
    }

    public async void ManagerMatchUserStart()
    {
        try
        {
            gameAnvilManager.UserController.OnMatchUserDone += OnManagerMatchUserDone;
            var result = await gameAnvilManager.UserController.MatchUserStart(managerRoomType, "");
            UI.managerRoomResultInputField.text = result.ResultCode.ToString();
            UI.managerRoomIdResultInputField.text = null;
            UI.managerRoomExceptionInputField.text = null;
            UI.consoleInputField.text += result.ResultCode.ToString() + '\n';
        }
        catch (Exception e)
        {
            UI.managerRoomResultInputField.text = null;
            UI.managerRoomIdResultInputField.text = null;
            UI.managerRoomExceptionInputField.text = e.ToString();
            UI.consoleInputField.text += e.ToString() + '\n';
        }
    }

    public void OnManagerMatchUserDone(GameAnvilUserController userController, ResultCodeMatchUserDone resultCode, MatchResult matchResult)
    {
        gameAnvilManager.UserController.OnMatchUserDone -= OnManagerMatchUserDone;
        UI.managerRoomResultInputField.text = matchResult.Created.ToString();
        UI.managerRoomIdResultInputField.text = matchResult.RoomId.ToString();
        UI.managerRoomExceptionInputField.text = null;
        UI.consoleInputField.text += "Match Done Result : " + matchResult.Created + '\n';
        UI.consoleInputField.text += "Room Id : " + matchResult.RoomId + '\n';
    }

    public async void ManagerMatchRoom()
    {
        try
        {
            var result = await gameAnvilManager.UserController.MatchRoom(false, false, managerRoomType, ConstantManager.channelId, "");
            UI.managerRoomResultInputField.text = result.ResultCode.ToString();
            UI.managerRoomIdResultInputField.text = result.Data.RoomId.ToString();
            UI.managerRoomExceptionInputField.text = null;
            UI.consoleInputField.text += result.ResultCode.ToString() + '\n';
            UI.consoleInputField.text += "Room Id : " + result.Data.RoomId + '\n';
        }
        catch (Exception e)
        {
            UI.managerRoomResultInputField.text = null;
            UI.managerRoomIdResultInputField.text = null;
            UI.managerRoomExceptionInputField.text = e.ToString();
            UI.consoleInputField.text += e.ToString() + '\n';
        }
    }

    public async void ManagerCancelMatchMaking()
    {
        try
        {
            var result = await gameAnvilManager.UserController.MatchUserCancel(managerRoomType);
            UI.managerRoomResultInputField.text = result.ToString();
            UI.managerRoomIdResultInputField.text = null;
            UI.managerRoomExceptionInputField.text = null;
            UI.consoleInputField.text += result.ToString() + '\n';
        }
        catch (Exception e)
        {
            UI.managerRoomExceptionInputField.text = e.ToString();
            UI.managerRoomIdResultInputField.text = null;
            UI.managerRoomResultInputField.text = null;
            UI.consoleInputField.text += e.ToString() + '\n';
        }
    }

    private void OnEnterRoom()
    {
        Debug.Log("User enter the room.");
        SyncController.Instance.InstantiateSyncObject();
        SyncController.Instance.Instantiate("Character", Vector3.zero, Quaternion.identity);
    }
}
