using System.Collections.Generic;
using System.Linq;
using CrazyGames;
using Photon.Pun;
using Photon.Realtime;
using TMPro;
using UnityEngine;

public class LobbyScene : MonoBehaviourPunCallbacks
{
    public TMP_InputField createRoomNameInput;
    public TMP_InputField joinRoomNameInput;
    public TMP_InputField usernameInput;
    public GameObject loadingOverlay;

    // make use of these static flags to avoid repeatedly handling instant multiplayer or invite params logic when the player returns to this scene
    private static bool _instantMultiplayerHandled = false;
    private static bool _inviteParamsHandled = false;

    private void Start()
    {
        PhotonNetwork.AutomaticallySyncScene = true;

        if (!_instantMultiplayerHandled && CrazySDK.Game.IsInstantMultiplayer)
        {
            _instantMultiplayerHandled = true;
            Logger.Log("Instant multiplayer enabled, joining random room...");
            OnJoinRandomRoomClick();
        }

        if (!_inviteParamsHandled && CrazySDK.Game.InviteParams != null)
        {
            _inviteParamsHandled = true;
            Logger.Log(
                $"Invite params found, handling: {string.Join(", ", CrazySDK.Game.InviteParams.Select(kv => $"{kv.Key}={kv.Value}"))}"
            );
            HandleInitialInviteParams(CrazySDK.Game.InviteParams);
        }

        CrazySDK.User.GetUser(
            (user) =>
            {
                if (user != null)
                {
                    usernameInput.text = user.username;
                    PhotonNetwork.NickName = user.username;
                }
                else
                {
                    usernameInput.text = "Guest" + Random.Range(1000, 9999);
                    PhotonNetwork.NickName = usernameInput.text;
                }
            }
        );
        usernameInput.onValueChanged.AddListener(
            (value) =>
            {
                PhotonNetwork.NickName = value;
            }
        );
    }

    // similar to JoinRoomListener in JoinListenerSingleton
    private void HandleInitialInviteParams(Dictionary<string, string> inviteParams)
    {
        if (inviteParams.TryGetValue("regionId", out var regionId))
        {
            if (PhotonNetwork.NetworkingClient.CloudRegion != regionId)
            {
                // in this case you ideally present the player with a popup asking them if they want to switch to the correct region, but for simplicity we'll just log an error and not join the room
                Logger.LogError(
                    "Invite params specify region "
                        + regionId
                        + " but current Photon region is "
                        + PhotonNetwork.NetworkingClient.CloudRegion
                        + ", not joining room"
                );
                return;
            }
        }
        if (inviteParams.TryGetValue("roomName", out var roomName))
        {
            loadingOverlay.SetActive(true);
            PhotonNetwork.JoinRoom(roomName);
        }
    }

    public void OnCreateRoomClick()
    {
        var roomName = createRoomNameInput.text;
        if (string.IsNullOrEmpty(roomName))
        {
            return;
        }
        loadingOverlay.SetActive(true);
        PhotonNetwork.CreateRoom(roomName, new RoomOptions { MaxPlayers = 4 });
    }

    public void OnJoinRoomClick()
    {
        var roomName = joinRoomNameInput.text;
        if (string.IsNullOrEmpty(roomName))
        {
            return;
        }
        loadingOverlay.SetActive(true);
        PhotonNetwork.JoinRoom(roomName);
    }

    public void OnJoinRandomRoomClick()
    {
        loadingOverlay.SetActive(true);
        PhotonNetwork.JoinRandomOrCreateRoom(roomOptions: new RoomOptions { MaxPlayers = 4 });
    }

    public override void OnJoinedRoom()
    {
        Logger.Log("Joined room: " + PhotonNetwork.CurrentRoom.Name);
        if (PhotonNetwork.IsMasterClient)
        {
            PhotonNetwork.LoadLevel("Room");
        }
    }

    public override void OnCreateRoomFailed(short returnCode, string message)
    {
        loadingOverlay.SetActive(false);
        Logger.LogError("Failed to create room: " + message);
    }

    public override void OnJoinRoomFailed(short returnCode, string message)
    {
        loadingOverlay.SetActive(false);
        Logger.LogError("Failed to join room: " + message);
    }

    public override void OnJoinRandomFailed(short returnCode, string message)
    {
        loadingOverlay.SetActive(false);
        Logger.LogError("Failed to join random room: " + message);
    }
}
