import { _decorator, BoxCollider2D, Button, CircleCollider2D, Collider2D, Component, find, instantiate, Node, NodeEventType, tween, view, Vec3, mat4, UITransform } from 'cc';
import { resLoader, ResLoader } from '../../core_tgx/base/ResLoader';
import { CupHeight, TakeGobletGlobalInstance, WaterColors } from './TakeGobletGlobalInstance';
import { OutArea } from './Component/OutArea';
import { WaitArea } from './Component/WaitArea';
import { CocktailCup } from './Component/CocktailCup';
import { OriginCup } 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';
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)
    goblets: Node = null!;  //原浆区

    private originCupPositions = new Map<string, Vec3>(); // 改用唯一ID记录

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

    onDestroy() {
        this.unregisterListener();
    }

    registerListener() {
        EventDispatcher.instance.on(GameEvent.EVENT_CLICK_ORIGIN_CUP, this.handlePourOriginCup, this);
        EventDispatcher.instance.on(GameEvent.EVENT_ORIGIN_CUP_DESTROYED, (uuid: string) => {
            const cupNode = find(uuid) as Node;
            if (cupNode) {
                this.spawnNewOriginCup(cupNode);
            }
        }, this);
        EventDispatcher.instance.on(GameEvent.EVENT_COCKTAIL_CUP_DESTROYED, this.handleCupDestroyed, this);
    }

    unregisterListener() {
        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);
    }

    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.cupColor = instance.getRandomColor();
                cup.reset();
                allCups.push(cupNode);
            }
        }

        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(); // 重置所有暂存杯
        });
    }

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

    private generateOriginCups() {
        const outCups = this.outArea.getCups() as Node[];
        const waitCups = this.waitArea.getCups() as Node[];

        // DOTO 取前7个杯子颜色后期修改
        const allCups = [...outCups, ...waitCups].slice(0, 7);
        const colors = allCups.map(cup => {
            const comp = cup.getComponent(CocktailCup);
            return comp ? comp.cupColor : WaterColors.Blue;
        });

        this.goblets.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('在生成初始原浆杯时记录位置: ', 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) {
        // 如果子节点0是底层，需要反转顺序
        const colors: WaterColors[] = [];
        for (let i = originCup.waters.children.length - 1; i >= 0; i--) {
            const waterNode = originCup.waters.children[i];
            if (waterNode.active) {
                const water = waterNode.getComponent(Water);
                colors.push(water.color);
            }
        }

        let hasUnprocessed = false; // 标记是否有未处理的水层

        for (const color of colors) {
            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,
                color,
                targetIsTemp
            );

            // 更新目标杯
            if (targetIsTemp) {
                const tempCupComp = targetNode.getComponent(TempCup)!;
                tempCupComp.fill(color);
            } else {
                const cocktailCup = targetNode.getComponent(CocktailCup)!;
                cocktailCup.addLayer(color);
            }

            this.hideCurrentWaterLayer(originCup);
        }

        // 处理完所有颜色后检查剩余水层
        const remaining = originCup.waters.children.filter(n => n.active).length;
        if (hasUnprocessed || remaining > 0) {
            console.log("游戏结束：仍有未处理的水层");
            // 触发游戏结束逻辑
        } else {
            // 所有水层处理完毕，销毁原浆杯
            originCup.destroyOriginCup();
            this.addWaitCupToOutArea();
        }
    }

    // 添加等待区杯子到调酒区
    private addWaitCupToOutArea() {
        // 获取等待区最右侧杯子
        const waitCups = this.waitArea.getCups();
        if (waitCups.length === 0) return;

        const lastCup = waitCups[waitCups.length - 1];

        // 改变父节点到调酒区
        lastCup.setParent(this.outArea.node);

        // 从等待区移除
        this.waitArea.getCups().pop();

        // 调酒区所有杯子向右平移80
        this.outArea.getCups().forEach(cup => {
            tween(cup)
                .by(0.3, { position: new Vec3(80, 0, 0) }, { easing: 'sineOut' })
                .start();
        });

        // 等待区剩余杯子向右平移80
        this.waitArea.getCups().forEach(cup => {
            tween(cup)
                .by(0.3, { position: new Vec3(80, 0, 0) }, { easing: 'sineOut' })
                .start();
        });
    }

    private async pourAnimation(
        origin: Node,
        target: Node,
        color: WaterColors,
        isTempCup: boolean = false
    ) {
        // 使用正确的坐标转换
        const originParent = origin.parent!;
        const targetWorldPos = target.worldPosition;
        const localPos = originParent.getComponent(UITransform)!.convertToNodeSpaceAR(targetWorldPos);

        // 调整Y轴偏移量
        if (isTempCup) {
            localPos.y += 80; // 暂存杯偏移
        } else {
            localPos.y += 150; // 调酒杯偏移
        }

        // 只做单程移动，保留在目标位置
        await new Promise<void>(resolve => {
            tween(origin)
                .to(0.5, { position: localPos }) // 延长动画时间到0.5秒
                .call(() => resolve())
                .start();
        });
    }

    // 新增辅助方法
    private hideCurrentWaterLayer(originCup: OriginCup) {
        const activeWaters = originCup.waters.children.filter(n => n.active);
        if (activeWaters.length > 0) {
            const topIndex = activeWaters.length - 1;
            activeWaters[topIndex].active = false;
        }
    }

    private async spawnNewOriginCup(destroyedCup: Node) {
        // 获取被销毁杯子的初始位置
        const id = destroyedCup.uuid;
        const targetPos = this.originCupPositions.get(id) || Vec3.ZERO;

        // 创建新原浆杯
        const height = TakeGobletGlobalInstance.instance.generateOriginCupHeight();
        const prefab = await TakeGobletGlobalInstance.instance.loadAsyncOriginCup(height);
        const newCup = instantiate(prefab);

        // 设置初始位置（屏幕左侧）
        const uiTransform = this.node.getComponent(UITransform)!;
        newCup.setPosition(-uiTransform.width / 2, 0, 0);
        this.goblets.addChild(newCup);

        // 记录新杯子的初始位置
        this.originCupPositions.set(newCup.uuid, targetPos);

        // 移动动画到原位置
        tween(newCup)
            .to(0.5, { position: targetPos })
            .start();

        // DOTO 获取颜色配置
        const colors = this.getAvailableColors(5); // 获取前5个颜色
        this.setupOriginCupColors(newCup, 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 setupOriginCupColors(cupNode: Node, colors: WaterColors[]) {
        const originCup = cupNode.getComponent(OriginCup)!;
        const waters = originCup.waters.children;

        // 暂时写死5层水
        const waterCount = 5;
        for (let i = 0; i < waterCount; i++) {
            const waterNode = waters[i];
            if (!waterNode) continue;

            const water = waterNode.getComponent(Water)!;
            water.color = colors[Math.floor(Math.random() * colors.length)];
            waterNode.active = true;
        }
    }

    private handleCupDestroyed(destroyedCup: Node) {
        // 从outArea移除被销毁的杯子
        this.outArea.removeCup(destroyedCup);
        // 补充新杯子到等待区
        this.generateNewCupToWaitArea();
    }

    private async generateNewCupToWaitArea() {
        const configs = TakeGobletGlobalInstance.instance.getInitialCupsConfig();
        const randomConfig = configs[Math.floor(Math.random() * configs.length)];

        const prefab = await TakeGobletGlobalInstance.instance.loadAsyncCocktail(randomConfig.height);
        const newCup = instantiate(prefab);
        const cupComp = newCup.getComponent(CocktailCup)!;

        cupComp.cupColor = TakeGobletGlobalInstance.instance.getRandomColor();
        cupComp.reset();

        this.waitArea.addCup(newCup);
    }

    // 新增重置方法
    public resetLevel() {
        this.originCupPositions.clear();
        this.generateInitialCups();
    }
}

