using System;
using System.Runtime.InteropServices;
using UnityEngine;

namespace FRVR
{
    public class TournamentModule : MonoBehaviour
    {
        private FRVRSDK _frvrSDK;

        // Callback storage for IL2CPP compatibility
        private Action<string> _createCallback;
        private Action<string> _createErrorCallback;
        private Action _postScoreCallback;
        private Action<string> _postScoreErrorCallback;
        private Action<string> _getCurrentTournamentCallback;
        private Action<string> _getCurrentTournamentErrorCallback;
        private Action<string> _getMyTournamentsCallback;
        private Action<string> _getMyTournamentsErrorCallback;
        private Action<string> _getActiveTournamentsCallback;
        private Action<string> _getActiveTournamentsErrorCallback;
        private Action<string> _createOrPostScoreCallback;
        private Action<string> _createOrPostScoreErrorCallback;
        private Action _joinCallback;
        private Action<string> _joinErrorCallback;
        private Action _leaveCallback;
        private Action<string> _leaveErrorCallback;
        private Action _invitePlayersCallback;
        private Action<string> _invitePlayersErrorCallback;

        public void Init(FRVRSDK frvrSDK)
        {
            _frvrSDK = frvrSDK;
        }

        public bool IsSupported()
        {
            if (!Application.isEditor && Application.platform != RuntimePlatform.WebGLPlayer)
            {
                return false;
            }

            return _frvrSDK.WrapSDKFunc(
                () => TournamentIsSupportedSDK(),
                () => true // Editor simulation
            );
        }

        public bool IsSupportedAPI(string api)
        {
            if (!Application.isEditor && Application.platform != RuntimePlatform.WebGLPlayer)
            {
                return false;
            }

            return _frvrSDK.WrapSDKFunc(
                () => TournamentIsSupportedAPISDK(api),
                () => true // Editor simulation
            );
        }

        public void GetCurrentTournament(Action<string> onSuccess, Action<string> onError = null)
        {
            if (!Application.isEditor && Application.platform != RuntimePlatform.WebGLPlayer)
            {
                return;
            }

            _frvrSDK.DebugLog("Getting current tournament");

            _getCurrentTournamentCallback = onSuccess;
            _getCurrentTournamentErrorCallback = onError;

            _frvrSDK.WrapSDKAction(
                () =>
                {
                    TournamentGetCurrentTournamentSDK();
                },
                () =>
                {
                    _frvrSDK.DebugLog("Editor: Simulating GetCurrentTournament");
                    onSuccess("{\"id\":\"editor-tournament-001\",\"title\":\"Editor Test Tournament\"}");
                }
            );
        }

        public void PostScore(string tournamentId, int score, Action onSuccess, Action<string> onError = null)
        {
            if (!Application.isEditor && Application.platform != RuntimePlatform.WebGLPlayer)
            {
                return;
            }

            _frvrSDK.DebugLog($"Posting score {score} to tournament {tournamentId}");

            _postScoreCallback = onSuccess;
            _postScoreErrorCallback = onError;

            _frvrSDK.WrapSDKAction(
                () =>
                {
                    TournamentPostScoreSDK(tournamentId, score);
                },
                () =>
                {
                    _frvrSDK.DebugLog("Editor: Simulating PostScore success");
                    onSuccess();
                }
            );
        }

        public void Create(string payloadJson, string title, string sortOrder, long endTime,
            Action<string> onSuccess, Action<string> onError = null)
        {
            if (!Application.isEditor && Application.platform != RuntimePlatform.WebGLPlayer)
            {
                return;
            }

            _frvrSDK.DebugLog($"Creating tournament: {title}");

            _createCallback = onSuccess;
            _createErrorCallback = onError;

            _frvrSDK.WrapSDKAction(
                () =>
                {
                    TournamentCreateSDK(payloadJson, title, sortOrder, endTime.ToString());
                },
                () =>
                {
                    _frvrSDK.DebugLog("Editor: Simulating Create tournament success");
                    onSuccess("editor-tournament-" + UnityEngine.Random.Range(1000, 9999));
                }
            );
        }

        public void GetMyTournaments(Action<string> onSuccess, Action<string> onError = null)
        {
            if (!Application.isEditor && Application.platform != RuntimePlatform.WebGLPlayer)
            {
                return;
            }

            _frvrSDK.DebugLog("Getting my tournaments");

            _getMyTournamentsCallback = onSuccess;
            _getMyTournamentsErrorCallback = onError;

            _frvrSDK.WrapSDKAction(
                () =>
                {
                    TournamentGetMyTournamentsSDK();
                },
                () =>
                {
                    _frvrSDK.DebugLog("Editor: Simulating GetMyTournaments");
                    onSuccess("{\"tournaments\":[]}");
                }
            );
        }

        public void GetActiveTournaments(Action<string> onSuccess, Action<string> onError = null)
        {
            if (!Application.isEditor && Application.platform != RuntimePlatform.WebGLPlayer)
            {
                return;
            }

            _frvrSDK.DebugLog("Getting active tournaments");

            _getActiveTournamentsCallback = onSuccess;
            _getActiveTournamentsErrorCallback = onError;

            _frvrSDK.WrapSDKAction(
                () =>
                {
                    TournamentGetActiveTournamentsSDK();
                },
                () =>
                {
                    _frvrSDK.DebugLog("Editor: Simulating GetActiveTournaments");
                    onSuccess("{\"tournaments\":[]}");
                }
            );
        }

        public void Join(string tournamentId, Action onSuccess, Action<string> onError = null)
        {
            if (!Application.isEditor && Application.platform != RuntimePlatform.WebGLPlayer)
            {
                return;
            }

            _frvrSDK.DebugLog($"Joining tournament {tournamentId}");

            _joinCallback = onSuccess;
            _joinErrorCallback = onError;

            _frvrSDK.WrapSDKAction(
                () =>
                {
                    TournamentJoinSDK(tournamentId);
                },
                () =>
                {
                    _frvrSDK.DebugLog("Editor: Simulating Join tournament success");
                    onSuccess();
                }
            );
        }

        public void Leave(Action onSuccess, Action<string> onError = null)
        {
            if (!Application.isEditor && Application.platform != RuntimePlatform.WebGLPlayer)
            {
                return;
            }

            _frvrSDK.DebugLog("Leaving tournament");

            _leaveCallback = onSuccess;
            _leaveErrorCallback = onError;

            _frvrSDK.WrapSDKAction(
                () =>
                {
                    TournamentLeaveSDK();
                },
                () =>
                {
                    _frvrSDK.DebugLog("Editor: Simulating Leave tournament success");
                    onSuccess();
                }
            );
        }

        public void InvitePlayers(string optionsJson, Action onSuccess, Action<string> onError = null)
        {
            if (!Application.isEditor && Application.platform != RuntimePlatform.WebGLPlayer)
            {
                return;
            }

            _frvrSDK.DebugLog("Inviting players to tournament");

            _invitePlayersCallback = onSuccess;
            _invitePlayersErrorCallback = onError;

            _frvrSDK.WrapSDKAction(
                () =>
                {
                    TournamentInvitePlayersSDK(optionsJson);
                },
                () =>
                {
                    _frvrSDK.DebugLog("Editor: Simulating InvitePlayers success");
                    onSuccess();
                }
            );
        }

        public void CreateOrPostScore(string payloadJson, string title, string sortOrder, long endTime,
            int score, Action<string> onSuccess, Action<string> onError = null)
        {
            if (!Application.isEditor && Application.platform != RuntimePlatform.WebGLPlayer)
            {
                return;
            }

            _frvrSDK.DebugLog($"CreateOrPostScore: score={score}, title={title}");

            _createOrPostScoreCallback = onSuccess;
            _createOrPostScoreErrorCallback = onError;

            _frvrSDK.WrapSDKAction(
                () =>
                {
                    TournamentCreateOrPostScoreSDK(payloadJson, title, sortOrder, endTime.ToString(), score);
                },
                () =>
                {
                    _frvrSDK.DebugLog("Editor: Simulating CreateOrPostScore - creating new tournament");
                    onSuccess("{\"action\":\"created\",\"tournamentId\":\"editor-tournament-" +
                        UnityEngine.Random.Range(1000, 9999) + "\"}");
                }
            );
        }

        // JSLib callback methods
        internal void HandleTournamentCreateComplete(string tournamentId)
        {
            _createCallback?.Invoke(tournamentId);
        }

        internal void HandleTournamentCreateError(string errorJson)
        {
            _createErrorCallback?.Invoke(errorJson);
        }

        internal void HandleTournamentPostScoreComplete()
        {
            _postScoreCallback?.Invoke();
        }

        internal void HandleTournamentPostScoreError(string errorJson)
        {
            _postScoreErrorCallback?.Invoke(errorJson);
        }

        internal void HandleTournamentGetCurrentTournamentComplete(string tournamentJson)
        {
            _getCurrentTournamentCallback?.Invoke(tournamentJson);
        }

        internal void HandleTournamentGetCurrentTournamentError(string errorJson)
        {
            _getCurrentTournamentErrorCallback?.Invoke(errorJson);
        }

        internal void HandleTournamentGetMyTournamentsComplete(string tournamentsJson)
        {
            _getMyTournamentsCallback?.Invoke(tournamentsJson);
        }

        internal void HandleTournamentGetMyTournamentsError(string errorJson)
        {
            _getMyTournamentsErrorCallback?.Invoke(errorJson);
        }

        internal void HandleTournamentGetActiveTournamentsComplete(string tournamentsJson)
        {
            _getActiveTournamentsCallback?.Invoke(tournamentsJson);
        }

        internal void HandleTournamentGetActiveTournamentsError(string errorJson)
        {
            _getActiveTournamentsErrorCallback?.Invoke(errorJson);
        }

        internal void HandleTournamentJoinComplete()
        {
            _joinCallback?.Invoke();
        }

        internal void HandleTournamentJoinError(string errorJson)
        {
            _joinErrorCallback?.Invoke(errorJson);
        }

        internal void HandleTournamentLeaveComplete()
        {
            _leaveCallback?.Invoke();
        }

        internal void HandleTournamentLeaveError(string errorJson)
        {
            _leaveErrorCallback?.Invoke(errorJson);
        }

        internal void HandleTournamentInvitePlayersComplete()
        {
            _invitePlayersCallback?.Invoke();
        }

        internal void HandleTournamentInvitePlayersError(string errorJson)
        {
            _invitePlayersErrorCallback?.Invoke(errorJson);
        }

        internal void HandleTournamentCreateOrPostScoreComplete(string resultJson)
        {
            _createOrPostScoreCallback?.Invoke(resultJson);
        }

        internal void HandleTournamentCreateOrPostScoreError(string errorJson)
        {
            _createOrPostScoreErrorCallback?.Invoke(errorJson);
        }

#if UNITY_WEBGL
        [DllImport("__Internal")]
        private static extern bool TournamentIsSupportedSDK();

        [DllImport("__Internal")]
        private static extern bool TournamentIsSupportedAPISDK(string api);

        [DllImport("__Internal")]
        private static extern void TournamentGetCurrentTournamentSDK();

        [DllImport("__Internal")]
        private static extern void TournamentPostScoreSDK(string tournamentId, int score);

        [DllImport("__Internal")]
        private static extern void TournamentCreateSDK(string payloadJson, string title, string sortOrder, string endTime);

        [DllImport("__Internal")]
        private static extern void TournamentGetMyTournamentsSDK();

        [DllImport("__Internal")]
        private static extern void TournamentGetActiveTournamentsSDK();

        [DllImport("__Internal")]
        private static extern void TournamentCreateOrPostScoreSDK(string payloadJson, string title, string sortOrder, string endTime, int score);

        [DllImport("__Internal")]
        private static extern void TournamentJoinSDK(string tournamentId);

        [DllImport("__Internal")]
        private static extern void TournamentLeaveSDK();

        [DllImport("__Internal")]
        private static extern void TournamentInvitePlayersSDK(string optionsJson);
#else
        private static bool TournamentIsSupportedSDK() { return false; }
        private static bool TournamentIsSupportedAPISDK(string api) { return false; }
        private static void TournamentGetCurrentTournamentSDK() { }
        private static void TournamentPostScoreSDK(string tournamentId, int score) { }
        private static void TournamentCreateSDK(string payloadJson, string title, string sortOrder, string endTime) { }
        private static void TournamentGetMyTournamentsSDK() { }
        private static void TournamentGetActiveTournamentsSDK() { }
        private static void TournamentCreateOrPostScoreSDK(string payloadJson, string title, string sortOrder, string endTime, int score) { }
        private static void TournamentJoinSDK(string tournamentId) { }
        private static void TournamentLeaveSDK() { }
        private static void TournamentInvitePlayersSDK(string optionsJson) { }
#endif
    }

    [Serializable]
    public class TournamentInfo
    {
        public string id;
        public long created;
        public long startTime;
        public long endTime;
    }

    [Serializable]
    public class TournamentInfoArray
    {
        public TournamentInfo[] tournaments;
    }

    [Serializable]
    public class PlatformTournament
    {
        public string id;
        public string contextID;
        public string title;
        public string type;
        public string platformType;
        public string payload;
        public int offset;
        public int count;
        public string[] players;
        public long startTime;
        public long endTime;
    }

    [Serializable]
    public class PlatformTournamentArray
    {
        public PlatformTournament[] tournaments;
    }

    [Serializable]
    public class CreateOrPostScoreResult
    {
        public string action;
        public string tournamentId;
    }
}
