import { _decorator, native } from 'cc';
import { ISDKCallbacks } from './Interfaces/ISDKCallbacks';
import { IBannerCallbacks } from './Interfaces/IBannerCallbacks';
import { BannerPlacement } from './Enums/BannerPlacement';
import { InterstitialFormat } from './Enums/InterstitialFormat';
import { IInterstitialCallbacks } from './Interfaces/IInterstitialCallbacks';
import { IRewardedCallbacks } from './Interfaces/IRewardedCallbacks';
const { ccclass } = _decorator;

@ccclass('NexverseAdManager')
export class NexverseAdManager
{
    private static instance: NexverseAdManager = null;
    public static getInstance(): NexverseAdManager {
        if (this.instance == null)
            this.instance = new NexverseAdManager();

        return this.instance;
    }

    private constructor() {
    }

    private is_initialized: boolean = false;
    private callback_sdk: ISDKCallbacks = null;
    private callback_banner: IBannerCallbacks = null;
    private callback_interstitial: IInterstitialCallbacks = null;
    private callback_rewarded: IRewardedCallbacks = null;


    private Dispatch_ToNative(method_name: string, args: string = "") {
        native.jsbBridgeWrapper.dispatchEventToNative(method_name, args);
    }


    //-----------Initialization Methods
    public Initialize(_callback: ISDKCallbacks, _account_id: number, _app_id: number) {
        if (this.is_initialized)
            return;

        this.Setup_CallbackListners();
        this.callback_sdk = _callback;

        const params = {
            accountId: _account_id,
            appId: _app_id
        };
        this.Dispatch_ToNative("InitSDK", JSON.stringify(params));
    }


    //-----------Config Methods
    public SetTestMode(value: boolean) {
        this.Dispatch_ToNative("setTestMode", value.toString());
    }
    public ShareGeoLocation(value: boolean) {
        this.Dispatch_ToNative("shareGeoLocation", value.toString());
    }
    public SetGlobalOrtbConfig(value: string) {
        this.Dispatch_ToNative("setGlobalOrtbConfig", value);
    }
    public SetGDPRConsentString(value: string) {
        this.Dispatch_ToNative("setGDPRConsentString", value);
    }
    public SetSubjectToGDPR(value: boolean) {
        this.Dispatch_ToNative("setSubjectToGDPR", value.toString());
    }
    public SetSubjectToCOPPA(value: boolean) {
        this.Dispatch_ToNative("setSubjectToCOPPA", value.toString());
    }


    //-----------Banner Methods
    public Create_Banner(_callback: IBannerCallbacks, _config_id: string, _widthPx: number = 320, _heightPx: number = 50, _placement: BannerPlacement = BannerPlacement.Top, _autoRefreshSec: number = 120, _video: boolean = false) {
        this.callback_banner = _callback;
        const params = {
            configId: _config_id,
            widthPx: _widthPx,
            heightPx: _heightPx,
            gravity: _placement,
            autoRefreshSec: _autoRefreshSec,
            video: _video
        };
        this.Dispatch_ToNative("createBanner", JSON.stringify(params));
    }
    public Destroy_Banner() {
        this.Dispatch_ToNative("destroyBanner");
    }


    //-----------Interstitial Methods
    public Load_Interstitial(_callback: IInterstitialCallbacks, _config_id: string, _format: InterstitialFormat = InterstitialFormat.BANNER) {
        this.callback_interstitial = _callback;
        const params = {
            configId: _config_id,
            format: _format
        };
        this.Dispatch_ToNative("loadInterstitial", JSON.stringify(params));
    }
    public Show_Interstitial() {
        this.Dispatch_ToNative("showInterstitial");
    }


    //-----------Rewarded Methods
    public Load_Rewarded(_callback: IRewardedCallbacks, _config_id: string) {
        this.callback_rewarded = _callback;
        const params = {
            configId: _config_id
        };
        this.Dispatch_ToNative("loadRewarded", JSON.stringify(params));
    }
    public Show_Rewarded() {
        this.Dispatch_ToNative("showRewarded");
    }



    private Setup_CallbackListners() {
        //-----------SDK Callbacks
        this.Setup_Listners_SDK();

        //-----------Banner Callbacks
        this.Setup_Listners_Banner();

        //-----------Interstitial Callbacks
        this.Setup_Listners_Interstitial();

        //-----------Rewarded Callbacks
        this.Setup_Listners_Rewarded();
    }

    private Setup_Listners_SDK() {
        native.jsbBridgeWrapper.addNativeEventListener("OnSdkInitialized", () => {
            this.is_initialized = true;
            this.callback_sdk?.onSdkInitialized();
        });
        native.jsbBridgeWrapper.addNativeEventListener("OnSdkInitializedWithWarning", (warning: string) => {
            this.callback_sdk?.onSdkInitializedWithWarning(warning);
        });
        native.jsbBridgeWrapper.addNativeEventListener("OnSdkFailed", (error: string) => {
            this.callback_sdk?.onSdkFailed(error);
        });
    }

    private Setup_Listners_Banner() {
        native.jsbBridgeWrapper.addNativeEventListener("OnBannerDestroyed", () => {
            this.callback_banner?.OnBannerDestroyed();
        });
        native.jsbBridgeWrapper.addNativeEventListener("OnBannerLoaded", () => {
            this.callback_banner?.OnBannerLoaded();
        });
        native.jsbBridgeWrapper.addNativeEventListener("OnBannerDisplayed", () => {
            this.callback_banner?.OnBannerDisplayed();
        });
        native.jsbBridgeWrapper.addNativeEventListener("OnBannerFailed", (error: string) => {
            this.callback_banner?.OnBannerFailed(error);
        });
        native.jsbBridgeWrapper.addNativeEventListener("OnBannerClicked", () => {
            this.callback_banner?.OnBannerClicked();
        });
        native.jsbBridgeWrapper.addNativeEventListener("OnBannerClosed", () => {
            this.callback_banner?.OnBannerClosed();
        });
        native.jsbBridgeWrapper.addNativeEventListener("BannerVideoCompleted", () => {
            this.callback_banner?.BannerVideoCompleted();
        });
        native.jsbBridgeWrapper.addNativeEventListener("BannerVideoPaused", () => {
            this.callback_banner?.BannerVideoPaused();
        });
        native.jsbBridgeWrapper.addNativeEventListener("BannerVideoResumed", () => {
            this.callback_banner?.BannerVideoResumed();
        });
        native.jsbBridgeWrapper.addNativeEventListener("BannerVideoUnMuted", () => {
            this.callback_banner?.BannerVideoUnMuted();
        });
        native.jsbBridgeWrapper.addNativeEventListener("BannerVideoMuted", () => {
            this.callback_banner?.BannerVideoMuted();
        });
    }

    private Setup_Listners_Interstitial() {
        native.jsbBridgeWrapper.addNativeEventListener("OnInterstitialFailed", (error: string) => {
            this.callback_interstitial?.OnInterstitialFailed(error);
        });
        native.jsbBridgeWrapper.addNativeEventListener("OnInterstitialShowError", (error: string) => {
            this.callback_interstitial?.OnInterstitialShowError(error);
        });
        native.jsbBridgeWrapper.addNativeEventListener("OnInterstitialLoaded", () => {
            this.callback_interstitial?.OnInterstitialLoaded();
        });
        native.jsbBridgeWrapper.addNativeEventListener("OnInterstitialDisplayed", () => {
            this.callback_interstitial?.OnInterstitialDisplayed();
        });
        native.jsbBridgeWrapper.addNativeEventListener("OnInterstitialClicked", () => {
            this.callback_interstitial?.OnInterstitialClicked();
        });
        native.jsbBridgeWrapper.addNativeEventListener("OnInterstitialClosed", () => {
            this.callback_interstitial?.OnInterstitialClosed();
        });
    }

    private Setup_Listners_Rewarded() {
        native.jsbBridgeWrapper.addNativeEventListener("RewardAdFailed", (error: string) => {
            this.callback_rewarded?.RewardAdFailed(error);
        });
        native.jsbBridgeWrapper.addNativeEventListener("RewardAdShowError", (error: string) => {
            this.callback_rewarded?.RewardAdShowError(error);
        });
        native.jsbBridgeWrapper.addNativeEventListener("RewardAdLoaded", () => {
            this.callback_rewarded?.RewardAdLoaded();
        });
        native.jsbBridgeWrapper.addNativeEventListener("RewardAdDisplayed", () => {
            this.callback_rewarded?.RewardAdDisplayed();
        });
        native.jsbBridgeWrapper.addNativeEventListener("RewardAdClicked", () => {
            this.callback_rewarded?.RewardAdClicked();
        });
        native.jsbBridgeWrapper.addNativeEventListener("RewardAdClosed", () => {
            this.callback_rewarded?.RewardAdClosed();
        });
        native.jsbBridgeWrapper.addNativeEventListener("RewardAdReward", (rewardJson: string) => {
            this.callback_rewarded?.RewardAdReward(rewardJson);
        });
    }
}


