import fs from 'fs/promises';
import path from 'path';
import { fileURLToPath } from 'url';
import { minifyPatchCode } from '../utils/minify.js';
// 缓存压缩后的 CTA 适配器代码
let cachedMinifiedCTAAdapter = null;
// 缓存压缩后的 Tracking 适配器代码
let cachedMinifiedTrackingAdapter = null;
// 缓存从 @playcraft/ads-tracking 提取的 tracking 实现代码
let cachedAdsTrackingScript = null;
// 缓存压缩后的平台脚本
const platformScriptCache = new Map();
export class PlatformAdapter {
    constructor(options) {
        this.options = options;
    }
    /**
     * 验证配置
     */
    validateOptions() {
        // 默认实现，子类可以覆盖
    }
    /**
     * 读取模板文件
     */
    async readTemplateFile(filename) {
        const currentDir = path.dirname(fileURLToPath(import.meta.url));
        const templatePath = path.resolve(currentDir, '../../templates/patches', filename);
        return await fs.readFile(templatePath, 'utf-8');
    }
    /**
     * 压缩平台脚本代码
     * @param scriptCode - 原始 JavaScript 代码
     * @param cacheKey - 缓存键（通常是平台名称）
     * @returns 压缩后的 <script> 标签
     */
    async minifyPlatformScript(scriptCode, cacheKey) {
        const key = cacheKey || this.getName();
        if (platformScriptCache.has(key)) {
            return `<script>${platformScriptCache.get(key)}</script>`;
        }
        const minified = await minifyPatchCode(scriptCode, key);
        platformScriptCache.set(key, minified);
        return `<script>${minified}</script>`;
    }
    /**
     * 获取 CTA 适配器脚本（异步版本，带压缩）
     */
    async getCTAAdapterScriptAsync() {
        if (cachedMinifiedCTAAdapter) {
            return `<script>${cachedMinifiedCTAAdapter}</script>`;
        }
        const ctaCode = await this.readTemplateFile('playcraft-cta-adapter.js');
        const minified = await minifyPatchCode(ctaCode, 'playcraft-cta-adapter.js');
        cachedMinifiedCTAAdapter = minified;
        return `<script>${minified}</script>`;
    }
    /**
     * 生成 Store URLs 注入脚本
     * 将 storeUrls 以全局变量写入 HTML，供 CTA 适配器读取
     */
    getStoreUrlsScript() {
        const urls = this.options.storeUrls || {};
        // 只有存在有效 URL 时才注入
        if (!urls.ios && !urls.android) {
            return '';
        }
        const safeUrls = {
            ...(urls.ios ? { ios: urls.ios } : {}),
            ...(urls.android ? { android: urls.android } : {}),
        };
        return `<script>window.__PLAYCRAFT_STORE_URLS__=${JSON.stringify(safeUrls)};</script>`;
    }
    /**
     * 获取 CTA 适配器脚本（同步版本，使用预压缩代码）
     * @deprecated 推荐使用 getCTAAdapterScriptAsync
     */
    getCTAAdapterScript() {
        // 预压缩的 CTA 适配器代码（由 terser 压缩生成）
        // 注意：此版本已移除硬编码地址，改为读取 window.__PLAYCRAFT_STORE_URLS__
        const minifiedCode = `!function(){"use strict";var _s=(typeof window!=="undefined"&&window.__PLAYCRAFT_STORE_URLS__)||{};var IOS_STORE_URL=_s.ios||"";var ANDROID_STORE_URL=_s.android||"";function i(){var ua=navigator.userAgent||"";return(/iPad|iPhone|iPod/.test(ua)||"MacIntel"===navigator.platform&&navigator.maxTouchPoints>1?"ios":/Android/i.test(ua)?"android":"unknown")==="ios"?IOS_STORE_URL:ANDROID_STORE_URL}function e(){this.platform=null,this.isReady=!1,this.readyCallbacks=[],this.detectPlatform(),this.initialize()}e.prototype.detectPlatform=function(){"undefined"!=typeof FbPlayableAd?this.platform="facebook":"undefined"!=typeof mraid?this.platform="mraid":"undefined"!=typeof dapi?this.platform="dapi":"undefined"!=typeof ExitApi?this.platform="google":void 0!==window.BGY_MRAID?this.platform="bigo":"function"==typeof snapchatCta?this.platform="snapchat":"function"==typeof window.openAppStore?this.platform="tiktok":"function"==typeof window.install?this.platform="mintegral":void 0!==window.TJ_API&&"function"==typeof window.TJ_API.click?this.platform="tapjoy":void 0!==window.NUC&&window.NUC.trigger&&"function"==typeof window.NUC.trigger.convert?this.platform="nucleo":void 0!==window.smxTracking&&"function"==typeof window.smxTracking.redirect?this.platform="smadex":(this.platform="unknown",console.warn("[PlayCraft CTA] Unknown platform")),console.log("[PlayCraft CTA] Platform:",this.platform)},e.prototype.initialize=function(){var i=this;switch(this.platform){case"facebook":case"google":case"bigo":case"snapchat":case"tiktok":case"mintegral":case"tapjoy":case"nucleo":case"smadex":default:this.isReady=!0,this.notifyReady();break;case"mraid":mraid.isReady&&mraid.isReady()?(this.isReady=!0,this.notifyReady()):mraid.addEventListener&&mraid.addEventListener("ready",function(){i.isReady=!0,i.notifyReady()});break;case"dapi":dapi.isReady&&dapi.isReady()?(this.isReady=!0,this.notifyReady()):dapi.addEventListener&&dapi.addEventListener("ready",function(){i.isReady=!0,i.notifyReady()})}},e.prototype.notifyReady=function(){for(var i=0;i<this.readyCallbacks.length;i++)try{this.readyCallbacks[i]()}catch(i){console.error("[PlayCraft CTA] Ready callback error:",i)}this.readyCallbacks=[]},e.prototype.onReady=function(i){this.isReady?setTimeout(i,0):this.readyCallbacks.push(i)},e.prototype.jump=function(e){e=e||{},this.isReady||console.warn("[PlayCraft CTA] Not ready"),console.log("[PlayCraft CTA] Jump - platform:",this.platform);try{switch(this.platform){case"facebook":"undefined"!=typeof FbPlayableAd&&FbPlayableAd.onCTAClick&&FbPlayableAd.onCTAClick();break;case"mraid":"undefined"!=typeof mraid&&mraid.open&&mraid.open(e.url||i());break;case"dapi":"undefined"!=typeof dapi&&dapi.openStoreUrl&&dapi.openStoreUrl();break;case"google":"undefined"!=typeof ExitApi&&ExitApi.exit&&ExitApi.exit();break;case"bigo":void 0!==window.BGY_MRAID&&window.BGY_MRAID.open&&window.BGY_MRAID.open();break;case"snapchat":"function"==typeof snapchatCta&&snapchatCta();break;case"tiktok":"function"==typeof window.openAppStore&&window.openAppStore();break;case"mintegral":"function"==typeof window.install&&window.install();break;case"tapjoy":void 0!==window.TJ_API&&window.TJ_API.click&&window.TJ_API.click();break;case"nucleo":void 0!==window.NUC&&window.NUC.trigger&&window.NUC.trigger.convert&&window.NUC.trigger.convert(e.url||i());break;case"smadex":void 0!==window.smxTracking&&window.smxTracking.redirect&&window.smxTracking.redirect();break;default:this.fallbackJump(e.url)}}catch(i){console.error("[PlayCraft CTA] Jump failed:",i),this.fallbackJump(e.url)}},e.prototype.fallbackJump=function(e){var o=e||i();if("undefined"!=typeof FbPlayableAd&&FbPlayableAd.onCTAClick)FbPlayableAd.onCTAClick();else if("undefined"!=typeof mraid&&mraid.open)mraid.open(o);else if("undefined"!=typeof dapi&&dapi.openStoreUrl)dapi.openStoreUrl();else if("undefined"!=typeof ExitApi&&ExitApi.exit)ExitApi.exit();else if(void 0!==window.BGY_MRAID&&window.BGY_MRAID.open)window.BGY_MRAID.open();else if("function"==typeof snapchatCta)snapchatCta();else if("function"==typeof window.openAppStore)window.openAppStore();else if("function"==typeof window.install)window.install();else if(void 0!==window.TJ_API&&window.TJ_API.click)window.TJ_API.click();else if(void 0!==window.NUC&&window.NUC.trigger&&window.NUC.trigger.convert)window.NUC.trigger.convert(o);else if(void 0!==window.smxTracking&&window.smxTracking.redirect)window.smxTracking.redirect();else{try{parent.postMessage("download","*")}catch(i){}o&&window.open(o,"_blank")}},e.prototype.getPlatform=function(){return this.platform},e.prototype.checkReady=function(){return this.isReady};var o=new e;window.PlayCraftCTA={jump:function(i){o.jump(i)},jump2AppStore:function(i){o.jump(i)},onReady:function(i){o.onReady(i)},getPlatform:function(){return o.getPlatform()},isReady:function(){return o.checkReady()}},window.jump2AppStore=window.PlayCraftCTA.jump2AppStore}();`;
        return `<script>${minifiedCode}</script>`;
    }
    /**
     * 在 HTML 中注入 CTA 适配器（异步版本）
     */
    async injectCTAAdapterAsync(html) {
        const storeUrlsScript = this.getStoreUrlsScript();
        const ctaScript = await this.getCTAAdapterScriptAsync();
        const combined = storeUrlsScript + ctaScript;
        // 在 </head> 之前或 </body> 之前注入
        if (html.includes('</head>')) {
            return html.replace('</head>', `${combined}\n</head>`);
        }
        else if (html.includes('</body>')) {
            return html.replace('</body>', `${combined}\n</body>`);
        }
        else {
            return combined + '\n' + html;
        }
    }
    /**
     * 在 HTML 中注入 CTA 适配器（同步版本）
     * @deprecated 推荐使用 injectCTAAdapterAsync
     */
    injectCTAAdapter(html) {
        const storeUrlsScript = this.getStoreUrlsScript();
        const ctaScript = this.getCTAAdapterScript();
        const combined = storeUrlsScript + ctaScript;
        // 在 </head> 之前或 </body> 之前注入
        if (html.includes('</head>')) {
            return html.replace('</head>', `${combined}\n</head>`);
        }
        else if (html.includes('</body>')) {
            return html.replace('</body>', `${combined}\n</body>`);
        }
        else {
            return combined + '\n' + html;
        }
    }
    // ===== Tracking Adapter =====
    /**
     * 生成 Tracking 配置注入脚本
     * 将 tracking 配置以全局变量写入 HTML，供 Tracking Adapter 读取
     */
    getTrackingConfigScript() {
        const tracking = this.options.tracking;
        if (tracking?.enabled === false)
            return '';
        const config = {};
        // adNetwork: 优先用显式配置，否则从 platform 自动推断
        const adNetwork = tracking?.adNetwork || this.options.platform || '';
        if (adNetwork)
            config.adNetwork = adNetwork;
        if (tracking?.totalInteractions)
            config.totalInteractions = tracking.totalInteractions;
        return Object.keys(config).length > 0
            ? `<script>window.__PLAYCRAFT_TRACKING_CONFIG__=${JSON.stringify(config)};</script>`
            : '';
    }
    /**
     * 获取 Tracking 适配器脚本（异步版本，带压缩）
     */
    async getTrackingAdapterScriptAsync() {
        if (cachedMinifiedTrackingAdapter) {
            return `<script>${cachedMinifiedTrackingAdapter}</script>`;
        }
        const code = await this.readTemplateFile('playcraft-tracking-adapter.js');
        const minified = await minifyPatchCode(code, 'playcraft-tracking-adapter.js');
        cachedMinifiedTrackingAdapter = minified;
        return `<script>${minified}</script>`;
    }
    /**
     * 从 @playcraft/ads-tracking 包中提取 tracking 实现代码
     * 读取 IIFE 版本，剥掉最外层的自执行箭头函数包装，
     * 重新包裹为独立 IIFE 并通过 window.PlayCraftTracking 暴露。
     */
    async getAdsdkTrackingScriptAsync() {
        if (cachedAdsTrackingScript) {
            return `<script>${cachedAdsTrackingScript}</script>`;
        }
        try {
            // 从 @playcraft/ads-tracking 的 IIFE 构建中读取
            const { createRequire } = await import('module');
            const require = createRequire(import.meta.url);
            const adsTrackingPath = require.resolve('@playcraft/ads-tracking/dist/iife/index.js');
            const iifeCode = await fs.readFile(adsTrackingPath, 'utf-8');
            // 提取 IIFE 内部实现：ads-tracking 的 IIFE 形如
            //   "use strict";\n(() => {\n  // src/tracking.ts\n  ...\n  var tracking = {...};\n})();
            // 需要剥掉最外层 (() => { ... })(); 保留内部代码，
            // 再在末尾挂到 window.PlayCraftTracking 上。
            const startMarker = '// src/tracking.ts';
            const startIdx = iifeCode.indexOf(startMarker);
            if (startIdx === -1) {
                console.warn('[Tracking] 无法从 @playcraft/ads-tracking 中提取 tracking 代码，使用内置 adapter');
                return '';
            }
            // 找到最后一个 "})();" 作为 IIFE 结束
            const endIdx = iifeCode.lastIndexOf('})();');
            if (endIdx === -1 || endIdx <= startIdx) {
                console.warn('[Tracking] 无法定位 @playcraft/ads-tracking IIFE 结尾，使用内置 adapter');
                return '';
            }
            const innerCode = iifeCode.substring(startIdx, endIdx).trimEnd();
            // 包装为独立 IIFE，暴露 window.PlayCraftTracking
            const wrappedCode = `(function(){"use strict";${innerCode}\nwindow.PlayCraftTracking=tracking;})();`;
            const minified = await minifyPatchCode(wrappedCode, 'ads-tracking-extract');
            cachedAdsTrackingScript = minified;
            return `<script>${minified}</script>`;
        }
        catch (e) {
            console.warn('[Tracking] 无法加载 @playcraft/ads-tracking:', e.message);
            return '';
        }
    }
    /**
     * 在 HTML 中注入 Tracking 适配器（异步版本）
     * 注入顺序：1.Config → 2.ads-tracking 实现 → 3.Adapter 桥接脚本
     */
    async injectTrackingAdapterAsync(html) {
        if (this.options.tracking?.enabled === false)
            return html;
        const configScript = this.getTrackingConfigScript();
        const adsTrackingScript = await this.getAdsdkTrackingScriptAsync();
        const trackingScript = await this.getTrackingAdapterScriptAsync();
        const combined = configScript + adsTrackingScript + trackingScript;
        if (html.includes('</head>')) {
            return html.replace('</head>', `${combined}\n</head>`);
        }
        else if (html.includes('</body>')) {
            return html.replace('</body>', `${combined}\n</body>`);
        }
        return combined + '\n' + html;
    }
}
