import { _decorator, Component, Label, Node, tween, UIOpacity, v3, Vec3, Sprite, UITransform, instantiate } from 'cc';
import { AudioManager } from '../AudioManager';
import LocalizedLabel from '../i18n/LocalizedLabel';
import PoolManager from '../PoolManager';
import { Popup } from '../src/ui/page/popup';
import { Url } from '../Url';
import { BlockConfig, BlockState, GridBoardData } from './Block/BlockData';
import GlobalData from './GlobalData';
import { GridBlockMgr } from './GridBlockMgr';
import { Guide } from './Guide';
import { LocalStorageMgr } from './LocalStorageMgr';
import { TouchMgr } from './TouchMgr';
import { BlockController } from './Block/BlockController';
const { ccclass, property } = _decorator;

@ccclass('MainGameLogic')

export class MainGameLogic extends Component {

    /** 单例模式 */
    private static _ins: MainGameLogic;
    constructor() {
        super();
        MainGameLogic._ins = this;
    }
    public static get ins(): MainGameLogic {
        if (!MainGameLogic._ins) {
            MainGameLogic._ins = new MainGameLogic();
        }
        return MainGameLogic._ins;
    }

    @property(Node)
    background: Node = null;

    @property(Node)
    guide: Node = null;
    @property(Label)
    curScoreLabel: Label = null;
    @property(Label)
    historyScoreLabel: Label = null;
    @property(Label)
    todayScoreLabel: Label = null;
    /** 当前得分 */
    public curScore: number = 0;
    /** 特殊处理总钱数 */
    spaciCashTotal: number = 0;
    sssspaciCashTotal: number = 0;
    @property(Label)
    refrashPropLabel: Label = null;
    @property(Label)
    hummerPropLabel: Label = null;
    lotteryData: any = null;

    private lastReturnedIndex: number = 0;

    @property(Node)
    tarPropRefrashIcon: Node = null;
    @property(Node)
    tarPropHummerIcon: Node = null;

    //特效展示节点
    @property(Node)
    effectsContainer: Node = null;

    propInUse: boolean = false;

    @property(Node)
    autoPlayBtn: Node = null;  // 自动放置按钮

    isAutoPlaying: boolean = false;  // 自动播放状态
    autoPlayTimer: any = null;  // 自动播放计时器

    start() {
        AudioManager.ins.play(Url.AUDIO.BGM);
        this.gameStart();
    }

    //游戏开始
    gameStart() {

        if (!GlobalData.isCommer || GlobalData.guideRecord >= 5) {
            GlobalData.isCommer = false;
            LocalStorageMgr.setItem(LocalStorageMgr.isCommer_key, GlobalData.isCommer);
            GridBlockMgr.ins.generateBoard_effect(GlobalData.lastGameBoard);
            this.scheduleOnce(() => {
                GridBlockMgr.ins.generateSpecificSelectionBlock(false)
            }, 2);
            this.guide.active = false;
        } else {
            console.log("开启新手引导");
            this.guide.active = true;
        }

        mtec.cc.adaptBackgroundNode(this.background);

        //不需要
        // this.checkAndUpdateDailyHighScore(GlobalData.lastLoginDate);

        //更新道具数量，不需要
        // this.updatePropNum();
    }

    //游戏结束
    gameOver() {
        this.scheduleOnce(async () => {
            await Popup.Gameoverpage();
        }, 3)

    }

    //重新开始游戏
    reStartGame() {
        this.curScore = 0;
        GlobalData.curScore = 0;
        LocalStorageMgr.setItem(LocalStorageMgr.curScore_key, GlobalData.curScore);
        this.updateScores(GlobalData.curScore)
        GridBlockMgr.ins.generateBoard_effect(GridBoardData.customizeBoardData5);
        this.scheduleOnce(() => {
            GridBlockMgr.ins.generateSpecificSelectionBlock(false)
        }, 2)
    }

    // 生成一个分数特效
    async createEleAddScoreEff(effPos: Vec3, scoreNum: number) {
        let addsecore = await PoolManager.getObject('labelTip');
        addsecore.setParent(this.effectsContainer);
        addsecore.setPosition(effPos);
        addsecore.angle = 0;
        addsecore.getComponent(Label).string = '+' + scoreNum.toString();
        // addsecore.qtJumpDistance(new Vec3(this.randInt(-400, 400), -this.randInt(1000, 1500), 0), this.randInt(1000, 1300), 1, 1)
        //     .call(() => {
        //         PoolManager.putObject('labelTip', addsecore)
        //     })
        //     .start();
        tween(addsecore)
            .to(0.3, { scale: v3(6, 6, 1) })
            .delay(0.5)
            .to(0.5, { scale: v3(0, 0, 1) }, { easing: 'backIn' })
            .call(() => {
                this.updateScores(scoreNum);
                PoolManager.putObject('labelTip', addsecore)
            })
            .start();
    }

    // 生成连续消除特效
    async createConsecutiveEffect(effPos: Vec3, totalClearedLines: number) {
        if (!effPos) {
            return
        }
        let consecutiveEff;
        let name;
        if (totalClearedLines < 2) {
            return;
        }
        if (totalClearedLines == 2) {
            //good
            consecutiveEff = await PoolManager.getObject('good');
            AudioManager.ins.playOneShot(Url.AUDIO.SFX17, 1);
            name = 'good'
        } else if (totalClearedLines == 3) {
            //great
            consecutiveEff = await PoolManager.getObject('great');
            AudioManager.ins.playOneShot(Url.AUDIO.SFX18, 1);
            name = 'great'
        } else if (totalClearedLines == 4) {
            //excellent
            consecutiveEff = await PoolManager.getObject('excellent');
            AudioManager.ins.playOneShot(Url.AUDIO.SFX19, 1);
            name = 'excellent'
        } else if (totalClearedLines == 5) {
            //amazing
            consecutiveEff = await PoolManager.getObject('amazing');
            AudioManager.ins.playOneShot(Url.AUDIO.SFX20, 1);
            name = 'amazing'
        } else if (totalClearedLines >= 6) {
            //unbelievable
            consecutiveEff = await PoolManager.getObject('unbelievable');
            AudioManager.ins.playOneShot(Url.AUDIO.SFX21, 1);
            name = 'unbelievable'
        }

        consecutiveEff.setParent(this.effectsContainer);
        consecutiveEff.setPosition(effPos);
        consecutiveEff.angle = 0;
        consecutiveEff.setScale(v3(0, 0, 1))
        // consecutiveEff.qtJumpDistance(new Vec3(this.randInt(-400, 400), -this.randInt(1000, 1500), 0), this.randInt(1000, 1200), 1, 1)
        //     .call(() => {
        //         PoolManager.putObject(name, consecutiveEff)
        //     })
        //     .start();
        tween(consecutiveEff)
            .to(0.3, { scale: v3(1, 1, 1) })
            .delay(0.5)
            .to(0.5, { scale: v3(0, 0, 1) }, { easing: 'backIn' })
            .call(() => {
                PoolManager.putObject(name, consecutiveEff)
            })
            .start();
    }

    //  生成一个tip吐司、
    async createOneTipTpast(str: string, insert: string = null) {
        let tip: Node = await PoolManager.getObject('tip');
        tip.setParent(this.effectsContainer);
        tip.setPosition(v3(0, 0, 0));
        tip.getComponent(UIOpacity).opacity = 255;
        let tiplabel = tip.children[0].getComponent(Label)
        let localizedLabel = tiplabel.node.getComponent(LocalizedLabel);
        localizedLabel.setTextKeyAndOption(str, insert);

        tween(tip)
            .delay(0.5)
            .to(0.5, { position: v3(0, 50, 0) })
            .call(() => {
                PoolManager.putObject('tip', tip)
            })
            .start()

        tween(tip.getComponent(UIOpacity))
            .delay(0.5)
            .to(0.5, { opacity: 0 })
            .start()
    }


    colorMap = {
        BLUE: '#00B8FF',       // 蓝色
        DEEPBLUE: '#00008B',   // 深蓝色
        GREEN: '#008000',      // 绿色
        ORANGE: '#FFA500',     // 橘色
        PURPLE: '#800080',     // 紫色
        RED: '#FF0000',        // 红色
        YELLOW: '#FFFF00'      // 黄色
    };
    /// 根据 Url.BLOCK 对象的值获取对应的颜色值
    getColorHexFromUrl(blockUrl) {
        // 遍历 Url.BLOCK 对象，找到匹配的键名
        for (let key in Url.BLOCK) {
            if (Url.BLOCK[key] === blockUrl) {
                return this.colorMap[key]; // 返回对应的颜色值
            }
        }
        return 'Invalid block URL'; // 如果未找到匹配项，返回错误信息
    }

    async createOneBlockEfEffect(blocknode: Node, block_color: string) {
        let colorHEX = this.getColorHexFromUrl(block_color);
        for (let i = 0; i < 2; i++) {
            let tarEfPos = TouchMgr.ins.getNodeAToNodeBPoint(blocknode, this.effectsContainer);
            let blockef = await PoolManager.getObject('ef');
            blockef.setParent(this.effectsContainer);
            blockef.setPosition(tarEfPos.add(v3(this.randInt(-20, 20), this.randInt(-20, 20), 0)));
            blockef.active = true;
            blockef.getComponent(UIOpacity).opacity = 255;
            // blockef.getComponent(Sprite).color = new Color().fromHEX(colorHEX);
            blockef.setScale(v3(0, 0, 0));
            let s = this.randFloat(0.5, 1.2);
            tween(blockef)
                .parallel(
                    tween().to(0.3, { scale: v3(s, s, 0) }),
                    tween().to(0.3, { angle: this.randInt(0, 360) })
                )
                .start()

            tween(blockef.getComponent(UIOpacity))
                .delay(0.3)
                .to(0.3, { opacity: 0 })
                .call(() => {
                    PoolManager.putObject('ef', blockef); // 回收到对象池
                })
                .start()
        }
    }

    //  随机生成一个力的值
    getRandomForce(min1, max1, min2, max2) {
        // 50% 的概率选择第一个区间 [-5000, -2000]，或第二个区间 [2000, 5000]
        if (Math.random() < 0.5) {
            return Math.random() * (max1 - min1) + min1; // [-5000, -2000]
        } else {
            return Math.random() * (max2 - min2) + min2; // [2000, 5000]
        }
    }

    randInt(min: number, max: number = undefined): number {
        if (max === undefined) {
            max = min;
            min = 0;
        }
        min = Math.ceil(min);
        max = Math.floor(max);
        return Math.floor(Math.random() * (max - min)) + min;
    }
    randFloat(min: number, max: number = undefined): number {
        if (max === undefined) {
            max = min;
            min = 0;
        }
        return Math.random() * (max - min) + min;
    }


    /**
     * 使用锤子道具特效
     * @param targetPos 飞向目标位置
     */
    // async usePropHummerEffect(targetPos: Vec3, call) {

    //     let hummer = await PoolManager.getObject('hummer');
    //     hummer.setParent(this.effectsContainer);
    //     hummer.setPosition(v3(0, 0, 0));
    //     hummer.setScale(2, 2, 1);
    //     hummer.angle = 0;
    //     tween(hummer)
    //         .delay(0.2)
    //         .parallel(
    //             tween().to(0.3, { position: targetPos }),
    //             tween().to(0.3, { angle: -30 })
    //         )
    //         .call(() => {
    //             AudioManager.ins.playOneShot(Url.AUDIO.SFX8, 1);
    //         })
    //         .to(0.2, { angle: 70 })
    //         .call(() => {
    //             call();
    //             PoolManager.putObject('hummer', hummer);
    //         })
    //         .start()
    // }

    // updatePropNum() {
    //     this.refrashPropLabel.string = 'x' + GlobalData.refrashPropNum.toString();
    //     this.hummerPropLabel.string = 'x' + GlobalData.hummerPropNum.toString();
    //     let refrashadicon = this.refrashPropLabel.node.parent.getChildByName('adicon');
    //     let hummeradicon = this.hummerPropLabel.node.parent.getChildByName('adicon');
    //     if (GlobalData.refrashPropNum == 0) {
    //         this.refrashPropLabel.node.active = false;
    //         refrashadicon.active = true;
    //     } else {
    //         this.refrashPropLabel.node.active = true;
    //         refrashadicon.active = false;
    //     }
    //     if (GlobalData.hummerPropNum == 0) {
    //         this.hummerPropLabel.node.active = false;
    //         hummeradicon.active = true;
    //     } else {
    //         this.hummerPropLabel.node.active = true;
    //         hummeradicon.active = false;
    //     }
    // }

    // async useRefrashProp(event, _gameOverUse = false) {
    //     if (_gameOverUse) {
    //         AudioManager.ins.playOneShot(Url.AUDIO.SFX7, 1);
    //         GridBlockMgr.ins.generateSpecificSelectionBlock(true);
    //         return
    //     }

    //     if (this.propInUse) {
    //         return
    //     }
    //     if (GlobalData.refrashPropNum > 0) {
    //         this.propInUse = true;
    //         AudioManager.ins.playOneShot(Url.AUDIO.SFX7, 1);
    //         GridBlockMgr.ins.generateSpecificSelectionBlock(true);
    //         GlobalData.refrashPropNum--;
    //         this.updatePropNum();

    //     } else {
    //         AudioManager.ins.pauseBgm();
    //         //  触发广告
    //         let isCom = await true;
    //         if (isCom) {
    //             GlobalData.refrashPropNum++;
    //             this.updatePropNum();
    //             AudioManager.ins.resumeBgm();
    //         }
    //     }
    //     LocalStorageMgr.setItem(LocalStorageMgr.refrashPropNum_key, GlobalData.refrashPropNum)
    // }

    // async useHummerProp(event, _gameOverUse = false) {
    //     // console.log(_gameOverUse);

    //     if (_gameOverUse) {
    //         GridBlockMgr.ins.chechAndEliminateRandomArea();
    //         return
    //     }
    //     if (this.propInUse) {
    //         return
    //     }
    //     if (GlobalData.hummerPropNum > 0) {
    //         this.propInUse = true;
    //         let isUse = GridBlockMgr.ins.chechAndEliminateRandomArea();
    //         // console.log(isUse);
    //         if (isUse) {
    //             GlobalData.hummerPropNum--;
    //             this.updatePropNum();
    //         }

    //     } else {
    //         AudioManager.ins.pauseBgm();
    //         //  触发广告
    //         let isCom = await true;
    //         if (isCom) {
    //             GlobalData.hummerPropNum++;
    //             this.updatePropNum();
    //             AudioManager.ins.resumeBgm();
    //         }
    //     }
    //     LocalStorageMgr.setItem(LocalStorageMgr.hummerPropNum_key, GlobalData.hummerPropNum)
    // }

    /** 检测引导和合成次数 */
    public async detectGuideAndElimiTimes(add_tempel_lotNum: number) {
        GlobalData.elimiTimes++;
        LocalStorageMgr.setItem(LocalStorageMgr.elimiTimes_key, GlobalData.elimiTimes);
        if (GlobalData.isCommer) {
            Guide.ins.completeCurGuide(GlobalData.elimiTimes + 1);
        }
    }

    /** 检查是否是新的一天并更新今日最高分 */
    // public checkAndUpdateDailyHighScore(lastLoginDate: string): void {
    //     // 更新当前得分
    //     this.curScore = GlobalData.curScore;
    //     // 获取当前日期
    //     const currentDate = new Date().toDateString();

    //     // 检查是否是同一天 
    //     console.log('是否是同一天：', lastLoginDate == currentDate);

    //     if (lastLoginDate !== currentDate) {//不是同一天
    //         GlobalData.todayHighScore = 0;
    //         LocalStorageMgr.setItem(LocalStorageMgr.todayHighScore_key, GlobalData.todayHighScore);

    //     } else {
    //         if (GlobalData.curScore >= GlobalData.todayHighScore) {
    //             GlobalData.todayHighScore = GlobalData.curScore;
    //             LocalStorageMgr.setItem(LocalStorageMgr.todayHighScore_key, GlobalData.todayHighScore);
    //         }
    //     }

    //     // 更新最后登录日期
    //     LocalStorageMgr.setItem(LocalStorageMgr.lastLoginDate_key, currentDate);
    //     this.updateScoreLabel(this.historyScoreLabel, GlobalData.historyHighScore);
    //     this.updateScoreLabel(this.todayScoreLabel, GlobalData.todayHighScore);
    //     this.updateScoreLabel(this.curScoreLabel, GlobalData.curScore);

    // }

    /** 更新分数 */
    public updateScores(addScore: number): void {
        // 更新当前得分
        this.curScore += addScore;
        GlobalData.curScore = this.curScore;
        // 更新今日最高分
        if (this.curScore > GlobalData.todayHighScore) {
            GlobalData.todayHighScore = this.curScore;
            this.updateScoreLabel(this.todayScoreLabel, this.curScore)
        }

        // 更新历史最高分
        if (this.curScore > GlobalData.historyHighScore) {
            GlobalData.historyHighScore = this.curScore;
            this.updateScoreLabel(this.historyScoreLabel, this.curScore)
        }

        this.updateScoreLabel(this.curScoreLabel, this.curScore);

        // 保存分数的方法
        LocalStorageMgr.setItem(LocalStorageMgr.historyHighScore_key, GlobalData.historyHighScore);
        LocalStorageMgr.setItem(LocalStorageMgr.todayHighScore_key, GlobalData.todayHighScore);
        LocalStorageMgr.setItem(LocalStorageMgr.curScore_key, GlobalData.curScore);
    }

    /**
     * 更新分数标签，使其逐渐增长到新分数
     * @param tarLabel 目标标签
     * @param newScore 新分数
     * @param duration 动画持续时间
     */
    updateScoreLabel(tarLabel: Label, newScore: number, duration: number = 1): void {
        const currentScore = parseInt(tarLabel.string) || 0;
        const delta = newScore - currentScore;

        if (delta === 0) {
            return;
        }

        tween({ value: currentScore })
            .to(duration, { value: newScore }, {
                onUpdate: (target: { value: number }) => {
                    tarLabel.string = Math.floor(target.value).toString();
                }
            })
            .start();

        //当前分数超过关分数就通关
        if ((newScore >= 100)) {
            console.log("通关了");
        }
    }

}


