import { _decorator, Component, ERaycast2DType, find, geometry, Node, PhysicsSystem, PhysicsSystem2D } from 'cc';
import { CarColorLog, CarColors, CarTypes } from '../CarColorsGlobalTypes';
import { CarBoxComponent } from '../Components/CarBoxComponent';
import { CarCarColorsComponent } from '../Components/CarCarColorsComponent';
import { EventDispatcher } from 'db://assets/core_tgx/easy_ui_framework/EventDispatcher';
import { GameEvent } from '../Enum/GameEvent';
import { CarColorsGlobalInstance } from '../CarColorsGlobalInstance';
import { LevelAction } from '../LevelAction';
import { PinComponent } from '../Components/PinComponent';
import { GameUtil } from '../GameUtil';
const { ccclass, property } = _decorator;

@ccclass('CarCarColorsSysterm')
export class CarCarColorsSysterm extends Component {
    activeCar: Map<string, Node> = new Map()

    carSeats: Array<CarColors> = []

    carBoxMap: Array<CarBoxComponent> = []

    pinColorIndex: number = 0;

    protected start(): void {
        EventDispatcher.instance.on(GameEvent.EVENT_REFRESH_COLOR, this.refreshCarColor, this);
    }

    protected onDestroy(): void {
        EventDispatcher.instance.off(GameEvent.EVENT_REFRESH_COLOR, this.refreshCarColor);
    }

    addCar(node: Node) {
        const carBoxCom = node.getComponent(CarBoxComponent)
        if (carBoxCom) {
            this.carBoxMap.push(carBoxCom)
            node.getChildByName("cars").children.forEach((car) => {
                this.addCar(car)
            })
            return
        }
        this.activeCar.set(node.uuid, node)
        if (!node.getComponent(CarCarColorsComponent)) return;
        const color = node.getComponent(CarCarColorsComponent).carColor
        const carType = node.getComponent(CarCarColorsComponent).carType
        let len = 0;
        if (carType === CarTypes.Bus) {
            len = 8
        }
        else if (carType === CarTypes.Minivan) {
            len = 6
        } else if (carType === CarTypes.Sedan) {
            len = 4
        } else if (carType === CarTypes.Single) {
            len = 1
        }

        for (; len--;) {
            this.carSeats.push(color)
        }
    }

    //根据难易度对 carSeats 进行排序
    sortCarSeatsByDifficulty() {
        // 生成车辆颜色与其对应的难易度评分映射
        const carDifficultyMap: { color: CarColors; difficultyScore: number; seats: number }[] = [];

        this.activeCar.forEach((node, uuid) => {
            const carComponent = node.getComponent(CarCarColorsComponent);
            if (!carComponent) return;

            // 调用计算难易度的方法
            const difficultyScore = this.calculateCarDifficulty(node);

            // 获取车类型对应的座位数
            let seats = 0;
            if (carComponent.carType === CarTypes.Bus) {
                seats = 8;
            } else if (carComponent.carType === CarTypes.Minivan) {
                seats = 6;
            } else if (carComponent.carType === CarTypes.Sedan) {
                seats = 4;
            } else if (carComponent.carType === CarTypes.Single) {
                seats = 1;
            }

            // 添加到映射数组
            carDifficultyMap.push({
                color: carComponent.carColor,
                difficultyScore,
                seats,
            });
        });

        // 按难易度降序排序（难的排前面，易的排后面）
        carDifficultyMap.sort((a, b) => b.difficultyScore - a.difficultyScore);

        // 根据排序结果重新生成 carSeats 数组
        this.carSeats = [];
        carDifficultyMap.forEach((item) => {
            for (let i = 0; i < item.seats; i++) {
                this.carSeats.push(item.color);
            }
        });
    }

    // 计算车的难易度评分
    calculateCarDifficulty(node: Node): number {
        const carComponent = node.getComponent(CarCarColorsComponent);
        if (!carComponent) return Infinity;

        // 检测车是否被阻挡
        const isBlocked = carComponent.checkCollision();

        // 获取车前方障碍物数量
        const obstacleCount = carComponent.checkCollisionNum();

        // 计算最终难易度评分
        // 难易度越低越容易：没有被阻挡则 -10，障碍物数量乘以权重 2，类型分值
        const difficultyScore = (isBlocked ? 10 : -10) + obstacleCount * 2;
        return difficultyScore;
    }

    removeCar(node: Node) {
        this.activeCar.delete(node.uuid)
        // console.log(this.activeCar);
    }

    clearAll() {
        this.activeCar.clear()
        this.carBoxMap.length = 0
        this.carBoxMap = []

        this.carSeats.length = 0
        this.carSeats = []

        this.pinColorIndex = 0;
    }

    //移除被解锁的钉子颜色
    removeColorFromSeats(color: CarColors) {
        // console.log('被移除的钉子颜色:', CarColorLog[color]);
        const index = this.carSeats.indexOf(color)
        if (index > -1) {
            this.carSeats.splice(index, 1)
        }
    }

    refreshCarColor() {
        // 找出外圈没被挡住的车子
        const canOutCar: CarCarColorsComponent[] = [];
        const cars = find("Canvas/Scene/Levels").children[0].getComponentsInChildren(CarCarColorsComponent)!;

        cars.forEach(car => {
            const carComp = car.getComponent(CarCarColorsComponent);
            const collider = carComp.checkCollision();

            if (!collider) {
                canOutCar.push(car);
            }
        });

        // 找出待解锁的钉子颜色
        const level = CarColorsGlobalInstance.instance.levels.children[0];
        const layer_arr = level.getComponent(LevelAction)!.get_all_layer();
        let topPins: Set<CarColors> = new Set();

        layer_arr.forEach(layer => {
            if (layer.layer_status == 1) {
                layer.node.children.forEach((element) => {
                    const pins = element.getComponentsInChildren(PinComponent)!;
                    pins.forEach((pin) => {
                        const pinCom = pin.getComponent(PinComponent)!;
                        if (!pinCom.isBlocked) {
                            topPins.add(pinCom.pin_color);
                        }
                    });
                });
            }
        });

        if (topPins.size === 0) {
            console.log("没有需要替换的颜色！");
            return;
        }

        // 按车类型分组
        const carTypes = new Map<CarTypes, CarCarColorsComponent[]>();
        cars.forEach(car => {
            const carType = car.carType;
            if (!carTypes.has(carType)) {
                carTypes.set(carType, []);
            }
            carTypes.get(carType)!.push(car);
        });

        let replaced = false;

        // **遍历 canOutCar，优先用 topPins 颜色替换**
        for (const car of canOutCar) {
            const sameTypeCars = carTypes.get(car.carType);
            if (!sameTypeCars || sameTypeCars.length < 2) continue; // 确保有同类型的车可以交换

            // 查找同类型的车，颜色在 topPins 里
            const swapCar = sameTypeCars.find(c => c !== car && topPins.has(c.carColor));
            if (swapCar) {
                // 交换颜色
                const tempColor = car.carColor;
                car.carColor = swapCar.carColor;
                swapCar.carColor = tempColor;

                topPins.delete(car.carColor); // 移除已经替换过的颜色
                replaced = true;
            }
        }

        if (!replaced) {
            console.log("没有合适的车可以进行颜色交换！");
        }
    }


    //找出所有可开出的车
    findCanOutCars() {
        const canOutCar: CarCarColorsComponent[] = [];
        const cars = find("Canvas/Scene/Levels").children[0].getComponentsInChildren(CarCarColorsComponent)!;
        cars.forEach(car => {
            const carComp = car.getComponent(CarCarColorsComponent);
            const collider = carComp.checkCollision();

            if (!collider) {
                canOutCar.push(car);
            }
        });

        return canOutCar;
    }

    checkCarBox() {
        if (this.carBoxMap.length === 0) return

        let mask = 1 << 1; //车分组
        let maxDistance = 300;
        let queryTrigger = true;
        for (let i = this.carBoxMap.length; i--;) {
            const carBoxCom = this.carBoxMap[i]
            if (carBoxCom.isAnimateOut) continue
            if (carBoxCom.num <= 0) {
                this.carBoxMap.splice(i, 1)
                continue
            }

            const car = carBoxCom.node;
            const objs = GameUtil.getWorldPositionAsVec2(car);
            const obje = GameUtil.calculateRayEnd(car, maxDistance);

            let results = PhysicsSystem2D.instance.raycast(objs, obje, ERaycast2DType.Closest);
            if (results.length == 0) {
                // console.log("没有障碍物>>>>>>>");
                carBoxCom.outCarTween();
            } else {
                // console.log("有障碍物:", results[0].collider.node.name);
            }
        }
    }

    protected lateUpdate(dt: number): void {
        //DOTO 检测车盒子
        this.checkCarBox()
    }
}


