using System;
using System.Globalization;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

namespace MajacloudSdk.Samples.Starter
{
    /// <summary>Reusable "claim reward" button with a cooldown countdown driven by the server's next_claim_at.</summary>
    public sealed class DailyRewardButton : MonoBehaviour
    {
        [SerializeField] private string rewardKey = "daily_coins";
        [SerializeField] private Button button;
        [SerializeField] private TMP_Text label;
        [SerializeField] private TMP_Text countdownLabel;

        private DateTime? _nextClaimAt;
        private bool _busy;

        public string RewardKey
        {
            get => rewardKey;
            set => rewardKey = value;
        }

        public event Action<MajacloudRewardClaim> Claimed;

        private void Awake()
        {
            if (button != null) button.onClick.AddListener(Claim);
            if (StarterController.Instance != null && !string.IsNullOrEmpty(StarterController.Instance.RewardKey)) rewardKey = StarterController.Instance.RewardKey;
        }

        private void OnEnable() => RefreshState();

        private void Update()
        {
            if (!_nextClaimAt.HasValue) return;
            var remaining = _nextClaimAt.Value - DateTime.UtcNow;
            if (remaining <= TimeSpan.Zero)
            {
                _nextClaimAt = null;
                SetReady();
                return;
            }
            if (countdownLabel != null) countdownLabel.text = "Next in " + remaining.ToString(remaining.TotalHours >= 1 ? @"h\h\ mm\m" : @"mm\m\ ss\s", CultureInfo.InvariantCulture);
        }

        public async void RefreshState()
        {
            if (!Majacloud.IsInitialized || !Majacloud.Auth.IsSignedIn) return;
            var rewards = await Majacloud.Rewards.ListAsync();
            if (this == null || !rewards.Ok) return;
            foreach (var reward in rewards.Value)
            {
                if (reward.RewardKey != rewardKey) continue;
                if (label != null) label.text = "Claim " + reward.Name + " (+" + reward.Amount.ToString("0.##", CultureInfo.InvariantCulture) + " " + reward.Currency + ")";
                if (reward.Claimable == false && reward.NextClaimAt.HasValue) SetCooldown(reward.NextClaimAt.Value);
                else SetReady();
                return;
            }
            if (label != null) label.text = "Reward \"" + rewardKey + "\" not found";
            if (button != null) button.interactable = false;
        }

        public async void Claim()
        {
            if (_busy || !Majacloud.IsInitialized) return;
            _busy = true;
            if (button != null) button.interactable = false;
            var result = await Majacloud.Rewards.ClaimAsync(rewardKey);
            if (this == null) return;
            _busy = false;
            if (!result.Ok)
            {
                if (result.Error.Code == MajacloudErrorCode.Conflict)
                {
                    var next = result.Error.GetDetailDateTime("next_claim_at");
                    if (next.HasValue) SetCooldown(next.Value);
                    StarterController.Toast("Already claimed. Come back later.", true);
                    return;
                }
                if (button != null) button.interactable = true;
                StarterController.Toast(result.Error.Message, true);
                return;
            }
            StarterController.Toast("+" + result.Value.Amount.ToString("0.##", CultureInfo.InvariantCulture) + " " + result.Value.Currency + " · balance " + result.Value.Balance.ToString("0.##", CultureInfo.InvariantCulture));
            if (result.Value.NextClaimAt.HasValue) SetCooldown(result.Value.NextClaimAt.Value);
            else SetReady();
            Claimed?.Invoke(result.Value);
        }

        private void SetCooldown(DateTime nextClaimAt)
        {
            _nextClaimAt = nextClaimAt;
            if (button != null) button.interactable = false;
        }

        private void SetReady()
        {
            _nextClaimAt = null;
            if (button != null) button.interactable = true;
            if (countdownLabel != null) countdownLabel.text = string.Empty;
        }
    }
}
