import {
    _decorator,
    Camera,
    director, instantiate,
    Label,
    math,
    Node,
    PhysicsSystem2D,
    Prefab,
    UITransform,
} from "cc";
import { Joystick } from "./Components/Joystick";
import { FastBtn } from "./Components/FastBtn";
import { FoodManger } from "./Manager/FoodManger";
import { Global } from "./Global";
import { Events, GameState } from "./Common/Enums";
import { showToast } from "../../../Module/UIFast";
import Scene from "../../../Module/Scene";
import { executePreFrame, getItemGenerator } from "../../Utils/ExecutePreFrame";
import { Player } from "./Player";
import { AISnake } from "./AISnake";
import { Quadtree } from "./QuadTree/QuadTree";
import { QuadTreeNode } from "./QuadTree/QuadTreeNode";
import { aiPool, clearAllPool, foodPool } from "./Manager/CommonPool";

const { ccclass, property } = _decorator;


@ccclass("MainGame")
export class MainGame extends Scene {

    static bundle: string = "MainGame";
    static skin: string = "MainGame";

    @property(Prefab)
    private animalPrefab: Prefab = null;

    @property({
        displayName: "最多食物",
        tooltip: "地图上随机产生食物，如果超过当前值不在产生。"
    })
    maxFood: number = 300;

    @property({
        displayName: "NPC数量",
        tooltip: "当前游戏最大NPC角色"
    })
    private maxAnimal: number = 20;

    @property({ type: Joystick, displayName: "摇杆" }) joystick: Joystick = null;

    @property({
        type: FastBtn,
        displayName: "快进按钮"
    })
    private fastBtn: FastBtn = null;

    @property(UITransform)
    private uiBg: UITransform = null;

    @property(Player)
    player: Player = null;

    @property(FoodManger)
    fondManger: FoodManger = null;

    @property(Node)
    animalNode: Node = null;

    @property(Camera)
    camera: Camera = null;

    @property({ type: Label, group: "UI" }) killTxt: Label = null;

    @property({ type: Label, group: "UI" }) lengthTxt: Label = null;

    private _killNum = 0;
    set killNum(n: number) {
        this._killNum = n;
        this.killTxt.string = `${this._killNum}名`;
    }

    get killNum() {
        return this._killNum;
    }


    private state: GameState = GameState.READY;
    private rebirthSum: number = 0;

    private static _ins: MainGame = null;
    static get ins(): MainGame {
        return MainGame._ins;
    }

    // quadTree: Quadtree = null;
    // private _lastQuadTreeUpdate: number = 0;
    // private readonly QUAD_TREE_UPDATE_INTERVAL = 1 / 60; // 可以根据需求调整更新频率

    async onLoad() {
        MainGame._ins = this;

        // this.quadTree = new Quadtree({
        //     x: 0, y: 0,
        //     width: Global.MAP_WIDTH,
        //     height: Global.MAP_HEIGHT,
        // }, 25, 6);

        PhysicsSystem2D.instance.enable = true;
        // PhysicsSystem2D.instance.gravity = math.Vec2.ZERO;
        // PhysicsSystem2D.instance.debugDrawFlags = EPhysics2DDrawFlags.Aabb |
        //     EPhysics2DDrawFlags.Pair |
        //     EPhysics2DDrawFlags.CenterOfMass |
        //     EPhysics2DDrawFlags.Joint |
        //     EPhysics2DDrawFlags.Shape;

        Global.MAP_WIDTH = this.uiBg.contentSize.x;
        Global.MAP_HEIGHT = this.uiBg.contentSize.y;

        // 初始化墙壁
        const wallTop = this.uiBg.node.getChildByName("WALL_TOP");
        wallTop.setPosition(0, Global.MAP_HEIGHT / 2);
        wallTop.getComponent(UITransform).width = Global.MAP_WIDTH;

        const wallBottom = this.uiBg.node.getChildByName("WALL_BOTTOM");
        wallBottom.setPosition(0, -Global.MAP_HEIGHT / 2);
        wallBottom.getComponent(UITransform).width = Global.MAP_WIDTH;

        const wallLeft = this.uiBg.node.getChildByName("WALL_LEFT");
        wallLeft.setPosition(-Global.MAP_WIDTH / 2, 0);
        wallLeft.getComponent(UITransform).height = Global.MAP_HEIGHT;

        const wallRight = this.uiBg.node.getChildByName("WALL_RIGHT");
        wallRight.setPosition(Global.MAP_WIDTH / 2, 0);
        wallRight.getComponent(UITransform).height = Global.MAP_HEIGHT;

        this.player.init({
            // initEnergy: 10000
        });

        // 初始化食物和NPC
        this.fondManger.init(this.maxFood);
        // this.fondManger.init(2000);
        this.initAnimal(this.maxAnimal);
        // this.initAnimal(1);

        // 设置游戏状态
        this.setGameState(GameState.PLAY);

        // 注册事件
        director.on(Events.showGOver, this.showGOver, this);
        director.on(Events.setGameState, this.setGameState, this);
    }

    onDestroy() {
        MainGame._ins = null;
        clearAllPool();
    }

    update(dt: number) {
        if (this.state == GameState.READY) return;

        this.player.onUpdate(dt);

        // 更新相机位置
        this.camera.node.setPosition(this.player.head.getPosition());

        // 更新NPC移动
        this.animalNode.children.forEach(child => {
            child.getComponent(AISnake)?.onUpdate(dt);
        });

        // 更新四叉树
        // this._lastQuadTreeUpdate += dt;
        // if (this._lastQuadTreeUpdate >= this.QUAD_TREE_UPDATE_INTERVAL) {
        //     this.updateQuadTree();
        //     this._lastQuadTreeUpdate = 0;
        // }

        // // 处理碰撞检测
        // this.handleCollisions();
    }

    // private updateQuadTree() {
    //     // 清空四叉树
    //     this.quadTree.clear();

    //     // 重新插入所有节点
    //     for (const node of QuadTreeNode.caches) {
    //         if (node.node.active && node.enabled) {
    //             this.quadTree.insert(node);
    //         }
    //     }
    //     for (const node of QuadTreeNode.staticCaches) {
    //         if (node.node.active && node.enabled) {
    //             this.quadTree.insert(node);
    //         }
    //     }
    // }

    // private handleCollisions() {
    //     // 使用四叉树进行碰撞检测
    //     for (const node of QuadTreeNode.caches) {

    //         if (!node.node.active) continue;
    //         const potentialCollisions = this.quadTree.retrieve(node);
    //         // 检查具体的碰撞
    //         for (const other of potentialCollisions) {
    //             if (node.intersects(other)) {
    //                 // 处理碰撞
    //                 node.emit(QuadTreeNode.EventType.COLLISION, node, other);
    //             }
    //         }
    //     }
    // }

    onPause() {
        this.setGameState(GameState.PAUSE);
        console.log("pause");
    }

    setGameState(state: GameState) {
        this.state = Number(state);
        switch (this.state) {
            case GameState.READY:
                break;
            case GameState.PLAY:
                director.resume();
                break;
            case GameState.PAUSE:
                director.pause();
                break;
            case GameState.OVER:
                this.rebirthSum++;
                if (this.rebirthSum > 2) return this.showGOver();
                showToast("你已死亡！");
                break;
            case GameState.WIN:
                director.pause();
                console.log("win", this.player.getSnakeLen());
                break;
            case GameState.QUIT:
                director.resume();
                director.loadScene("GameMain");
                break;
            default:
                console.log("err");
        }
    }

    showGOver() {
        console.log("showGOver", this.player.getSnakeLen());
    }

    initItem = (index: number) => {
        const node = aiPool.get() || instantiate(this.animalPrefab);
        const x = math.randomRangeInt(-(Global.MAP_WIDTH / 2 - 50), Global.MAP_WIDTH / 2 - 50);
        const y = math.randomRangeInt(-(Global.MAP_HEIGHT / 2 - 50), Global.MAP_HEIGHT / 2 - 50);

        node.getComponent(AISnake)?.init({
            x, y,
            // x: 50,
            // y: 50,
            // bodyCount: 100,
            angle: math.randomRangeInt(0, 360),
            skinName: "default",
        });

        this.animalNode.addChild(node);
    };

    async initAnimal(count: number) {
        await executePreFrame(getItemGenerator(count, this.initItem), 1, this);
    }

}