using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
/*
 * @brief 사용자가 동영상 기능(로드/재생)호출 시, 이벤트 처리를 위한 이벤트 핸들러 모음
 */
namespace hive.adkit.daro
{
    public class AdKitCallbackManager : MonoBehaviour
    {
        // Callback handler
        Dictionary<string, EventHandlers> callbackHandler = new Dictionary<string, EventHandlers>();

        // 초기화 콜백
        private Action<bool> onInitComplete;

        // Consent UI 호출 완료 콜백
        private Action onShowConsentUIFinish;

        private static AdKitCallbackManager _instance;
        public static AdKitCallbackManager Instance => _instance;

        void Awake()
        {
            if (_instance == null)
            {
                _instance = this;
                DontDestroyOnLoad(gameObject);
            }
            else if (_instance != this)
            {
                Destroy(gameObject); // 중복 방지
            }
        }

        ~AdKitCallbackManager()
        {
            callbackHandler = null;
        }

        public void OnAdKitInitializeCallback(Action<bool> callback)
        {
            onInitComplete = callback;
        }


        public void OnShowConsentUIFinishCallback(Action callback)
        {
            onShowConsentUIFinish = callback;
        }

        public void RegisterCallbackHandler(string adUnitId, EventHandlers handler)
        {
            if (callbackHandler.ContainsKey(adUnitId))
                callbackHandler.Remove(adUnitId);

            callbackHandler[adUnitId] = handler;
        }

        public void UnregisterCallbackHandler(string adUnitId)
        {
            if (callbackHandler.ContainsKey(adUnitId))
                callbackHandler.Remove(adUnitId);
        }

        void onSdkInitialize(string jsonString)
        {
            AdKitLogger.d("onSdkInitialize jsonString : " + jsonString);
            bool result = false;

            JSONObject json = new JSONObject(jsonString);
            json.GetField(ref result, "result");

            onInitComplete?.Invoke(result);
        }

        void onShowConsentUI(string jsonString)
        {
            onShowConsentUIFinish?.Invoke();
        }

        void handleCallbackEvent(string jsonString)
        {

            AdKitLogger.d("handleCallbackEvent jsonString : " + jsonString);

            string adUnitId = "";

            JSONObject json = new JSONObject(jsonString);
            json.GetField(ref adUnitId, "ad_unit_id");

            if (!callbackHandler.TryGetValue(adUnitId, out var handler))
            {
                AdKitLogger.d("handleCallbackEvent no adUnitId");
                return;
            }

            string eventType = "";
            json.GetField(ref eventType, "event_type");

            if (eventType.Equals("load"))
            {
                handler.onAdLoaded?.Invoke();
            }
            else if (eventType.Equals("open"))
            {
                handler.onAdOpening?.Invoke();
            }
            else if (eventType.Equals("click"))
            {
                handler.onAdClick?.Invoke();
            }
            else if (eventType.Equals("close"))
            {
                string adType = "";
                json.GetField(ref adType, "ad_type");

                if (adType == "banner")
                {
                    // banner 광고의 경우 destroy() 시 close 콜백을 내려주고 있어서 콜백을 받은 후에 close 콜백을 삭제 처리함
                    UnregisterCallbackHandler(adUnitId);
                }

                handler.onAdClosed?.Invoke();
            }
            else if (eventType.Equals("fail"))
            {
                int errorCode = -1;
                json.GetField(ref errorCode, "error_code");

                string errorMessage = "";
                json.GetField(ref errorMessage, "error_message");

                handler.onAdFailed?.Invoke(errorCode, errorMessage);
            }
            else if (eventType.Equals("paid"))
            {
                double revenue = 0.0;
                json.GetField(ref revenue, "revenue");

                string currency = "USD";
                json.GetField(ref currency, "currency");

                AdRevenueData adRevenueData = new AdRevenueData(revenue, currency);
                handler.onAdPaidEvent?.Invoke(adRevenueData);
            }
            else if (eventType.Equals("reward"))
            {
                string type = "";
                json.GetField(ref type, "item_type");

                int amount = 0;
                json.GetField(ref amount, "item_amount");

                RewardItem rewardItem = new RewardItem(type, amount);
                handler.onAdReward?.Invoke(rewardItem);
            }
        }
    }
}