import ATAndroidNativeJS from "./Android/ATAndroidNativeJS";
import ATiOSNativeJS from "./iOS/ATiOSNativeJS";

type PlatformBridge = {
    loadNative: (placementId: string, settings: string) => void;
    setAdListener: (eventJSON: string) => void;
    hasAdReady: (placementId: string) => boolean;
    checkAdStatus: (placementId: string) => string;
    showAd: (placementId: string, adViewProperty: string) => void;
    showAdInScenario: (placementId: string, adViewProperty: string, scenario?: string) => void;
    removeAd: (placementId: string) => void;
};

let platformBridge: PlatformBridge | null = null;

const initPlatformBridge = (): PlatformBridge | null => {  
    if (cc.sys.os === cc.sys.OS_IOS) {           
        return null;
    } else if (cc.sys.os === cc.sys.OS_ANDROID) {
        return ATAndroidNativeJS;
    }
    return null;
};

platformBridge = initPlatformBridge();

interface DeveloperCallback {
    onNativeAdLoaded?: (placementId: string) => void;
    onNativeAdLoadFail?: (placementId: string, errorInfo: any) => void;
    onNativeAdShow?: (placementId: string, callbackInfo: any) => void;
    onNativeAdClick?: (placementId: string, callbackInfo: any) => void;
    onNativeAdVideoStart?: (placementId: string) => void;
    onNativeAdVideoEnd?: (placementId: string) => void;
    onNativeAdCloseButtonTapped?: (placementId: string, callbackInfo: any) => void;
}

class ATNativeListener {
    developerCallback: DeveloperCallback | null = null;

    onNativeAdLoaded(placementId: string) {
        this.developerCallback?.onNativeAdLoaded?.(placementId);
    }

    onNativeAdLoadFail(placementId: string, errorInfo: any) {
        this.developerCallback?.onNativeAdLoadFail?.(placementId, errorInfo);
    }

    onNativeAdShow(placementId: string, callbackInfo: any) {
        this.developerCallback?.onNativeAdShow?.(placementId, callbackInfo);
    }

    onNativeAdClick(placementId: string, callbackInfo: any) {
        this.developerCallback?.onNativeAdClick?.(placementId, callbackInfo);
    }

    onNativeAdVideoStart(placementId: string) {
        this.developerCallback?.onNativeAdVideoStart?.(placementId);
    }

    onNativeAdVideoEnd(placementId: string) {
        this.developerCallback?.onNativeAdVideoEnd?.(placementId);
    }

    onNativeAdCloseButtonTapped(placementId: string, callbackInfo: any) {
        this.developerCallback?.onNativeAdCloseButtonTapped?.(placementId, callbackInfo);
    }
}

const LoadedCallbackKey = "NativeLoaded";
const LoadFailCallbackKey = "NativeLoadFail";
const CloseCallbackKey = "NativeCloseButtonTapped";
const ClickCallbackKey = "NativeClick";
const ShowCallbackKey = "NativeShow";
const VideoStartKey = "NativeVideoStart";
const VideoEndKey = "NativeVideoEnd";

class ATNativeSDK {
    ATNativeListener: ATNativeListener = new ATNativeListener();

    loadNative(placementId: string, settings: Record<string, any> = {}) {
        if (platformBridge) {
            platformBridge.loadNative(placementId, JSON.stringify(settings));
        } else {
            cc.log("You must run on Android or iOS.");
        }
    }

    setAdListener(listener: DeveloperCallback) {
        const eventJSON: Record<string, string> = {
            [LoadedCallbackKey]: "ATNativeJSSDK.ATNativeListener.onNativeAdLoaded",
            [LoadFailCallbackKey]: "ATNativeJSSDK.ATNativeListener.onNativeAdLoadFail",
            [CloseCallbackKey]: "ATNativeJSSDK.ATNativeListener.onNativeAdCloseButtonTapped",
            [ClickCallbackKey]: "ATNativeJSSDK.ATNativeListener.onNativeAdClick",
            [ShowCallbackKey]: "ATNativeJSSDK.ATNativeListener.onNativeAdShow",
            [VideoStartKey]: "ATNativeJSSDK.ATNativeListener.onNativeAdVideoStart",
            [VideoEndKey]: "ATNativeJSSDK.ATNativeListener.onNativeAdVideoEnd"
        };

        if (platformBridge) {
            platformBridge.setAdListener(JSON.stringify(eventJSON));
        } else {
            cc.log("You must run on Android or iOS.");
        }

        this.ATNativeListener.developerCallback = listener;
    }

    hasAdReady(placementId: string): boolean {
        if (platformBridge) {
            return platformBridge.hasAdReady(placementId);
        } else {
            cc.log("You must run on Android or iOS.");
        }
        return false;
    }

    checkAdStatus(placementId: string): string {
        if (platformBridge) {
            return platformBridge.checkAdStatus(placementId);
        } else {
            cc.log("You must run on Android or iOS.");
        }
        return "";
    }

    showAd(placementId: string, adViewProperty: AdViewProperty) {
        if (platformBridge) {
            platformBridge.showAd(placementId, JSON.stringify(adViewProperty.getAdViewProperty()));
        } else {
            cc.log("You must run on Android or iOS.");
        }
    }

    showAdInScenario(placementId: string, adViewProperty: AdViewProperty, scenario: string = "") {
        if (platformBridge) {
            platformBridge.showAdInScenario(placementId, JSON.stringify(adViewProperty.getAdViewProperty()), scenario);
        } else {
            cc.log("You must run on Android or iOS.");
        }
    }

    removeAd(placementId: string) {
        if (platformBridge) {
            platformBridge.removeAd(placementId);
        } else {
            cc.log("You must run on Android or iOS.");
        }
    }

    createLoadAdSize(width: number, height: number): Record<string, number> {
        return { width, height };
    }
}

class AdViewProperty {
    parent: string | null = null;
    appIcon: string | null = null;
    mainImage: string | null = null;
    title: string | null = null;
    desc: string | null = null;
    adLogo: string | null = null;
    cta: string | null = null;
    rating: number | null = null;
    dislike: number | null = null;

    createItemViewProperty(
        x: number,
        y: number,
        width: number,
        height: number,
        backgroundColor: string,
        textColor: string,
        textSize: number,
        isCustomClick: boolean = false
    ): Record<string, any> {
        return {
            x,
            y,
            width,
            height,
            backgroundColor,
            textColor,
            textSize,
            isCustomClick
        };
    }

    getAdViewProperty(): Record<string, any> {
        const nativeViewProperty: Record<string, any> = {};

        if (this.parent != null) {
            nativeViewProperty["parent"] = this.parent;
        }

        if (this.appIcon != null) {
            nativeViewProperty["icon"] = this.appIcon;
        }

        if (this.mainImage != null) {
            nativeViewProperty["mainImage"] = this.mainImage;
        }

        if (this.title != null) {
            nativeViewProperty["title"] = this.title;
        }

        if (this.desc != null) {
            nativeViewProperty["desc"] = this.desc;
        }

        if (this.adLogo != null) {
            nativeViewProperty["adLogo"] = this.adLogo;
        }

        if (this.cta != null) {
            nativeViewProperty["cta"] = this.cta;
        }

        if (this.rating != null) {
            nativeViewProperty["rating"] = this.rating;
        }

        if (this.dislike != null) {
            nativeViewProperty["dislike"] = this.dislike;
        }

        return nativeViewProperty;
    }
}

(window as any).ATNativeJSSDK = new ATNativeSDK();
export default ATNativeSDK;
