using System;
using Dirichlet.Mediation;
using Runtime.ADAggregator;
using UnityEngine;

public sealed class TapadnAwardVideoPlayer : ADPlayer, IDirichletRewardVideoAutoAdListener
{
    private const float RewardCloseSettleDelaySeconds = 0.25f;

    private DirichletAdNative _adNative;
    private DirichletRewardVideoAd _loadedAd;
    private bool _rewardVerified;
    private bool _rewardVerifyReceived;
    private bool _closePendingRewardVerify;
    private bool _showSettled;
    private AdTimeHandler _rewardCloseSettleHandler;

    public override int MaxLoadAttempts => TapadnAdController.CurrentOptions?.RewardedMaxLoadAttempts ?? base.MaxLoadAttempts;
    public override float LoadRetryDelaySeconds => Math.Max(0f, (TapadnAdController.CurrentOptions?.RewardedLoadRetryDelayMs ?? 500) / 1000f);
    public override float ShowPendingTimeoutSeconds => Math.Max(1f, (TapadnAdController.CurrentOptions?.RewardedShowTimeoutMs ?? 20000) / 1000f);
    public override bool AutoPreloadOnInit => TapadnAdController.CurrentOptions?.RewardedPrewarmOnInit ?? false;

    public override void OnInit()
    {
        _adNative = DirichletAdManager.CreateAdNative();
    }

    public override bool IsReadly()
    {
        if (UseAutoLoad())
        {
            return TapadnAdRequestFactory.TryParseSlotId(Key, out _);
        }

        if (_loadedAd != null && _loadedAd.IsLoaded && _loadedAd.IsValid)
        {
            curState = 2;
            return true;
        }

        return false;
    }

    public override void LoadAD()
    {
        if (!TapadnAdRequestFactory.TryParseSlotId(Key, out _))
        {
            Debug.LogError($"[TapADN] Invalid rewarded slot id: {Key}");
            curState = 0;
            return;
        }

        if (UseAutoLoad())
        {
            curState = 2;
            try
            {
                _adNative.PreLoad(TapadnAdRequestFactory.BuildRewarded(Key, TapadnAdController.CurrentOptions), 3);
            }
            catch (Exception exception)
            {
                Debug.LogWarning($"[TapADN] Rewarded preload skipped: {exception.Message}");
            }
            return;
        }

        if (curState == 1 || IsReadly())
        {
            return;
        }

        curState = 1;
        _adNative.LoadRewardVideoAd(
            TapadnAdRequestFactory.BuildRewarded(Key, TapadnAdController.CurrentOptions),
            ad =>
            {
                _loadedAd?.Destroy();
                _loadedAd = ad;
                _loadedAd.Shown += OnManualShown;
                _loadedAd.Clicked += OnManualClicked;
                _loadedAd.ShowFailed += OnManualShowFailed;
                _loadedAd.RewardVerified += OnManualRewardVerify;
                _loadedAd.Closed += OnManualClosed;
                curState = 2;
                Debug.Log($"[TapADN] Rewarded loaded. slot={Key}");
            },
            error =>
            {
                curState = 0;
                Debug.LogError($"[TapADN] Rewarded load failed. code={error.Code}, message={error.Message}");
            });
    }

    public override void ShowAD(Action onClose, Action<bool> onVideoComplete)
    {
        adListener.onClose = onClose;
        adListener.onVideoComplete = onVideoComplete;
        _rewardVerified = false;
        _rewardVerifyReceived = false;
        _closePendingRewardVerify = false;
        _showSettled = false;
        _rewardCloseSettleHandler?.Kill();
        _rewardCloseSettleHandler = null;
        curState = 0;

        if (UseAutoLoad())
        {
            _adNative.ShowRewardVideoAutoAd(TapadnAdRequestFactory.BuildRewarded(Key, TapadnAdController.CurrentOptions), this);
            return;
        }

        if (_loadedAd == null || !_loadedAd.Show())
        {
            OnError(new DirichletError("show_failed", "ShowRewardVideoAd returned false"));
            return;
        }
    }

    public void OnError(DirichletError error)
    {
        if (_showSettled)
        {
            return;
        }

        _showSettled = true;
        _rewardCloseSettleHandler?.Kill();
        _rewardCloseSettleHandler = null;
        curState = 0;
        Debug.LogError($"[TapADN] Rewarded show failed. code={error?.Code}, message={error?.Message}");
        adListener.OnShowError();
    }

    public void OnAdShow()
    {
        NotifyShowStarted();
    }

    public void OnAdClose()
    {
        if (_showSettled)
        {
            return;
        }

        if (_rewardVerifyReceived)
        {
            CompleteRewardedClose();
            return;
        }

        _closePendingRewardVerify = true;
        _rewardCloseSettleHandler?.Kill();
        _rewardCloseSettleHandler = ADManager.Instance.CreateTimer(RewardCloseSettleDelaySeconds, CompleteRewardedClose);
    }

    public void OnRewardVerify(DirichletRewardVerificationEventArgs args)
    {
        _rewardVerifyReceived = true;
        _rewardVerified = args != null && args.IsVerified;
        if (_closePendingRewardVerify)
        {
            CompleteRewardedClose();
        }
    }

    public void OnAdClick()
    {
    }

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

    private void OnManualShown()
    {
        NotifyShowStarted();
    }

    private void OnManualClicked()
    {
    }

    private void OnManualShowFailed(DirichletError error)
    {
        OnError(error);
    }

    private void OnManualRewardVerify(DirichletRewardVerificationEventArgs args)
    {
        OnRewardVerify(args);
    }

    private void OnManualClosed()
    {
        _loadedAd?.Destroy();
        _loadedAd = null;
        OnAdClose();
    }

    private void CompleteRewardedClose()
    {
        if (_showSettled)
        {
            return;
        }

        _showSettled = true;
        _closePendingRewardVerify = false;
        _rewardCloseSettleHandler?.Kill();
        _rewardCloseSettleHandler = null;
        adListener.OnRewardVerify(_rewardVerified, TapadnAdController.CurrentOptions?.RewardAmount ?? 1, TapadnAdController.CurrentOptions?.RewardName ?? string.Empty);
        adListener.OnAdClose();
    }
}
