import { sys } from 'cc';

/**
 * 微信分享配置
 */
export interface WxShareConfig {
    /** 分享标题 */
    title: string;
    /** 分享图片 URL 或本地路径 */
    imageUrl?: string;
    /** 查询字符串，从这条转发消息进入后，可通过 wx.getLaunchOptionsSync 或 wx.onShow 获取 */
    query?: string;
}

/**
 * 微信朋友圈分享配置
 */
export interface WxShareTimelineConfig {
    /** 分享标题 */
    title: string;
    /** 分享图片 URL 或本地路径 */
    imageUrl?: string;
    /** 查询字符串 */
    query?: string;
}

/**
 * 微信小游戏 SDK 工具类
 * 封装微信平台相关 API，非微信环境下静默降级
 */
export class WxSDK {
    /**
     * 是否处于微信小游戏环境
     */
    static isWechat(): boolean {
        return sys.platform === sys.Platform.WECHAT_GAME;
    }

    /**
     * 获取 wx 全局对象（仅微信环境下可用）
     */
    static getWx(): any {
        if (!WxSDK.isWechat()) return null;
        return typeof wx !== 'undefined' ? wx : null;
    }

    // ==================== 登录相关 ====================

    /**
     * 微信登录，获取临时 code
     * @returns Promise<string> 登录 code
     */
    static login(): Promise<string> {
        return new Promise((resolve, reject) => {
            const wxApi = WxSDK.getWx();
            if (!wxApi) {
                reject(new Error('非微信环境，无法调用 wx.login'));
                return;
            }

            wxApi.login({
                success: (res: any) => {
                    if (res.code) {
                        console.log('[WxSDK] wx.login 成功，获取到 code');
                        resolve(res.code);
                    } else {
                        console.error('[WxSDK] wx.login 失败:', res.errMsg);
                        reject(new Error(res.errMsg || 'wx.login 失败'));
                    }
                },
                fail: (err: any) => {
                    console.error('[WxSDK] wx.login 调用失败:', err);
                    reject(new Error(err.errMsg || 'wx.login 调用失败'));
                }
            });
        });
    }

    // ==================== 分享相关 ====================

    /**
     * 开启转发/分享菜单
     * 调用后用户可通过右上角菜单进行转发
     * @param withShareTicket 是否带 shareTicket，用于获取群信息
     */
    static showShareMenu(withShareTicket: boolean = true): void {
        const wxApi = WxSDK.getWx();
        if (!wxApi) return;

        wxApi.showShareMenu({
            withShareTicket,
            menus: ['shareAppMessage', 'shareTimeline'],
            success: () => {
                console.log('[WxSDK] showShareMenu 成功');
            },
            fail: (err: any) => {
                console.warn('[WxSDK] showShareMenu 失败', err);
            }
        });
    }

    /**
     * 设置被动分享（右上角菜单 "转发给朋友"）的内容
     * 需要在页面加载后尽早调用，只需调用一次
     * @param config 分享配置
     */
    static onShareAppMessage(config: WxShareConfig): void {
        const wxApi = WxSDK.getWx();
        if (!wxApi) return;

        wxApi.onShareAppMessage(() => ({
            title: config.title,
            imageUrl: config.imageUrl ?? '',
            query: config.query ?? ''
        }));

        console.log('[WxSDK] onShareAppMessage 已设置');
    }

    /**
     * 设置分享到朋友圈的内容
     * @param config 朋友圈分享配置
     */
    static onShareTimeline(config: WxShareTimelineConfig): void {
        const wxApi = WxSDK.getWx();
        if (!wxApi) return;

        if (typeof wxApi.onShareTimeline !== 'function') {
            console.warn('[WxSDK] 当前微信版本不支持 onShareTimeline');
            return;
        }

        wxApi.onShareTimeline(() => ({
            title: config.title,
            imageUrl: config.imageUrl ?? '',
            query: config.query ?? ''
        }));

        console.log('[WxSDK] onShareTimeline 已设置');
    }

    /**
     * 主动触发转发（拉起分享面板）
     * @param config 分享配置
     */
    static shareAppMessage(config: WxShareConfig): void {
        const wxApi = WxSDK.getWx();
        if (!wxApi) return;

        wxApi.shareAppMessage({
            title: config.title,
            imageUrl: config.imageUrl ?? '',
            query: config.query ?? ''
        });

        console.log('[WxSDK] shareAppMessage 已触发');
    }

    /**
     * 一键初始化分享功能
     * 开启分享菜单 + 设置被动分享内容 + 设置朋友圈分享内容
     * @param config 分享配置
     */
    static initShare(config: WxShareConfig): void {
        if (!WxSDK.isWechat()) {
            console.log('[WxSDK] 非微信环境，跳过分享初始化');
            return;
        }

        WxSDK.showShareMenu();
        WxSDK.onShareAppMessage(config);
        WxSDK.onShareTimeline({
            title: config.title,
            imageUrl: config.imageUrl,
            query: config.query
        });

        console.log('[WxSDK] 分享功能初始化完成');
    }

    // ==================== 震动相关 ====================

    /**
     * 触发短震动（15ms）
     * 用于轻量级反馈，如按钮点击
     */
    static vibrateShort(): void {
        const wxApi = WxSDK.getWx();
        if (!wxApi) return;

        wxApi.vibrateShort({
            type: 'medium',
            success: () => {
                console.log('[WxSDK] 短震动成功');
            },
            fail: (err: any) => {
                console.warn('[WxSDK] 短震动失败', err);
            }
        });
    }

    /**
     * 触发长震动（400ms）
     * 用于重要反馈，如错误提示
     */
    static vibrateLong(): void {
        const wxApi = WxSDK.getWx();
        if (!wxApi) return;

        wxApi.vibrateLong({
            success: () => {
                console.log('[WxSDK] 长震动成功');
            },
            fail: (err: any) => {
                console.warn('[WxSDK] 长震动失败', err);
            }
        });
    }

    // ==================== 激励视频广告 ====================

    /** 激励视频广告实例（复用） */
    private static _rewardedVideoAd: any = null;

    /**
     * 展示激励视频广告
     * 用户看完广告后返回 true，中途退出或失败返回 false
     * 非微信环境直接返回 true（开发模式直接通过）
     * @param adUnitId 广告单元 ID（默认使用项目配置的 ID）
     * @returns Promise<boolean> 是否看完广告
     */
    static showRewardedVideoAd(adUnitId: string = ''): Promise<boolean> {
        return new Promise((resolve) => {
            const wxApi = WxSDK.getWx();
            if (!wxApi) {
                console.log('[WxSDK] 非微信环境，跳过激励视频广告');
                resolve(true);
                return;
            }

            if (typeof wxApi.createRewardedVideoAd !== 'function') {
                console.warn('[WxSDK] 当前微信版本不支持激励视频广告');
                resolve(true);
                return;
            }

            try {
                // 复用或创建广告实例
                if (!WxSDK._rewardedVideoAd) {
                    WxSDK._rewardedVideoAd = wxApi.createRewardedVideoAd({
                        adUnitId: adUnitId,
                    });
                }

                const ad = WxSDK._rewardedVideoAd;

                // 定义关闭回调（一次性）
                const onClose = (res: any) => {
                    ad.offClose(onClose);
                    if (res && res.isEnded) {
                        console.log('[WxSDK] 激励视频广告观看完成');
                        resolve(true);
                    } else {
                        console.log('[WxSDK] 激励视频广告中途退出');
                        resolve(false);
                    }
                };

                // 定义错误回调（一次性）
                const onError = (err: any) => {
                    ad.offError(onError);
                    ad.offClose(onClose);
                    console.error('[WxSDK] 激励视频广告错误:', err);
                    resolve(false);
                };

                ad.onClose(onClose);
                ad.onError(onError);

                // 先尝试 show，如果广告未加载则先 load
                ad.show().catch(() => {
                    ad.load().then(() => ad.show()).catch((loadErr: any) => {
                        ad.offClose(onClose);
                        ad.offError(onError);
                        console.error('[WxSDK] 激励视频广告加载失败:', loadErr);
                        resolve(false);
                    });
                });
            } catch (err) {
                console.error('[WxSDK] 激励视频广告异常:', err);
                resolve(false);
            }
        });
    }

    // ==================== 启动参数 ====================

    /**
     * 从启动参数中获取分享码
     * @returns 分享码，不存在则返回 null
     */
    static getShareCodeFromLaunch(): string | null {
        const wxApi = WxSDK.getWx();
        if (!wxApi) return null;

        try {
            const options = wxApi.getLaunchOptionsSync();
            if (options?.query?.shareCode) {
                console.log('[WxSDK] 检测到分享码:', options.query.shareCode);
                return options.query.shareCode;
            }
        } catch (err) {
            console.warn('[WxSDK] 获取启动参数失败:', err);
        }
        return null;
    }
}

// ==================== 隐私授权相关 ====================

/**
 * 检查用户是否已授权隐私
 * @returns Promise<{ needAuthorization: boolean }> needAuthorization 为 false 表示已授权
 */
export async function checkPrivacySetting(): Promise<{ needAuthorization: boolean }> {
    return new Promise((resolve) => {
        const wxApi = WxSDK.getWx();
        if (!wxApi) {
            // 非微信环境，认为已授权
            resolve({ needAuthorization: false });
            return;
        }

        if (typeof wxApi.getPrivacySetting !== 'function') {
            // 低版本微信，认为已授权
            console.warn('[WxSDK] 当前微信版本不支持 getPrivacySetting');
            resolve({ needAuthorization: false });
            return;
        }

        wxApi.getPrivacySetting({
            success: (res: any) => {
                console.log('[WxSDK] 隐私授权检查结果:', res);
                resolve({ needAuthorization: res.needAuthorization });
            },
            fail: (err: any) => {
                console.warn('[WxSDK] 隐私授权检查失败:', err);
                // 检查失败时认为需要授权
                resolve({ needAuthorization: true });
            }
        });
    });
}

/**
 * 引导用户进行隐私授权
 * 调用后会弹出微信隐私授权弹窗
 * @returns Promise<void>
 */
export async function requirePrivacyAuthorize(): Promise<void> {
    return new Promise((resolve, reject) => {
        const wxApi = WxSDK.getWx();
        if (!wxApi) {
            console.warn('[WxSDK] 非微信环境，跳过隐私授权');
            resolve();
            return;
        }

        if (typeof wxApi.requirePrivacyAuthorize !== 'function') {
            console.warn('[WxSDK] 当前微信版本不支持 requirePrivacyAuthorize');
            resolve();
            return;
        }

        wxApi.requirePrivacyAuthorize({
            success: () => {
                console.log('[WxSDK] 用户已授权隐私');
                resolve();
            },
            fail: (err: any) => {
                console.warn('[WxSDK] 用户拒绝或授权失败:', err);
                reject(new Error(err.errMsg || '隐私授权失败'));
            }
        });
    });
}

// ==================== 用户信息相关 ====================

/**
 * 用户信息（头像、昵称）
 */
export interface WxUserInfo {
    avatarUrl: string;
    nickName: string;
    country?: string;
    province?: string;
    city?: string;
    gender?: number;
}

/**
 * 获取用户头像和昵称（需要用户主动授权）
 * @returns Promise<WxUserInfo>
 */
export async function getUserProfile(): Promise<WxUserInfo> {
    return new Promise((resolve, reject) => {
        const wxApi = WxSDK.getWx();
        if (!wxApi) {
            // 非微信环境，返回 mock 数据
            console.warn('[WxSDK] 非微信环境，返回 mock 用户信息');
            resolve({
                avatarUrl: '',
                nickName: '微信用户'
            });
            return;
        }

        if (typeof wxApi.getUserProfile !== 'function') {
            console.warn('[WxSDK] 当前微信版本不支持 getUserProfile');
            reject(new Error('当前微信版本不支持 getUserProfile'));
            return;
        }

        wxApi.getUserProfile({
            desc: '用于完善用户资料',
            success: (res: any) => {
                if (res.userInfo) {
                    console.log('[WxSDK] 获取用户信息成功');
                    resolve({
                        avatarUrl: res.userInfo.avatarUrl,
                        nickName: res.userInfo.nickName,
                        country: res.userInfo.country,
                        province: res.userInfo.province,
                        city: res.userInfo.city,
                        gender: res.userInfo.gender
                    });
                } else {
                    console.error('[WxSDK] 获取用户信息失败: 无 userInfo');
                    reject(new Error('获取用户信息失败'));
                }
            },
            fail: (err: any) => {
                console.error('[WxSDK] 获取用户信息失败:', err);
                reject(new Error(err.errMsg || '获取用户信息失败'));
            }
        });
    });
}
