import { _decorator, BoxCollider2D, Button, CircleCollider2D, Collider2D, Component, find, instantiate, Node, NodeEventType, tween, view, Vec3, mat4, UITransform, Label } from 'cc';
import { CupHeight, TakeGobletGlobalInstance, WaterColorLog, WaterColors } from './TakeGobletGlobalInstance';
import { OutArea } from './Component/OutArea';
import { WaitArea } from './Component/WaitArea';
import { CocktailCup } from './Component/CocktailCup';
import { OriginCup, OriginCupState } from './Component/OriginCup';
import { Water } from './Component/Water';
import { EventDispatcher } from '../../core_tgx/easy_ui_framework/EventDispatcher';
import { GameEvent } from './Enum/GameEvent';
import { TempCup } from './Component/TempCup';
import { TempCups } from './Component/TempCups';
import { tgxUIMgr, tgxUITips } from '../../core_tgx/tgx';
import { LevelManager } from './Manager/LevelMgr';
import { UI_BattleResult } from '../../scripts/UIDef';
import { GameUtil } from './GameUtil';
import { OriginArea } from './Component/OriginArea';
import { GtagMgr, GtagType } from '../../core_tgx/base/GtagMgr';
import { GlobalConfig } from '../../start/Config/GlobalConfig';
import { AdvertMgr } from '../../core_tgx/base/ad/AdvertMgr';
const { ccclass, property } = _decorator;

@ccclass('LevelAction')
export class LevelAction extends Component {

    @property(OutArea)
    outArea: OutArea = null!;  // 直接引用OutArea组件

    @property(WaitArea)
    waitArea: WaitArea = null!;  // 直接引用WaitArea组件

    @property(Node)
    tempCups: Node = null!;  //临时杯

    @property(Node)
    originArea: Node = null!;  //原浆区

    originCupPositions = new Map<string, Vec3>(); // 改用唯一ID记录
    private isProcessing = false; // 添加状态锁
    static instance: LevelAction; // 添加静态实例

    onLoad() {
        LevelAction.instance = this;
    }

    start() {
        this.generateInitialCups();
        this.registerListener();
        this.reportInformation();
    }

    //上报信息
    reportInformation() {
        const { level } = LevelManager.instance.levelModel;
        console.log(`上报信息 level:${level}`);
        GtagMgr.inst.doGameDot(GtagType.level_start, { level });

        if (!GlobalConfig.isDebug) {
            AdvertMgr.instance.showInterstitial();
        }
    }

    onDestroy() {
        this.unregisterListener();
    }

    registerListener() {
        EventDispatcher.instance.on(GameEvent.EVENT_REFRESH_COLOR, this.generateOriginCups, this);
        EventDispatcher.instance.on(GameEvent.EVENT_CLICK_ORIGIN_CUP, this.handlePourOriginCup, this);
        EventDispatcher.instance.on(GameEvent.EVENT_ORIGIN_CUP_DESTROYED, (uuid: string) => {
            if (!this.originCupPositions) return
            const targetPos = this.originCupPositions.get(uuid);
            if (targetPos) {
                this.spawnNewOriginCup(targetPos);
            }
        }, this);
        EventDispatcher.instance.on(GameEvent.EVENT_COCKTAIL_CUP_DESTROYED, this.handleCupDestroyed, this);
        EventDispatcher.instance.on(GameEvent.EVENT_RIGHT_CUP_FULL, this.addWaitCupToOutArea, this);
    }

    unregisterListener() {
        EventDispatcher.instance.off(GameEvent.EVENT_REFRESH_COLOR, this.generateOriginCups, this);
        EventDispatcher.instance.off(GameEvent.EVENT_CLICK_ORIGIN_CUP, this.handlePourOriginCup, this);
        EventDispatcher.instance.off(GameEvent.EVENT_ORIGIN_CUP_DESTROYED, this.spawnNewOriginCup, this);
        EventDispatcher.instance.off(GameEvent.EVENT_COCKTAIL_CUP_DESTROYED, this.handleCupDestroyed, this);
        EventDispatcher.instance.off(GameEvent.EVENT_RIGHT_CUP_FULL, this.addWaitCupToOutArea, this);
    }

    private async generateInitialCups() {
        const instance = TakeGobletGlobalInstance.instance;
        const configs = instance.getInitialCupsConfig();

        const allCups: Node[] = [];
        for (const config of configs) {
            for (let i = 0; i < config.count; i++) {
                const prefab = await instance.loadAsyncCocktail(config.height);
                const cupNode = instantiate(prefab);
                const cup = cupNode.getComponent(CocktailCup)!;

                cup.reset();
                allCups.push(cupNode);
            }
        }

        const levelColors = LevelManager.instance.levelModel.levelColors;
        const rule = instance.cocktailCupRule();
        const [x, y] = rule;
        const colorPool = levelColors.slice(0, y);

        // 为所有杯子分配颜色，并控制颜色种类不超过y种
        allCups.forEach(cup => {
            const cupComp = cup.getComponent(CocktailCup)!;
            // 从颜色池随机选择一个颜色
            const randomColor = colorPool[Math.floor(Math.random() * colorPool.length)];
            cupComp.cupColor = randomColor;
        });

        console.log('allCups: ', allCups.length);
        // 分配初始位置
        allCups.slice(0, 2).forEach(cup => this.outArea.addCup(cup));
        allCups.slice(2).forEach(cup => this.waitArea.addCup(cup));

        // 在分配完调酒杯后添加
        this.generateOriginCups();

        // 初始化暂存区
        this.tempCups.children.forEach(tempCupNode => {
            const tempCup = tempCupNode.getComponent(TempCup)!;
            tempCup.reset(); // 重置所有暂存杯
        });

        EventDispatcher.instance.emit(GameEvent.EVENT_REFRESH_REMAIN_CUP);
    }

    // 当调酒区杯子被消除时调用
    public async handleCupsRemoved(count: number) {
        for (let i = 0; i < count; i++) {
            const cup = this.waitArea.takeCup();
            if (cup) {
                this.outArea.addCup(cup);
            }
        }
    }

    private async generateOriginCups() {
        if (this.isProcessing) {
            tgxUITips.show('我知道你很急，但你先别急!');
            return;
        }
        const levelModel = LevelManager.instance.levelModel;
        const outCups = this.outArea.getCups() as Node[];
        const waitCups = this.waitArea.getCups() as Node[];

        const measuringcup_number = levelModel.levelConfig.measuringcup_number;
        const allCups = [...outCups, ...waitCups].slice(0, measuringcup_number);
        const colors = allCups.map(cup => {
            const comp = cup.getComponent(CocktailCup);
            return comp ? comp.cupColor : WaterColors.Blue;
        });

        this.originArea.children.forEach(originCupNode => {
            const originCup = originCupNode.getComponent(OriginCup)!;
            const waters = originCup.waters.children;

            for (let i = 0; i < originCup.cupHeight; i++) {
                const waterNode = waters[i];
                const water = waterNode.getComponent(Water);
                if (water) {
                    water.initColor(colors[Math.floor(Math.random() * colors.length)]);
                    waterNode.active = true;
                }
            }

            // 在生成初始原浆杯时记录位置
            const id = originCupNode.uuid; // 使用节点唯一ID
            this.originCupPositions.set(id, originCupNode.position.clone());
            // console.log('在生成初始原浆杯时记录id : ', id, originCupNode.position);
        });
    }

    private findTargetCupInOutArea(color: WaterColors): { node: Node, comp: CocktailCup } | null {
        const validCups = this.outArea.getCups()
            .map(node => ({
                node,
                comp: node.getComponent(CocktailCup)!
            }))
            .filter(({ comp }) =>
                comp &&
                comp.cupColor === color &&
                !comp.isFull
            );

        if (validCups.length === 0) return null;

        const sorted = validCups.sort((a, b) => (a.comp.remainingCapacity ?? 0) - (b.comp.remainingCapacity ?? 0));
        return sorted[0];
    }

    public async handlePourOriginCup(originCup: OriginCup) {
        if (this.isProcessing) {
            tgxUITips.show('我知道你很急，但你先别急!');
            return;
        }
        this.isProcessing = true;

        try {
            // 如果子节点0是底层，需要反转顺序
            const watersNode: Node[] = [];
            for (let i = originCup.waters.children.length - 1; i >= 0; i--) {
                const waterNode = originCup.waters.children[i];
                if (waterNode.active) {
                    watersNode.push(waterNode);
                }
            }

            let hasUnprocessed = false; // 标记是否有未处理的水层
            originCup.setMark(false);

            for (const waterNode of watersNode) {
                const color = waterNode.getComponent(Water)!.color;
                console.log(`当前处理的颜色:${WaterColorLog[color]}}`);
                let targetNode: Node | null = this.findTargetCupInOutArea(color)?.node || null;
                let targetIsTemp = false;

                // 调酒区未找到，查找暂存区
                if (!targetNode) {
                    const tempCupsComp = this.tempCups.getComponent(TempCups);
                    if (!tempCupsComp) {
                        console.error('TempCups component not found!');
                        continue;
                    }
                    const tempCup = tempCupsComp.findAvailableTempCup();
                    if (tempCup) {
                        targetNode = tempCup.node;
                        targetIsTemp = true;
                    }
                }

                if (!targetNode) {
                    hasUnprocessed = true;
                    console.log(`颜色${WaterColors[color]}未找到可用杯子`);
                    continue; // 继续尝试处理后续颜色
                }

                await this.pourAnimation(
                    originCup.node,
                    targetNode,
                    undefined,
                    targetIsTemp
                );

                originCup.pourWater();
                // 更新目标杯
                if (targetIsTemp) {
                    const tempCupComp = targetNode.getComponent(TempCup)!;
                    await tempCupComp.fill(color);
                } else {
                    const cocktailCup = targetNode.getComponent(CocktailCup)!;
                    await cocktailCup.addLayer(); // 等待添加水层流程完成
                }

                originCup.hideCurrentWaterLayer();
            }

            // 处理完所有颜色后检查剩余水层
            const remaining = originCup.waters.children.filter(n => n.active).length;
            if (hasUnprocessed || remaining > 0) {
                // console.log("游戏结束：仍有未处理的水层");
                this.isProcessing = true;

                const waitLength = this.waitArea!.getCups().length;
                const outLength = this.outArea!.getCups().length;
                let remain = waitLength + outLength;
                console.log(`waitLength:${waitLength} +  outLenght:${outLength} = remain:${remain}`);
                LevelManager.instance.levelModel.remainCupCount = remain;

                LevelManager.instance.levelModel.isWin = false;
                tgxUIMgr.inst.showUI(UI_BattleResult);
            } else {
                // 所有水层处理完毕，销毁原浆杯
                await originCup.destroyOriginCup();
                this.addWaitCupToOutArea();
            }
        } finally {
            this.isProcessing = false;
        }
    }

    //处理暂存区倒水到调酒区
    private async handlePourTempCupToOutArea() {
        if (this.isProcessing) return;
        this.isProcessing = true;

        try {
            const tempCupsComp = this.tempCups.getComponent(TempCups)!;
            const filledCups = tempCupsComp.getFilledCups();

            for (const tempCup of filledCups) {
                const originalPos = tempCup.node.position.clone();
                const colors = tempCup.getColors();

                for (const color of colors) {
                    const targetCup = this.findTargetCupInOutArea(color);
                    if (!targetCup) {
                        // console.log(`颜色${WaterColors[color]}未找到可用调酒杯`);
                        continue;
                    }

                    await this.pourAnimation(
                        tempCup.node,
                        targetCup.node,
                        originalPos,
                        true
                    );

                    tempCup.pour();
                    const cocktailCup = targetCup.comp;
                    await cocktailCup.addLayer();

                    await GameUtil.delay(0.2);
                    // 返回到暂存区初始位置
                    if (originalPos) {
                        await new Promise(resolve => {
                            tween(tempCup.node)
                                .to(0.3, { position: originalPos })
                                .call(() => {
                                    tempCup.reset();
                                    resolve(true);
                                })
                                .start();
                        });
                    }
                }
            }
        } finally {
            this.isProcessing = false;
        }
    }

    // 添加新杯子后触发暂存区倒水
    private async addWaitCupToOutArea() {
        const waitCups = this.waitArea.cups;
        const outCups = this.outArea.getCups();
        const needAddCount = outCups.length === 0 ? 2 : 1;
        const byX = outCups.length === 0 ? 220 : 110;

        const movingCups: Node[] = [];
        for (let i = 0; i < needAddCount; i++) {
            if (waitCups.length === 0) break;
            movingCups.push(waitCups.pop()!);
        }

        const newCups: Node[] = [];
        for (const cup of movingCups) {
            const comp = cup.getComponent(CocktailCup)!;
            const prefab = await TakeGobletGlobalInstance.instance.loadAsyncCocktail(comp.cupHeight);
            const newCup = instantiate(prefab);
            const newComp = newCup.getComponent(CocktailCup)!;

            newComp.cupColor = comp.cupColor;
            newComp.reset();

            const targetX = outCups.length === 0 ?
                (newCups.length === 0 ? -160 : -50) :
                -50;
            newCup.setPosition(new Vec3(targetX, 0, 0));

            newCups.push(newCup);
            cup.destroy();
        }

        const outNodes = this.outArea.node.getChildByName('OutNodes')!;
        newCups.forEach(cup => cup.setParent(outNodes));

        // 执行统一平移
        if (this.waitArea.getCups().length > 0) {
            this.outArea.getCups().concat(this.waitArea.getCups()).forEach(cup => {
                tween(cup)
                    .by(0.3, { position: new Vec3(byX, 0, 0) }, { easing: 'sineOut' })
                    .start();
            });
        }

        await GameUtil.delay(0.2);
        // 在添加完成后处理暂存区倒水
        await this.handlePourTempCupToOutArea();

        // 胜利条件检测：当两个区域都没有杯子时触发胜利
        if (this.outArea.getCups().length === 0 && this.waitArea.cups.length === 0) {
            this.isProcessing = true;
            LevelManager.instance.levelModel.isWin = true;
            tgxUIMgr.inst.showUI(UI_BattleResult);
        }
    }

    /** 倒水移动动画
     * @param origin 原杯子
     * @param target 目标杯子
     * @param originalPos 原始位置
     * @param isTempCup 是否是暂存区杯子
    */
    private async pourAnimation(
        origin: Node,
        target: Node,
        originalPos?: Vec3,
        isTempCup: boolean = false
    ) {
        const targetWorldPos = target.getWorldPosition().clone();
        const tempRegex = /TempCup/.test(origin.name);
        // 调整偏移量
        targetWorldPos.x -= !tempRegex ? 55 : 20;
        targetWorldPos.y += !tempRegex ? 125 : 205;

        // 移动动画到目标位置
        await new Promise<void>(resolve => {
            tween(origin)
                .to(0.5, { worldPosition: targetWorldPos })
                .call(resolve)
                .start();
        });
    }

    private async spawnNewOriginCup(targetPos: Vec3) {
        const levelModel = LevelManager.instance.levelModel;
        const measuringcup_number = levelModel.levelConfig.measuringcup_number;//获取调酒和等待区前面数量
        const colors = this.getAvailableColors(measuringcup_number);
        if (colors.length <= 0) return;

        // 创建新原浆杯
        const height = TakeGobletGlobalInstance.instance.generateOriginCupHeight();
        const prefab = await TakeGobletGlobalInstance.instance.loadAsyncOriginCup(height);
        const newCup = instantiate(prefab);
        this.originArea.addChild(newCup);
        await newCup.getComponent(OriginCup)?.spawnNewOriginCup(height, targetPos, colors);
    }

    // 获取可用颜色
    private getAvailableColors(count: number): WaterColors[] {
        const outCups = this.outArea.getCups();
        const waitCups = this.waitArea.getCups();
        const allCups = [...outCups, ...waitCups].slice(0, count);

        return allCups.map(cup => {
            const comp = cup.getComponent(CocktailCup);
            return comp ? comp.cupColor : WaterColors.Blue;
        });
    }

    private handleCupDestroyed(destroyedCup: Node) {
        // 从outArea移除被销毁的杯子
        this.outArea.removeCup(destroyedCup);
    }
}

