using UnityEngine;
using UnityEngine.SceneManagement;
using Photon.Pun;
using Photon.Realtime;
using ExitGames.Client.Photon;

namespace Photon
{
    public class PhotonManager : MonoBehaviourPunCallbacks
    {
        [Header("Made By ShadowApe Studios / Your Fellow Dummy")]
        public static PhotonManager Instance { get; private set; }

        [Header("Photon")]
        [SerializeField] private string AppId;
        [SerializeField] private string VoiceAppId;
        [SerializeField] private string Region = "us";

        [Header("Player")]
        [SerializeField] private Camera LocalCamera;
        [SerializeField] public Transform HeadTarget;

        [Header("Networking")]
        [SerializeField] private string DefaultQueue = "Default";
        [SerializeField] private int DefaultRoomLimit = 16;

        [Header("Auto Connect")]
        [SerializeField] private bool ConnectOnAwake = true;
        [SerializeField] private bool JoinRoomOnConnect = true;

        [Header("Forced Room (Optional)")]
        [SerializeField] private bool ForceJoinSpecificRoom = false;
        [SerializeField] private string ForcedRoomName = "MainRoom";
        [SerializeField] private int ForcedRoomMaxPlayers = 16;

        private void Awake()
        {
            if (Instance != null)
            {
                Destroy(gameObject);
                return;
            }

            Instance = this;
            DontDestroyOnLoad(gameObject);
            SceneManager.sceneLoaded += OnSceneLoaded;

            // VR-safe Photon rates
            PhotonNetwork.SendRate = 30;
            PhotonNetwork.SerializationRate = 30;

            AssignCamera();

            if (ConnectOnAwake)
                Connect();
        }

        private void OnDestroy()
        {
            SceneManager.sceneLoaded -= OnSceneLoaded;
        }

        private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
        {
            AssignCamera();
        }

        private void AssignCamera()
        {
            if (!LocalCamera)
                LocalCamera = Camera.main;

            if (LocalCamera)
                HeadTarget = LocalCamera.transform;
        }

        public void Connect()
        {
            PhotonNetwork.PhotonServerSettings.AppSettings.AppIdRealtime = AppId;
            PhotonNetwork.PhotonServerSettings.AppSettings.AppIdVoice = VoiceAppId;
            PhotonNetwork.PhotonServerSettings.AppSettings.FixedRegion = Region;

            PhotonNetwork.ConnectUsingSettings();
        }

        public override void OnConnectedToMaster()
        {
            if (!JoinRoomOnConnect) return;

            if (ForceJoinSpecificRoom)
            {
                JoinForcedRoom();
                return;
            }

            JoinRandomRoom();
        }

        private void JoinRandomRoom()
        {
            Hashtable props = new Hashtable
            {
                { "queue", DefaultQueue }
            };

            RoomOptions options = new RoomOptions
            {
                MaxPlayers = (byte)DefaultRoomLimit,
                CustomRoomProperties = props,
                CustomRoomPropertiesForLobby = new[] { "queue" }
            };

            PhotonNetwork.JoinRandomRoom(props, options.MaxPlayers);
        }
        [Tooltip("Enable if you want to force players to join a specific room, or enable if you don't have a custom room system implemented.")]
        private void JoinForcedRoom()
        {
            PhotonNetwork.JoinOrCreateRoom(
                ForcedRoomName,
                new RoomOptions { MaxPlayers = (byte)ForcedRoomMaxPlayers },
                TypedLobby.Default
            );
        }

        public override void OnJoinRandomFailed(short returnCode, string message)
        {
            PhotonNetwork.CreateRoom(
                Random.Range(10000, 99999).ToString(),
                new RoomOptions { MaxPlayers = (byte)DefaultRoomLimit }
            );
        }
    }
}
