// Import platform-specific modules
import ATAndroidBannerJS from "./Android/ATAndroidBannerJS";
import ATiOSBannerJS from "./iOS/ATiOSBannerJS";

// Define callback keys as constants
const LoadedCallbackKey = "BannerLoaded";
const LoadFailCallbackKey = "BannerLoadFail";
const CloseCallbackKey = "BannerCloseButtonTapped";
const ClickCallbackKey = "BannerClick";
const ShowCallbackKey = "BannerShow";
const RefreshCallbackKey = "BannerRefresh";
const RefreshFailCallbackKey = "BannerRefreshFail";

// Define interfaces for callback methods
interface ATBannerListenerCallbacks {
    onBannerAdLoaded?: (placementId: string) => void;
    onBannerAdLoadFail?: (placementId: string, errorInfo: string) => void;
    onBannerAdShow?: (placementId: string, callbackInfo: any) => void;
    onBannerAdClick?: (placementId: string, callbackInfo: any) => void;
    onBannerAdAutoRefresh?: (placementId: string, callbackInfo: any) => void;
    onBannerAdAutoRefreshFail?: (placementId: string, errorInfo: string) => void;
    onBannerAdCloseButtonTapped?: (placementId: string, callbackInfo: any) => void;
}

interface AdSize {
    width: number;
    height: number;
}

interface AdRect {
    x: number;
    y: number;
    width: number;
    height: number;
}

type PlatformBridge = typeof ATAndroidBannerJS | typeof ATiOSBannerJS | null;

// Initialize platform bridge based on the OS
const initPlatformBridge = (): PlatformBridge => {
    if (cc.sys.os === cc.sys.OS_IOS) {
        return ATiOSBannerJS;
    } else if (cc.sys.os === cc.sys.OS_ANDROID) {
        return ATAndroidBannerJS;
    }
    return null;
};

const platformBridge = initPlatformBridge();

// Define the ATBannerSDK
const ATBannerSDK = {
    // Constants
    kATBannerAdLoadingExtraBannerAdSizeStruct: "banner_ad_size_struct",
    kATBannerAdShowingPositionTop: "top",
    kATBannerAdShowingPositionBottom: "bottom",

    kATBannerAdInlineAdaptiveWidth: "inline_adaptive_width",
    kATBannerAdInlineAdaptiveOrientation: "inline_adaptive_orientation",
    kATBannerAdInlineAdaptiveOrientationCurrent: 0,
    kATBannerAdInlineAdaptiveOrientationPortrait: 1,
    kATBannerAdInlineAdaptiveOrientationLandscape: 2,

    kATBannerAdAdaptiveWidth: "adaptive_width",
    kATBannerAdAdaptiveOrientation: "adaptive_orientation",
    kATBannerAdAdaptiveOrientationCurrent: 0,
    kATBannerAdAdaptiveOrientationPortrait: 1,
    kATBannerAdAdaptiveOrientationLandscape: 2,

    // Listener
    ATBannerListener: {
        developerCallback: null as ATBannerListenerCallbacks | null,

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

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

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

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

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

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

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

    // Methods
    loadBanner(placementId: string, settings: Record<string, any> = {}): void {
        if (platformBridge) {
            // Handle extra banner ad size struct
            if (settings.hasOwnProperty(this.kATBannerAdLoadingExtraBannerAdSizeStruct)) {
                const loadAdSize: AdSize = settings[this.kATBannerAdLoadingExtraBannerAdSizeStruct];
                settings["width"] = loadAdSize.width;
                settings["height"] = loadAdSize.height;
            }

            platformBridge.loadBanner(placementId, JSON.stringify(settings));
        } else {
            cc.log("You must run on Android or iOS.");
        }
    },

    setAdListener(listener: ATBannerListenerCallbacks): void {
        const eventJSON: Record<string, string> = {
            [LoadedCallbackKey]: "ATBannerJSSDK.ATBannerListener.onBannerAdLoaded",
            [LoadFailCallbackKey]: "ATBannerJSSDK.ATBannerListener.onBannerAdLoadFail",
            [CloseCallbackKey]: "ATBannerJSSDK.ATBannerListener.onBannerAdCloseButtonTapped",
            [ClickCallbackKey]: "ATBannerJSSDK.ATBannerListener.onBannerAdClick",
            [ShowCallbackKey]: "ATBannerJSSDK.ATBannerListener.onBannerAdShow",
            [RefreshCallbackKey]: "ATBannerJSSDK.ATBannerListener.onBannerAdAutoRefresh",
            [RefreshFailCallbackKey]: "ATBannerJSSDK.ATBannerListener.onBannerAdAutoRefreshFail"
        };

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

        this.ATBannerListener.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 "";
        }
    },

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

    showAdInPositionAndScenario(placementId: string, position: string, scenario: string): void {
        if (platformBridge) {
            platformBridge.showAdInPositionAndScenario(placementId, position, scenario);
        } else {
            cc.log("You must run on Android or iOS.");
        }
    },

    showAdInRectangle(placementId: string, showAdRect: AdRect): void {
        if (platformBridge) {
            platformBridge.showAdInRectangle(placementId, JSON.stringify(showAdRect));
        } else {
            cc.log("You must run on Android or iOS.");
        }
    },

    showAdInRectangleAndScenario(placementId: string, showAdRect: AdRect, scenario: string): void {
        if (platformBridge) {
            platformBridge.showAdInRectangleAndScenario(placementId, JSON.stringify(showAdRect), scenario);
        } else {
            cc.log("You must run on Android or iOS.");
        }
    },

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

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

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

    createLoadAdSize(width: number, height: number): AdSize {
        return { width, height };
    },

    createShowAdRect(x: number, y: number, width: number, height: number): AdRect {
        return { x, y, width, height };
    }
};

// Export the SDK to the global window object
(window as any).ATBannerJSSDK = ATBannerSDK;

export default ATBannerSDK;
