
import { MiniGameSdk } from "./MiniGameSdk";
const { ccclass, property } = cc._decorator;
enum EWechatAD {
    CUMSTOM_01 = 'adunit-f7c2417eb2c2e473'
}

@ccclass
export class MiniGameManager extends cc.Component {

    @property(cc.Node)
    entranceView: cc.Node = null;
    /**
     * 开始游戏前的初始化操作。
     * 主要负责检查并处理游戏入口按钮的激活状态，以及在特定环境下设置侧边栏的监听器。
     * 
     * @remarks
     * 此方法首先将游戏入口视图设为非激活状态，以准备进行后续的检查和设置。
     * 如果当前环境是抖音小游戏，会检查是否存在侧边栏，并根据检查结果激活或禁用游戏入口按钮。
     * 对于非抖音小游戏环境，直接激活游戏入口按钮。
     * 此外，无论环境如何，都会设置一个监听器，以处理来自侧边栏的事件，如成功触发时显示奖励提示。
     */
    private _id:any;
    private _userData:any;

    private static _instance: MiniGameManager;
    static get instance(): MiniGameManager {
        if (!MiniGameManager._instance) {
            MiniGameManager._instance = new MiniGameManager();
        }
        return MiniGameManager._instance;
    }

    start() {
        // 禁用游戏入口视图
        // this.entranceView.active = false;
        // MiniGameSdk.API.getUserProfile(this.setUserId);
        // cc.fx.GameTool.setUserInfo("");
        this.onGetLoginCode();
        // 尝试获取游戏入口按钮，如果存在则直接返回，不进行后续操作
        // let buttonEntrance = this.node.getChildByName('Btns')?.getChildByName('Button_EntranceView');
        // if (buttonEntrance) {
        //     return;
        // }

        // 如果是字节跳动小游戏环境，检查侧边栏是否存在

        if (MiniGameSdk.isBytedance()) {
            //抖音环境，检测侧边栏存在
            MiniGameSdk.BytedanceSidebar.checkSideBar((success: boolean) => {
                // 根据侧边栏存在性激活或禁用游戏入口按钮
                // buttonEntrance.active = success;
            });
        } else {
            // 非抖音小游戏环境，直接激活游戏入口按钮
            // 非抖音环境，正常显示按钮
            // buttonEntrance.active = true;
        }

        // 设置监听器，以处理来自侧边栏的交互事件
        MiniGameSdk.BytedanceSidebar.listenFromSidebar((success: boolean) => {
            // 如果交互成功，显示奖励提示
            if (success) {
                MiniGameSdk.API.showToast('侧边栏奖励', 5);
            }
        });
    }

    update(deltaTime: number) {

    }

    /**
     * 弹出广告横幅。
     * 此方法用于加载并显示广告横幅。它首先加载指定广告位的横幅广告，然后显示广告。
     * 加载广告和显示广告是通过MiniGameSdk.AdvertManager的实例方法来实现的。
     * 
     * @remarks
     * 此方法提供了两种显示横幅广告的方式：
     * 1. 默认方式：调用showBanner方法显示广告，系统会自动选择显示位置。
     * 2. 指定位置方式：可以通过传入额外的参数来指定广告显示在屏幕的顶部或底部，或者通过坐标指定显示位置。
     * 
     * 示例代码中注释掉了两种显示广告的具体方法，可以根据实际需求选择使用。
     */
    onShowBanner() {
        // 加载指定广告位的横幅广告。
        MiniGameSdk.AdvertManager.instance.loadBanner('adunit-4e7ef467e3eaab51');

        // 默认方式显示横幅广告。
        // 方法1：默认调用
        MiniGameSdk.AdvertManager.instance.showBanner();

        // 示例：指定屏幕底部正中显示横幅广告。
        // 方法2：指定屏幕顶部或底部正中
        // MiniGameSdk.AdvertManager.instance.showBanner('adunit-4e7ef467e3eaab51', MiniGameSdk.EAdBannerLocation.BOTTOM); 

        // 示例：通过坐标指定位置显示横幅广告。
        // 方法2：指定坐标
        // MiniGameSdk.AdvertManager.instance.showBanner('adunit-4e7ef467e3eaab51', { top: 10, left: 10 }); 
    }

    /**
     * 隐藏广告横幅的函数。
     * 
     * 该函数调用MiniGameSdk.AdvertManager实例的方法，用于隐藏广告横幅。
     * 当需要暂时停止展示广告或用户主动请求隐藏广告时，可以调用此函数。
     * 
     * @remarks
     * 此函数不接受任何参数，也不返回任何值。
     * 它单纯地触发广告横幅的隐藏操作，具体实现依赖于AdvertManager的实现。
     */
    onHideBanner() {
        MiniGameSdk.AdvertManager.instance.hideBanner();
    }

    /**
     * 显示插屏广告的函数。
     * 
     * 此函数调用MiniGameSdk.AdvertManager实例的方法，以显示一个指定的插屏广告。
     * 它使用了硬编码的广告单元标识符，这意味着它专为特定的广告位设计。
     * 在实际应用中，可能需要根据应用的配置或用户的特定条件来动态选择广告单元标识符。
     */
    onShowInterstitial() {
        MiniGameSdk.AdvertManager.instance.showInterstitial('adunit-eadd67851d3050ad');
    }

    /**
     * 调用广告管理器加载并展示自定义广告。
     * 此方法首先通过广告管理器的实例加载指定的自定义广告单元，然后展示这个自定义广告。
     * 加载和展示广告是广告管理系统中的常见操作，这里通过两步分别完成加载和展示的过程，
     * 以确保广告在展示前正确且充分地被加载。
     */
    onShowCustom() {
        // 加载指定的自定义广告单元。
        MiniGameSdk.AdvertManager.instance.loadCustom(EWechatAD.CUMSTOM_01);
        // 展示已加载的自定义广告。
        MiniGameSdk.AdvertManager.instance.showCustom(EWechatAD.CUMSTOM_01);
    }

    /**
     * 隐藏自定义广告。
     * 
     * 本函数调用MiniGameSdk.AdvertManager.instance.hideCustom()来隐藏自定义广告。
     * 这是对接广告管理系统的一部分，用于控制广告的显示与隐藏。
     * 在需要隐藏自定义广告的场景下，调用此函数即可实现相应功能。
     */
    onHideCustom() {
        MiniGameSdk.AdvertManager.instance.hideCustom(EWechatAD.CUMSTOM_01);
    }

    /**
     * 触发显示视频广告的函数。
     * 通过调用MiniGameSdk.AdvertManager.instance.showVideo方法，显示一个视频广告，并根据用户观看广告的情况执行相应的逻辑。
     * 
     * @remarks
     * 此函数首先传入一个广告单元ID，用于标识要显示的视频广告。然后传入一个回调函数，该回调函数在用户观看广告后被调用，无论用户是完成了观看、拒绝了观看还是观看过程中发生了错误。
     * 回调函数接收两个参数：一个是用户观看广告的结果，另一个是用户观看的广告数量。根据观看结果的不同，显示不同的提示信息。
     */
    onShowVideo() {
        // 广告单元ID，用于标识要显示的视频广告
        // 广告单元ID的样例
        //抖音形如: 1re3nfqkmy81m4m8ge
        //微信形如: adunit-a7718f6e195e42fe
        MiniGameSdk.AdvertManager.instance.showVideo('1re3nfqkmy81m4m8ge', (res: MiniGameSdk.EAdVideoResult, count: number) => {
            // 输出用户观看的广告数量
            console.log('用户看的视频广告个数是:', count);

            // 根据用户观看广告的结果，执行不同的逻辑
            switch (res) {
                case MiniGameSdk.EAdVideoResult.ACCEPT:
                    // 用户完成了广告观看，显示奖励提示
                    MiniGameSdk.API.showToast('用户看完广告，可以奖励');
                    break;
                case MiniGameSdk.EAdVideoResult.REJECT:
                    // 用户拒绝了广告观看，显示不奖励提示
                    MiniGameSdk.API.showToast('用户拒绝掉广告，不奖励');
                    break;
                case MiniGameSdk.EAdVideoResult.ERROR:
                    // 广告播放发生错误，显示错误提示
                    MiniGameSdk.API.showToast('播放广告发生错误，不奖励');
                    break;
                default:
                    // 其他情况，不作处理
                    break;
            }
        });
    }

    /**
     * 引导用户分享应用给朋友。
     * 
     * 通过调用MiniGameSdk的API分享功能，向用户的朋友圈发送邀请，邀请他们一起玩游戏。
     * 这是一个重要的推广手段，可以增加应用的曝光度和用户量。
     * 
     * @remarks
     * 此方法中调用的API依赖于特定的小游戏平台，因此在不同的平台上可能需要不同的实现。
     */
    onShare() {
        MiniGameSdk.API.shareAppToFriends('来玩游戏吧');
    }

    /**
     * 显示一个toast提示。
     * 
     * 通过调用MiniGameSdk的API方法来显示一个简短的提示信息。toast是一种轻量级的提示方式，用于在界面上短暂地展示一些信息，不影响用户操作。
     * 这里使用了固定的提示文本 '这是一个toast'，在实际应用中，可以根据需要动态设置提示文本。
     */
    onShowToast() {
        MiniGameSdk.API.showToast('这是一个toast');
    }

    /**
     * 触发设备振动功能。
     * 
     * 该方法用于调用MiniGameSdk提供的API，以实现设备的振动功能。当需要提醒用户或提供触觉反馈时，可以调用此方法。
     * 例如，在游戏或应用中，当用户完成特定操作或发生特定事件时，可以通过振动给予用户反馈。
     * 
     * @remarks
     * 此方法无参数，也不返回任何值。
     */
    onVirbrate() {
        MiniGameSdk.API.vibrate();
    }

    /**
     * 重新启动游戏实例。
     * 
     * 此函数调用MiniGameSdk中的API重新启动游戏。重新启动操作可能是为了初始化游戏环境、重置游戏状态或处理其他需要重启的场景。
     * 调用此函数后，游戏将会重新开始，当前的游戏状态将会被清除。
     * 
     * @remarks
     * 此函数不接受任何参数。
     * 
     * @returns 无返回值。
     */
    onReboot() {
        MiniGameSdk.API.reboot();
    }

    /**
     * 当前函数用于在迷你游戏中实现退出功能。
     * 它调用了MiniGameSdk提供的API方法来触发退出操作。
     * 该方法通常在需要结束当前迷你游戏或返回到上一级菜单时被调用。
     */
    onExit() {
        MiniGameSdk.API.exit();
    }

    /**
     * 显示分享菜单。
     * 
     * 通过调用MiniGameSdk的API方法，触发显示分享菜单的操作。此函数旨在提供一个统一的入口，
     * 以便在需要时轻松调用分享功能，而无需直接与具体的SDK接口交互。
     * 
     * @remarks
     * 此方法不接受任何参数，也不返回任何值。
     */
    onShowShareMenu() {
        MiniGameSdk.API.showShareMenu();
    }

    /**
     * 导航到指定的小游戏。
     * 
     * 本函数用于触发导航到一个特定的小游戏。这需要提供目标小游戏的ID，
     * 以便系统能够正确地将用户重定向到目标小游戏。
     * 
     * 注意：这里的'xxx'是占位符，实际使用时需要替换为具体的小游戏ID。
     */
    onNavigate() {
        MiniGameSdk.API.navigateTo('xxx'); // xxx替换为你的小游戏id
    }

    /**
     * 激活字节跳动入口视图。
     * 
     * 此方法用于将字节跳动入口视图设置为活跃状态。当需要在用户界面中显示字节跳动的入口时，
     * 可以调用此方法来激活相应的视图元素，使其对用户可见。
     */
    onBytedanceEntranceView() {
        // this.entranceView.active = true;
    }

    /**
     * 请求登录代码
     * 
     * 本函数用于触发小程序的登录流程，获取微信或头条等第三方平台的登录代码。
     * 这些代码可以用于后续的用户身份验证和数据同步流程。
     */
    onGetLoginCode() {
        // 调用MiniGameSdk的API登录方法，传入一个回调函数处理登录结果
        MiniGameSdk.API.login((code: string, anonymousCode: string) => {
            // 打印微信或头条的登录代码
            console.log('Wechat Or Bytedance Code:', code);
            // 打印头条的匿名登录代码
            // console.log('Bytedance Anonymous Code:', anonymousCode);
            if(code){
                cc.fx.GameTool.getUserId(code, data => this.setUserId(data)); 
            }
        });
    }

    setUserId(data){
        cc.fx.GameConfig.GM_INFO.userId = data.data.userId;
        MiniGameSdk.API.getUserInfo(this.setUserInfo);
    }

    setUserInfo(data){
        console.log("获取到的用户信息",data.userInfo);
        var useData = {
            "gameId": cc.fx.GameConfig.GM_INFO.gameId,
            "userId": cc.fx.GameConfig.GM_INFO.userId,
            "nickName":data.userInfo.nickName,
            "pic": data.userInfo.avatarUrl
           
        }
        console.log("即将上传的用户信息:",cc.fx.GameConfig.GM_INFO.userId,data.userInfo.nickName,data.userInfo.avatarUrl);
        console.log("Post数据:",useData);
        cc.fx.HttpUtil.setUserInfo(useData,(res)=>{
            console.log("上传成功:",res);
        });
    }

    /**
     * 创建并显示游戏圈按钮
     * 
     * 本函数通过调用MiniGameSdk的GameClub实例方法，实现游戏俱乐部的创建和显示。
     * 它首先配置俱乐部的图标类型和位置大小，然后创建俱乐部，最后显示俱乐部。
     * 这样做是为了在小游戏内创建并展示一个游戏俱乐部的图标，供玩家加入或互动。
     */
    onCreateClub() {
        // 配置俱乐部图标为绿色，设置图标的位置为顶部200像素，左侧0像素
        MiniGameSdk.GameClub.instance.create(
            MiniGameSdk.EGameClubIcon.GREEN,
            { top: 200, left: 0 },
            { width: 50, height: 50 });
        // 显示游戏俱乐部图标
        MiniGameSdk.GameClub.instance.show();
    }
}
