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

namespace FRVR
{
    public class AdModule : MonoBehaviour
    {
        // Interstitial ad callbacks
        private Action _onInterstitialAdStarted;
        private Action<SdkError> _onInterstitialAdError;
        private Action _onInterstitialAdFinished;
        
        // Rewarded ad callbacks
        private Action _onRewardAdStarted;
        private Action<SdkError> _onRewardAdError;
        private Action _onRewardAdFinished;
        
        // Banner ad callbacks
        private Action<bool> _onBannerAdComplete;
        
        private bool _adRequestInProgress;
        private string _currentAdType; // Track which type of ad is currently being shown
        private FRVRSDK _frvrSDK;

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

    public void ShowInterstitialAd(Action adStarted, Action<SdkError> adError, Action adFinished)
    {
        if (!Application.isEditor && Application.platform != RuntimePlatform.WebGLPlayer)
        {
            return;
        }

        if (_adRequestInProgress)
        {
            _frvrSDK.DebugLog("Ad request in progress, ignore interstitial request.");
            return;
        }

        _frvrSDK.DebugLog("Requesting Interstitial Ad");

        _onInterstitialAdStarted = adStarted;
        _onInterstitialAdError = adError;
        _onInterstitialAdFinished = adFinished;
        _adRequestInProgress = true;
        _currentAdType = "interstitial";

        _frvrSDK.WrapSDKAction(
            () =>
            {
                ShowInterstitialAdSDK();
            },
            () =>
            {
                SimulateAdPlayback("interstitial");
            }
        );
    }

    public void ShowRewardAd(Action adStarted, Action<SdkError> adError, Action adFinished)
    {
        if (!Application.isEditor && Application.platform != RuntimePlatform.WebGLPlayer)
        {
            return;
        }

        if (_adRequestInProgress)
        {
            _frvrSDK.DebugLog("Ad request in progress, ignore reward request.");
            return;
        }

        _frvrSDK.DebugLog("Requesting Reward Ad");

        _onRewardAdStarted = adStarted;
        _onRewardAdError = adError;
        _onRewardAdFinished = adFinished;
        _adRequestInProgress = true;
        _currentAdType = "reward";

        _frvrSDK.WrapSDKAction(
            () =>
            {
                ShowRewardAdSDK();
            },
            () =>
            {
                SimulateAdPlayback("reward");
            }
        );
    }

    public void ShowBannerAd(Action<bool> adComplete)
    {
        if (!Application.isEditor && Application.platform != RuntimePlatform.WebGLPlayer)
        {
            return;
        }

        _frvrSDK.DebugLog("Requesting Banner Ad");

        _onBannerAdComplete = adComplete;

        _frvrSDK.WrapSDKAction(
            () =>
            {
                ShowBannerAdSDK();
            },
            () =>
            {
                // Simulate banner ad success in editor
                HandleBannerAdComplete(1);
            }
        );
    }

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

        return _frvrSDK.WrapSDKFunc(
            () => IsAdReadySDK(adType),
            () => true // In editor, always return true for testing
        );
    }

    public void HideBannerAd()
    {
        if (!Application.isEditor && Application.platform != RuntimePlatform.WebGLPlayer)
        {
            return;
        }

        _frvrSDK.DebugLog("Hiding Banner Ad");

        _frvrSDK.WrapSDKAction(
            () =>
            {
                HideBannerAdSDK();
            },
            () =>
            {
                // No action needed in editor
            }
        );
    }

        private IEnumerator InvokeRealtimeCoroutine(Action action, float seconds)
        {
            yield return new WaitForSecondsRealtime(seconds);
            action();
        }

        private void SimulateAdPlayback(string adType)
        {
            _frvrSDK.DebugLog($"FRVR Ads: Editor ad simulation for {adType}, game will resume in 3 seconds");
            
            // Use specific callbacks instead of generic ones to avoid duplicates
            if (adType == "interstitial")
            {
                HandleInterstitialAdStarted();
            }
            else if (adType == "reward")
            {
                HandleRewardAdStarted();
            }
            
            StartCoroutine(InvokeRealtimeCoroutine(EndSimulation, 3));
        }

        private void EndSimulation()
        {
            // Use specific callbacks instead of generic ones to avoid duplicates
            if (_currentAdType == "interstitial")
            {
                HandleInterstitialAdFinished();
            }
            else if (_currentAdType == "reward")
            {
                HandleRewardAdFinished();
            }
        }

        private void CleanupAd()
        {
            _adRequestInProgress = false;
            _currentAdType = null;
        }

        internal void HandleAdError(string errorJson)
        {
            var error = JsonUtility.FromJson<SdkError>(errorJson);
            _frvrSDK.DebugLog("Ad Error: " + error);

            if (_currentAdType == "interstitial")
            {
                _onInterstitialAdError?.Invoke(error);
            }
            else if (_currentAdType == "reward")
            {
                _onRewardAdError?.Invoke(error);
            }
            CleanupAd();
        }

        internal void HandleInterstitialAdError(string errorJson)
        {
            var error = JsonUtility.FromJson<SdkError>(errorJson);
            _frvrSDK.DebugLog("Interstitial Ad Error: " + error);
            CleanupAd();
            _onInterstitialAdError?.Invoke(error);
        }

        internal void HandleRewardAdError(string errorJson)
        {
            var error = JsonUtility.FromJson<SdkError>(errorJson);
            _frvrSDK.DebugLog("Reward Ad Error: " + error);
            CleanupAd();
            _onRewardAdError?.Invoke(error);
        }

        internal void HandleAdFinished()
        {
		var previousAdType = _currentAdType;
		_frvrSDK.DebugLog("Ad Finished");
		
		if (previousAdType == "interstitial")
		{
			_onInterstitialAdFinished?.Invoke();
		}
		else if (previousAdType == "reward")
		{
			_onRewardAdFinished?.Invoke();
		}

		CleanupAd();
        }

        internal void HandleInterstitialAdFinished()
        {
            _frvrSDK.DebugLog("Interstitial Ad Finished");
            CleanupAd();
            _onInterstitialAdFinished?.Invoke();
        }

        internal void HandleRewardAdFinished()
        {
            _frvrSDK.DebugLog("Reward Ad Finished ");
            CleanupAd();
            _onRewardAdFinished?.Invoke();
        }

        internal void HandleAdStarted()
        {
            _frvrSDK.DebugLog("Ad Started");
            
            if (_currentAdType == "interstitial")
            {
                _onInterstitialAdStarted?.Invoke();
            }
            else if (_currentAdType == "reward")
            {
                _onRewardAdStarted?.Invoke();
            }
        }

        internal void HandleInterstitialAdStarted()
        {
            _frvrSDK.DebugLog("Interstitial Ad Started");
            _onInterstitialAdStarted?.Invoke();
        }

        internal void HandleRewardAdStarted()
        {
            _frvrSDK.DebugLog("Reward Ad Started");
            _onRewardAdStarted?.Invoke();
        }

        internal void HandleBannerAdComplete(int result)
        {
            _frvrSDK.DebugLog($"Banner Ad Complete: {(result == 1 ? "Success" : "Failed")}");
            _onBannerAdComplete?.Invoke(result == 1);
        }

#if UNITY_WEBGL
        [DllImport("__Internal")]
        private static extern void ShowInterstitialAdSDK();
        
        [DllImport("__Internal")]
        private static extern void ShowRewardAdSDK();
        
        [DllImport("__Internal")]
        private static extern bool IsAdReadySDK(string adType);
        
        [DllImport("__Internal")]
        private static extern void ShowBannerAdSDK();
        
        [DllImport("__Internal")]
        private static extern void HideBannerAdSDK();
#else
        private void ShowInterstitialAdSDK() { }
        private void ShowRewardAdSDK() { }
        private bool IsAdReadySDK(string adType) { return false; }
        private void ShowBannerAdSDK() { }
        private void HideBannerAdSDK() { }
#endif
    }
}
