using System;
using System.Collections.Generic;
using AnyThinkAds.Api;
using AnyThinkAds.Common;
using AnyThinkAds.ThirdParty.LitJson;
using Runtime.ADAggregator;
using UnityEngine;

public class AwardVideoPlayer : ADPlayer, ATRewardedVideoListener
{
    private IATRewardedVideoAdClient _client;
    private Action<bool> _onVideoComplete;
    private ADListenerAggregator _aggregator;
    private bool _autoLoadRegistered;
    private bool _rewardGranted;

    public override void OnInit()
    {
        _client = AnyThinkAds.ATAdsClientFactory.BuildRewardedVideoAdClient();
        _aggregator = new ADListenerAggregator();
        _aggregator.BindAwardVideoListener(_client, this);
    }

    public override void ShowAD(Action onClose, Action<bool> onVideoComplete)
    {
        if (!IsReadly())
        {
            return;
        }

        curState = 0;
        _rewardGranted = false;
        _onVideoComplete = onVideoComplete;
        adListener.onClose = onClose;
        adListener.onVideoComplete = OnVideoComplete;
        var json = new Dictionary<string, string> { { ATConst.SCENARIO, AdScene } };
        var mapJson = JsonMapper.ToJson(json);

        if (UseAutoLoad())
        {
            EnsureAutoLoadRegistered();
            _client.showAutoAd(Key, mapJson);
            return;
        }

        _client.showAd(Key, mapJson);
    }

    private void OnVideoComplete(bool obj)
    {
        _onVideoComplete?.Invoke(obj);
        _onVideoComplete = null;
    }

    public override bool IsReadly()
    {
        if (UseAutoLoad())
        {
            if (_client != null && _client.autoLoadRewardedVideoReadyForPlacementID(Key))
            {
                curState = 2;
                return true;
            }

            return curState == 2;
        }

        if (curState == 2)
        {
            return true;
        }

        if (_client != null && _client.hasAdReady(Key))
        {
            curState = 2;
            return true;
        }

        return false;
    }

    public override void LoadAD()
    {
        if (curState != 0)
        {
            return;
        }

        if (UseAutoLoad())
        {
            EnsureAutoLoadRegistered();
            _client.setAutoLocalExtra(Key, JsonMapper.ToJson(BuildRewardedExtra()));
            curState = _client.autoLoadRewardedVideoReadyForPlacementID(Key) ? 2 : 1;
            return;
        }

        if (_client != null && _client.hasAdReady(Key))
        {
            curState = 2;
            return;
        }

        curState = 1;
        _client.loadVideoAd(Key, JsonMapper.ToJson(BuildRewardedExtra()));
    }

    public void onRewardedVideoAdLoaded(string placementId)
    {
        Debug.Log($"[Topon] Rewarded loaded. placementId={placementId}");
        curState = 2;
    }

    public void onRewardedVideoAdLoadFail(string placementId, string code, string message)
    {
        Debug.LogError($"激励视频加载失败: {message} , code:{code} , placementId: {placementId}");
        curState = 0;
    }

    public void onRewardedVideoAdPlayStart(string placementId, ATCallbackInfo callbackInfo)
    {
        Debug.Log($"[Topon] Rewarded play start. placementId={placementId}");
        NotifyShowStarted();
    }

    public void onRewardedVideoAdPlayEnd(string placementId, ATCallbackInfo callbackInfo)
    {
        Debug.Log($"[Topon] Rewarded play end. placementId={placementId}");
    }

    public void onRewardedVideoAdPlayFail(string placementId, string code, string message)
    {
        Debug.LogError($"激励视频播放失败: {message} , code:{code} , placementId: {placementId}");
        curState = 0;
        adListener.OnShowError();
    }

    public void onRewardedVideoAdPlayClosed(string placementId, bool isReward, ATCallbackInfo callbackInfo)
    {
        Debug.Log($"[Topon] Rewarded closed. placementId={placementId}, reward={isReward}");
        adListener.OnRewardVerify(_rewardGranted || isReward, 1, "");
        adListener.OnAdClose();
    }

    public void onRewardedVideoAdPlayClicked(string placementId, ATCallbackInfo callbackInfo)
    {
        Debug.Log($"[Topon] Rewarded clicked. placementId={placementId}");
    }

    public void onReward(string placementId, ATCallbackInfo callbackInfo)
    {
        Debug.Log($"[Topon] Rewarded reward callback. placementId={placementId}");
        _rewardGranted = true;
    }

    public void startLoadingADSource(string placementId, ATCallbackInfo callbackInfo)
    {
    }

    public void finishLoadingADSource(string placementId, ATCallbackInfo callbackInfo)
    {
    }

    public void failToLoadADSource(string placementId, ATCallbackInfo callbackInfo, string code, string message)
    {
    }

    public void startBiddingADSource(string placementId, ATCallbackInfo callbackInfo)
    {
    }

    public void finishBiddingADSource(string placementId, ATCallbackInfo callbackInfo)
    {
    }

    public void failBiddingADSource(string placementId, ATCallbackInfo callbackInfo, string code, string message)
    {
    }

    public override void OnPlayRequestStarted()
    {
        if (UseAutoLoad())
        {
            EnsureAutoLoadRegistered();
            _client?.setAutoLocalExtra(Key, JsonMapper.ToJson(BuildRewardedExtra()));
        }
    }

    public override int MaxLoadAttempts => ToponAdController.CurrentOptions?.RewardedMaxLoadAttempts ?? base.MaxLoadAttempts;

    public override float LoadRetryDelaySeconds =>
        Math.Max(0f, (ToponAdController.CurrentOptions?.RewardedLoadRetryDelayMs ?? 750) / 1000f);

    public override bool AutoPreloadOnInit => ToponAdController.CurrentOptions?.RewardedPrewarmOnInit ?? true;

    private bool UseAutoLoad()
    {
        return ToponAdController.CurrentOptions?.RewardedAutoLoad ?? true;
    }

    private void EnsureAutoLoadRegistered()
    {
        if (_autoLoadRegistered)
        {
            return;
        }

        _client?.addAutoLoadAdPlacementID(new[] { Key });
        _autoLoadRegistered = true;
    }

    private Dictionary<string, string> BuildRewardedExtra()
    {
        return new Dictionary<string, string>
        {
            { ATConst.USERID_KEY, ADManager.Instance.UserId },
            { ATConst.USER_EXTRA_DATA, "user_extra_data" }
        };
    }

    public override void EnterAdScenario(string scenario)
    {
        if (string.IsNullOrWhiteSpace(scenario) || string.Equals(scenario, "__default__", StringComparison.Ordinal))
        {
            return;
        }

        if (UseAutoLoad())
        {
            EnsureAutoLoadRegistered();
            _client?.entryAutoAdScenarioWithPlacementID(Key, scenario);
            return;
        }

        _client?.entryScenarioWithPlacementID(Key, scenario);
    }
}
