using System;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

namespace MajacloudSdk.Samples.Starter
{
    public sealed class AccountPanel : MonoBehaviour
    {
        [SerializeField] private TMP_Text playerIdLabel;
        [SerializeField] private TMP_Text authTypeLabel;
        [SerializeField] private TMP_InputField nameInput;
        [SerializeField] private Button saveNameButton;
        [SerializeField] private Button linkButton;
        [SerializeField] private Button signOutButton;
        [SerializeField] private TMP_Text logLabel;

        private readonly List<string> _log = new List<string>();
        private MajacloudLinkFlow _pendingFlow;
        private bool _linking;

        private void Awake()
        {
            if (saveNameButton != null) saveNameButton.onClick.AddListener(SaveName);
            if (linkButton != null) linkButton.onClick.AddListener(Link);
            if (signOutButton != null) signOutButton.onClick.AddListener(SignOut);
        }

        private void OnEnable()
        {
            if (!Majacloud.IsInitialized) return;
            Majacloud.Auth.PlayerChanged += Apply;
            Apply(Majacloud.Auth.CurrentPlayer);
#if UNITY_WEBGL && !UNITY_EDITOR
            // Browsers block popups outside a click: prepare the flow now, open it inside the click handler.
            PrepareFlow();
#endif
        }

        private void OnDisable()
        {
            if (Majacloud.IsInitialized && Majacloud.Auth != null) Majacloud.Auth.PlayerChanged -= Apply;
        }

        private void Apply(MajacloudPlayer player)
        {
            if (playerIdLabel != null) playerIdLabel.text = "Player ID: " + (player != null ? player.PlayerId : "–");
            if (authTypeLabel != null) authTypeLabel.text = "Sign-in: " + (player != null ? player.RawAuthType + (player.EmailMasked != null ? " · " + player.EmailMasked : string.Empty) : "–");
            if (nameInput != null && player != null && !nameInput.isFocused) nameInput.text = player.DisplayName;
            if (linkButton != null) linkButton.interactable = player != null && player.IsGuest;
            var label = linkButton != null ? linkButton.GetComponentInChildren<TMP_Text>() : null;
            if (label != null) label.text = player != null && !player.IsGuest ? "Account linked" : "Link account (opens browser)";
        }

        public async void SaveName()
        {
            if (!Majacloud.IsInitialized || nameInput == null) return;
            var result = await Majacloud.Auth.SetDisplayNameAsync(nameInput.text);
            if (this == null) return;
            Log(result.Ok ? "Display name saved" : result.Error.Message);
            StarterController.Toast(result.Ok ? "Name updated" : result.Error.Message, !result.Ok);
        }

        public async void Link()
        {
            if (_linking || !Majacloud.IsInitialized) return;
            _linking = true;
            Log("Starting web sign-in…");
            MajacloudResult<MajacloudPlayer> result;
#if UNITY_WEBGL && !UNITY_EDITOR
            if (_pendingFlow == null || _pendingFlow.Status != MajacloudLinkStatus.Pending || DateTime.UtcNow > _pendingFlow.ExpiresAt)
            {
                var started = await Majacloud.Auth.StartLinkAsync();
                if (this == null) return;
                if (!started.Ok) { _linking = false; Log(started.Error.Message); return; }
                _pendingFlow = started.Value;
            }
            _pendingFlow.OpenInBrowser();
            result = await _pendingFlow.WaitForCompletionAsync();
            _pendingFlow = null;
#else
            result = await Majacloud.Auth.LinkAccountAsync(new MajacloudLinkOptions { PollIntervalSeconds = 2f });
#endif
            if (this == null) return;
            _linking = false;
            if (!result.Ok)
            {
                Log("Link failed: " + result.Error.Message);
                StarterController.Toast(result.Error.Message, true);
                return;
            }
            Log("Linked as " + result.Value.DisplayName + " (" + result.Value.RawAuthType + ")");
            StarterController.Toast("Account linked: " + result.Value.DisplayName);
        }

#if UNITY_WEBGL && !UNITY_EDITOR
        private async void PrepareFlow()
        {
            if (!Majacloud.Auth.IsSignedIn || !Majacloud.Auth.CurrentPlayer.IsGuest) return;
            var started = await Majacloud.Auth.StartLinkAsync();
            if (this != null && started.Ok) _pendingFlow = started.Value;
        }
#endif

        public async void SignOut()
        {
            if (!Majacloud.IsInitialized) return;
            await Majacloud.Auth.SignOutAsync();
            if (this == null) return;
            Log("Signed out. Creating a new guest…");
            var again = await Majacloud.Auth.SignInAnonymouslyAsync();
            if (this == null) return;
            Log(again.Ok ? "Signed in as " + again.Value.DisplayName : again.Error.Message);
            StarterController.Toast(again.Ok ? "New guest session" : again.Error.Message, !again.Ok);
        }

        private void Log(string line)
        {
            _log.Insert(0, DateTime.Now.ToString("HH:mm:ss") + "  " + line);
            if (_log.Count > 12) _log.RemoveAt(_log.Count - 1);
            if (logLabel != null) logLabel.text = string.Join("\n", _log);
        }
    }
}
