import { _decorator, Animation, animation, AudioClip, AudioSource, Collider2D, Color, Component, Contact2DType, director, ERigidBody2DType, game, Input, input, instantiate, Label, Node, Prefab, RigidBody2D, SceneAsset, sp, Sprite, Tween, tween, UITransform, Vec2, Vec3 } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('Controller2')
export class Controller extends Component {
    // 接方块
    @property(Node) finishBoard: Node = null;
    @property(sp.Skeleton) finishSkeleton: sp.Skeleton = null;
    @property(Node) SliderDistrict: Node = null;
    @property(Node) Slider: Node = null;
    @property(sp.Skeleton) clockSkeleton: sp.Skeleton = null;
    @property(Label) clockLabel: Label = null;
    @property(Node) greenLine: Node = null;
    @property(Node) Plate: Node = null;
    @property(Prefab) RubikCubePrefab: Prefab = null;
    @property(Node) RubikCubeParent: Node = null;
    @property(sp.Skeleton) machineSkeleton: sp.Skeleton = null;
    @property(Node) machine: Node = null;
    @property(Node) Ground: Node = null;
    @property(Node) star_1: Node = null;
    @property(Node) star_2: Node = null;
    @property(Node) Countdown: Node = null;
    @property(Node) x1: Node = null;
    @property(Animation) countdownAnimation: Animation = null;
    @property(Node) star: Node = null;
    @property(sp.Skeleton) satrSkeleton: sp.Skeleton = null;
    @property(AudioSource) audioSource: AudioSource = null;
    @property(AudioClip) countDownAudio: AudioClip = null;
    @property(AudioClip) settlementClip: AudioClip = null;
    @property(AudioSource) machineAudioSource: AudioSource = null;
    @property(AudioClip) machineClip: AudioClip = null;
    @property(AudioSource) rubikAudioSource: AudioSource = null;
    @property(AudioClip) rubikRightClip: AudioClip = null;
    @property(AudioClip) rubikWrongClip: AudioClip = null;
    @property(AudioSource) disappearAudioSource: AudioSource = null;
    @property(AudioClip) disappearClip: AudioClip = null;
    @property(AudioSource) starAppearAudioSource: AudioSource = null;
    @property(AudioClip) starAppearClip: AudioClip = null;

    // 核心状态变量
    isPressed: boolean = false;
    isDragging: boolean = false;
    sliderX: number = 0;
    isMoving: boolean = false;
    deadZone: number = 5; // 死区,滑杆在这个范围内不移动
    isRunning: boolean = false; // 是否正在运行游戏
    totalTime: number = 120; // 总时间
    currentTime: number = 0; // 剩余时间
    currentStage: "01" | "02" | "03" = "03"; // 当前关卡
    colllidercount: number = 0; // 碰撞计数器
    PlatePos: Vec3 = null;
    rubikCubeSkins: string[] = [
        "Hong", 
        "Huang", 
        "Lv", 
    ];
    speed: number = 100;
    starNum: number = 0;
    startGame: boolean = false;
    stackedCubes: Node[] = []; // 记录已堆叠的魔方

    start() {
        this.Animation();

    }

    Animation(){
        //先暂停游戏,等待动画播放完毕
        this.countdownAnimation.play();
        this.audioSource.clip = this.countDownAudio;
        this.audioSource.play();
        console.log("🎮 开始播放动画");
        // 使用事件类型常量
        this.countdownAnimation.once(Animation.EventType.FINISHED, () => {
            this.Countdown.active = false;
            this.onStart();
        }, this);
    }

    onStart(){
        // 初始化变量
        this.startGame = true;
        console.log("🎮 Controller组件初始化完毕");
        this.SliderMove();
        this.currentTime = this.totalTime;
        this.isRunning = true;
        this.schedule(this.generate, 4);
    }

    SliderMove(){
        //全局监听TOUCH_START,通过坐标判断是否在滑块上
        input.on(Input.EventType.TOUCH_START, this.onGlobalTouchStart, this);
        input.on(Input.EventType.TOUCH_MOVE, this.onGlobalTouchMove, this);
        input.on(Input.EventType.TOUCH_END, this.onGlobalTouchEnd, this);
    }

    private onGlobalTouchStart(event: any): void {

        if(this.isPressed){
            return; // 已经按下了,忽略
        }

        const touchPos = event.touch.getUILocation();//手指坐标,UI location相当于世界坐标
        const sliderPos = this.SliderDistrict.getWorldPosition();//滑杆节点世界坐标

        if(touchPos.x > sliderPos.x - 138 && touchPos.x < sliderPos.x + 138 && touchPos.y > sliderPos.y - 59 && touchPos.y < sliderPos.y + 59){
            //console.log("✅ 触摸在滑块上,可以开始拖拽");
            this.isPressed = true;
            this.isDragging = false;
        }
        else{
            console.log("❌ 触摸不在滑块上,忽略");
        }
    }

    private onGlobalTouchMove(event: any): void {
        // 只有先按下滑块才会响应移动
        if (!this.isPressed) {
            console.log("❌ 没有按下滑块,不能拖拽");
            return; // 没按下滑块,忽略移动
        }

        //console.log("⏳ 拖拽中");
        this.isDragging = true; // 标记为正在拖拽
        
        let touchPos = event.touch.getUILocation();//手指坐标,UI location相当于世界坐标
        let sliderPos = this.SliderDistrict.getWorldPosition();//滑杆节点世界坐标
        
        this.sliderX = touchPos.x - sliderPos.x;//横坐标差
  
        let sliderScope = 97;
        //限制滑杆在父节点的宽度的一半范围内
        if (this.sliderX < -sliderScope) {
            this.sliderX = -sliderScope;
        } else if (this.sliderX > sliderScope) {
            this.sliderX = sliderScope;
        }
        this.Slider.setPosition(this.sliderX, 0, 0);
    }

    private onGlobalTouchEnd(event: any): void {
        // 只有在拖拽状态才需要处理松开事件
        if (!this.isPressed) {
            return; // 没有在拖拽,忽略松开
        }

        //console.log("🔚 松开鼠标,拖拽结束");
        this.Slider.setPosition(0, 0, 0);
        this.sliderX = 0;
        // 重置所有状态,下次必须重新在滑块上按下才能拖拽
        this.isPressed = false;
        this.isDragging = false;
        this.isMoving = false;
        // this PlateSkeleton.setAnimation(0, "idle_01", true);

    }

    private clock(deltaTime: number){
        // ✅ 安全的Label更新
        if (this.clockLabel) {
            this.clockLabel.string = `${this.currentTime.toFixed(0)}s`;
            //console.log(this.clockLabel.string);
        }

        // ✅ 安全的greenLine更新
        const line = this.greenLine.getComponent(UITransform);
        const color = this.greenLine.getComponent(Sprite);
        if (line) {
            line.setContentSize(86 * this.currentTime / this.totalTime, 12);
        }

        let stage: '01' | '02' | '03';
        if(!this.isRunning){
            //console.log("游戏结束");
            return;
        } 
        this.currentTime -= deltaTime;
        // console.log(this.currentTime);
        
        if(this.currentTime >= this.totalTime / 2 && this.currentTime <= this.totalTime){
            stage = '01';
            //color.color = Color.GREEN;标准绿
            color.color = new Color(0, 190, 0, 255);
            //this.clockSkeleton.setAnimation(0, "02_YunSu", true);
        }
        else if(this.currentTime > 0.01667 && this.currentTime < this.totalTime / 2){
            stage = '02';
            color.color = new Color(255, 0, 0, 255);
            //this.clockSkeleton.setAnimation(0, "03_JiaSu", true);
        }
        else{
            stage = '03';
            this.isRunning = false;
            //console.log("游戏结束");
            this.gameOver();
        }
        
        // 只有当目标状态与当前状态不同时才切换动画
        if (stage !== this.currentStage) {
            this.switchTimeAnimation(stage);
        }
    }

    private switchTimeAnimation(stage: '01' | '02' | '03'): void {
        this.currentStage = stage;
        
        switch (stage) {
            case '01':
                console.log("🕒 闹钟:01");
                this.clockSkeleton.setAnimation(0, "02_YunSu", true);
                break;
                
            case '02':
                console.log("🕒 闹钟:02");
                this.clockSkeleton.setAnimation(0, "03_JiaSu", true);
                break;
                
            case '03':
                console.log("🕒 闹钟:03");
                this.clockSkeleton.setAnimation(0, "01_DaiJi", true);
                break;
        }
    }

        private PlateMove(deltaTime: number){
        // 计算当前移动方向和速度
        //const moveDirection = this.getCurrentMoveDirection();
        const moveSpeed = this.getCurrentMoveSpeed();
        
        // 移动人物
        if (this.sliderX > this.deadZone){
            const currentPos = this.Plate.getPosition();
            this.Plate.setPosition(currentPos.x + moveSpeed * deltaTime, currentPos.y, currentPos.z);
        }
            
        else if (this.sliderX < -this.deadZone){
            const currentPos = this.Plate.getPosition();
            this.Plate.setPosition(currentPos.x - moveSpeed * deltaTime, currentPos.y, currentPos.z);
        }
            
        else{

            return;
        }
        // this.updateAnimation();

        const PlateX = this.Plate.getPosition().x;
        console.log(PlateX);
        if(PlateX < -650){
            this.Plate.setPosition(-650, -269, 0);
        }
        else if(PlateX > 650){
            this.Plate.setPosition(650, -269, 0);
        }
    }

    private getCurrentMoveSpeed(): number {
        // 应用死区
        if (Math.abs(this.sliderX) < this.deadZone) {
            return 0; // 在死区内,不移动
        }

        // 太快了const speed: number = Math.pow(this.sliderX, 2); // 速度随滑杆位置变化而变化
        const speed: number = 5 * Math.abs(this.sliderX); // 速度随滑杆位置变化而变化
        return speed;
    }

    generate() {
        this.machineAudioSource.clip = this.machineClip;
        this.machineAudioSource.play();

        this.machineSkeleton.setAnimation(0, "fashe_01", false);
        let RubikCube = instantiate(this.RubikCubePrefab);
        // 直接添加到魔方容器
        RubikCube.setParent(this.RubikCubeParent);
        
        // 记录生成时的世界坐标
        const machineWorldPos = this.RubikCubeParent.getWorldPosition();
        const initialX = machineWorldPos.x;  // 记录初始 x 坐标
        const initialZ = machineWorldPos.z;  // 记录初始 z 坐标
        const initialY = machineWorldPos.y;  // 记录初始 y 坐标
        
        // 设置初始位置
        RubikCube.setWorldPosition(initialX, initialY, initialZ);
  
        // 🎨 设置随机皮肤
        const skeleton = RubikCube.getComponent(sp.Skeleton);
        const randomSkin = this.getRandomSkin();
        skeleton.setSkin(randomSkin);
        
        const RubikCubeCollider = RubikCube.getComponent(Collider2D);
        RubikCubeCollider.on(Contact2DType.BEGIN_CONTACT, this.beginContact, this);
        
        // 开始垂直下落动画
        tween(RubikCube)
            .to(5, {
                // 使用回调函数持续更新世界坐标,保持 x 和 z 不变,只改变 y
                worldPosition: new Vec3(initialX, initialY - 1000, initialZ)
            })
            .call(() => {
                // 下落完成后清理
                    RubikCubeCollider.off(Contact2DType.BEGIN_CONTACT, this.beginContact, this);
            })
            .start();
    }

    // 获取随机皮肤
    private getRandomSkin(): string {
        const randomIndex = Math.floor(Math.random() * this.rubikCubeSkins.length);
        return this.rubikCubeSkins[randomIndex];
    }

    private beginContact(selfCollider: Collider2D, otherCollider: Collider2D, contact: any) {
        selfCollider.off(Contact2DType.BEGIN_CONTACT, this.beginContact, this);
        const rubicube = selfCollider.node; // 获取碰撞的魔方节点

        // 停止该节点的所有 tween 动画
        Tween.stopAllByTarget(rubicube);

        if (otherCollider.tag === 1){
            console.log("🎉 碰撞成功"); 

            this.rubikAudioSource.clip = this.rubikRightClip;
            this.rubikAudioSource.play();

            // 使用 scheduleOnce 延迟一帧执行,确保物理系统已经停止
            this.scheduleOnce(() => {
                // 设置父节点
                rubicube.setParent(this.Plate);
                // 设置位置
                rubicube.setPosition(0, 72 + 56 * (this.colllidercount + 1), 0);
                this.colllidercount++;

                 // 添加到数组中
                this.stackedCubes.push(rubicube);

                // 重新启用刚体和碰撞器
                const rigidBody = rubicube.getComponent(RigidBody2D);
                rigidBody.enabled = true;
                rigidBody.type = ERigidBody2DType.Static; // 设置为静态刚体
                const collider = rubicube.getComponent(Collider2D);
                collider.enabled = true;
                collider.tag = 1; // 确保标签正确

                if(this.colllidercount == 5){
                    this.colllidercount = 0;
                    this.starNum++;
                    // 执行动画
                    this.eliminateFiveCubes();
                    
                    // 动画完毕亮出星星
                    this.StarShow();
                }

                if(this.colllidercount){
                    this.x1.active = true;
                    this.x1.setPosition(0, 72 + 56 * (this.colllidercount + 1) + 50, 0);
                }
                else{
                    this.x1.active = false;
                }
            }, 0);
        }
        else{
            this.rubikAudioSource.clip = this.rubikWrongClip;
            this.rubikAudioSource.play();

            const rigidBody = rubicube.getComponent(RigidBody2D);
            rigidBody.enabled = false;
            const collider = rubicube.getComponent(Collider2D);
            collider.enabled = false;
            // 先记录当前的世界坐标
            const currentWorldPos = rubicube.getWorldPosition();
            
            // 设置父节点
            rubicube.setParent(this.Ground);
            
            // 恢复到原来的世界坐标位置,避免因为父节点改变导致位置偏移
            rubicube.setWorldPosition(currentWorldPos);
            // 获取 Spine 组件并播放动画
            const spine = rubicube.getComponent(sp.Skeleton);
            spine.setAnimation(0, "xiaoshi_01", false);
        }

    }

    machineMove(deltaTime: number){
        const currentPos = this.machine.getPosition();
        this.machine.setPosition(currentPos.x + this.speed * deltaTime, currentPos.y, currentPos.z);
        if(this.machine.getPosition().x > 698){
            this.speed = -this.speed;
        }
        else if(this.machine.getPosition().x < -698){
            this.speed = -this.speed;
        }
        else
            return;
    }

    StarShow(){
        // 显示星星
        if(this.starNum == 1){
            // 显示一颗星星
            this.starAnimation(this.starNum);
        }
        else if(this.starNum == 2){
            this.starAnimation(this.starNum);
            // 显示两颗星星
            // 延迟 1 秒执行
            this.scheduleOnce(() => {
                console.log("1秒后执行");
                this.gameOver();
            }, 1);
        }
        else {
            return;
        }
    }

    // 消除5个魔方的方法
    private eliminateFiveCubes() {
        console.log("消除5个魔方!");
        this.disappearAudioSource.clip = this.disappearClip;
        this.disappearAudioSource.play();
        
        // 取出最底下的5个魔方
        const cubesToEliminate = this.stackedCubes.splice(0, 5);
        
        // 反转数组,让第5个在前面
        cubesToEliminate.reverse();

        // 播放消失动画并销毁
        cubesToEliminate.forEach((cube, index) => {
            // 可以添加一些延迟让消失效果更好看
            this.scheduleOnce(() => {
                cube.destroy();
            }, 0); // 每个魔方延迟0.1秒消失
        });
        
    }

    starAnimation(num: number){
        this.starAppearAudioSource.clip = this.starAppearClip;
        this.starAppearAudioSource.play();

        const currentPos = this.Plate.getWorldPosition();
        this.star.setWorldPosition(currentPos.x, currentPos.y + 200, currentPos.z);
        this.star.active = true;
        this.satrSkeleton.setAnimation(0, "01_ChuXian", false);
        this.satrSkeleton.setCompleteListener((trackEntry) => {
            // 修改这里:判断正确的动画名称
            if (trackEntry.animation.name === "01_ChuXian") {
                console.log("星星出现动画播放完成");
                this.starMove(num);
            }
        });
    }

    starMove(num: number){
        this.satrSkeleton.setAnimation(0, "02_XunHuan", false);
        const star1Pos = this.star_1.getWorldPosition();
        const star2Pos = this.star_2.getWorldPosition();

        if(num == 1){
            tween(this.star)
                .to(0.3, {
                    worldPosition: star1Pos,
                    scale: new Vec3(0.35, 0.35, 1)
                })
                .call(() => {
                    this.star.active = false;
                    this.star_1.active = true;
                    this.star.setScale(1, 1, 1);
                })
                .start();
        }
        else if(num == 2){
            tween(this.star)
                .to(0.3, {
                    worldPosition: star2Pos,
                    scale: new Vec3(0.35, 0.35, 1)
                })
                .call(() => {
                    this.star.active = false;
                    this.star_2.active = true;
                    this.star_1.setScale(1, 1, 1);
                })
                .start();
        }
        else{
            return;
        }
    }

    gameOver() {
        this.audioSource.clip = this.settlementClip;
        this.audioSource.play();
        this.finishBoard.active = true;
        this.finishSkeleton.setAnimation(0, "Chu_DanCiKa", false);
        this.stopGame();
    }

    stopGame() {
        console.log("停止游戏");
        
        // 停止游戏逻辑
        this.isRunning = false;
        this.startGame = false;
        
        // 停止所有定时器
        this.unschedule(this.generate);
        
        // 暂停所有音频(保持音频源可用)
        if (this.audioSource && this.audioSource.playing) {
            this.audioSource.pause();
        }
        if (this.machineAudioSource && this.machineAudioSource.playing) {
            this.machineAudioSource.pause();
        }
        if (this.rubikAudioSource && this.rubikAudioSource.playing) {
            this.rubikAudioSource.pause();
        }
        if (this.disappearAudioSource && this.disappearAudioSource.playing) {
            this.disappearAudioSource.pause();
        }
        if (this.starAppearAudioSource && this.starAppearAudioSource.playing) {
            this.starAppearAudioSource.pause();
        }
        
        // 清理物理组件和动画
        this.cleanupGameObjects();
        
        // 停止输入监听
        this.stopInputListening();
        
        // 重置状态
        this.resetGameState();
    }
    
    private cleanupGameObjects() {
        // 停止所有魔方的动画和物理
        const children = this.RubikCubeParent.children.slice();
        children.forEach(child => {
            Tween.stopAllByTarget(child);
            
            const rigidBody = child.getComponent(RigidBody2D);
            const collider = child.getComponent(Collider2D);
            
            if (collider) {
                collider.off(Contact2DType.BEGIN_CONTACT, this.beginContact, this);
                collider.enabled = false;
            }
            if (rigidBody) {
                rigidBody.enabled = false;
            }
        });
        
        // 清理盘子上的魔方
        this.stackedCubes.forEach(cube => {
            Tween.stopAllByTarget(cube);
            const rigidBody = cube.getComponent(RigidBody2D);
            const collider = cube.getComponent(Collider2D);
            
            if (rigidBody) rigidBody.enabled = false;
            if (collider) collider.enabled = false;
        });
        
        // 停止机器和星星的动画
        Tween.stopAllByTarget(this.machine);
        Tween.stopAllByTarget(this.star);
        
        // 停止倒计时动画
        if (this.countdownAnimation && this.countdownAnimation.isValid) {
            this.countdownAnimation.stop();
        }
    }
    
    private stopInputListening() {
        input.off(Input.EventType.TOUCH_START, this.onGlobalTouchStart, this);
        input.off(Input.EventType.TOUCH_MOVE, this.onGlobalTouchMove, this);
        input.off(Input.EventType.TOUCH_END, this.onGlobalTouchEnd, this);
    }
    
    private resetGameState() {
        this.isPressed = false;
        this.isDragging = false;
        this.isMoving = false;
        this.sliderX = 0;
        this.colllidercount = 0;
        this.starNum = 0;
        this.currentStage = "03";
        this.stackedCubes = [];
        
        // 重置滑杆位置
        this.Slider.setPosition(0, 0, 0);
    }

    update(deltaTime: number) {
        if(this.startGame){
            this.clock(deltaTime);
            this.PlateMove(deltaTime);
            this.machineMove(deltaTime);
        } 
    }
}

是超级管理员哦