/*
 * @Author: mojunshou 1637302775@qq.com
 * @Date: 2025-03-27 15:04:15
 * @LastEditors: mojunshou 1637302775@qq.com
 * @LastEditTime: 2025-03-27 15:21:52
 * @Description: 
 */
import { tween, Color, Sprite, UITransform, UIOpacity, v3 } from 'cc';
import { _decorator, EventTouch, Prefab, SpriteFrame, Vec3, Node } from 'cc';
import { GameComponent } from "db://oops-framework/module/common/GameComponent";

const { ccclass, property } = _decorator;

// 定义方块类型
export enum BlockColorType {
    RED = 0,
    BLUE = 1,
    GREEN = 2,
    YELLOW = 3,
    PURPLE = 4
}

// 定义方块形状模板（每种形状的格子偏移位置）
export const BLOCK_SHAPES = [
    // I形状
    [[0, 0], [0, 1], [0, 2]],
    // L形状
    [[0, 0], [0, 1], [1, 1]],
    // 反L形状
    [[0, 0], [0, 1], [-1, 1]],
    // T形状
    [[0, 0], [-1, 0], [1, 0], [0, 1]],
    // 方形
    [[0, 0], [1, 0], [0, 1], [1, 1]],
    // Z形状
    [[0, 0], [1, 0], [0, 1], [-1, 1]],
    // S形状
    [[0, 0], [-1, 0], [0, 1], [1, 1]]
];

/** 显示对象控制 */
@ccclass('BlockItemView')
export class BlockItemView extends GameComponent {
    @property([SpriteFrame])
    blockSprites: SpriteFrame[] = [];

    @property(Prefab)
    cellPrefab: Prefab = null!;

    // 方块当前类型
    private blockType: BlockColorType = BlockColorType.RED;
    // 方块形状索引
    private shapeIndex: number = 0;
    // 方块图标索引
    private iconIndex: number = 0;
    // 方块单元格尺寸
    private cellSize: number = 82;
    // 方块单元格节点数组
    private cells: Node[] = [];
    // 方块当前形状表示（格子坐标偏移）
    private currentShape: number[][] = [];
    // 是否可以旋转
    private isRotatable: boolean = false;
    // 是否可以拖拽
    private isDraggable: boolean = true;
    // 是否正在拖拽
    private isDragging: boolean = false;
    // 原始位置（拖拽失败时返回）
    private originalPosition: Vec3 = null!;


    protected start() {
        this.originalPosition = this.node.position.clone();
        this.initEventListeners();
    }

    /**
     * 初始化事件监听
    */
    initEventListeners() {
        this.node.on(Node.EventType.TOUCH_START, this.onTouchStart, this);
        this.node.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
        this.node.on(Node.EventType.TOUCH_END, this.onTouchEnd, this);
        this.node.on(Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this);
    }

    /**
     * 触摸开始事件
     */
    onTouchStart(event: EventTouch) {
        console.log("onTouchStart");
        if (!this.isDraggable) return;
        this.isDragging = true;
        this.originalPosition = this.node.position.clone();

        // 通知游戏组件方块被选中
        this.node.emit('block_selected', this);
    }

    /**
     * 触摸移动事件
     */
    onTouchMove(event: EventTouch) {
        if (!this.isDragging) return;

        const delta = event.getDelta();
        this.node.setPosition(
            this.node.position.x + delta.x,
            this.node.position.y + delta.y,
            this.node.position.z
        );

        // 通知游戏组件方块正在移动
        this.node.emit('block_moving', {
            block: this,
            position: this.node.position
        });
    }

    /**
     * 触摸结束事件
     */
    onTouchEnd(event: EventTouch) {
        if (!this.isDragging) return;

        this.isDragging = false;

        // 通知游戏组件方块放置
        this.node.emit('block_placed', {
            block: this,
            position: this.node.position
        });
    }


    /**
     * 返回原始位置
     */
    returnToOriginalPosition() {
        tween(this.node)
            .to(0.3, { position: this.originalPosition })
            .start();
    }

    /**
     * 移动到指定位置
     */
    moveTo(position: Vec3) {
        tween(this.node)
            .to(0.3, { position: position })
            .start();
    }

    /**
     * 高亮显示（可放置提示）
     */
    highlight(isValid: boolean) {
        const color = isValid ? new Color(150, 255, 150, 255) : new Color(255, 150, 150, 255);
        for (const cell of this.cells) {
            const sprite = cell.getComponent(Sprite);
            if (sprite) {
                sprite.color = color;
            }
        }
    }

    /**
     * 取消高亮
     */
    resetHighlight() {
        for (const cell of this.cells) {
            const sprite = cell.getComponent(Sprite);
            if (sprite) {
                sprite.color = Color.WHITE;
            }
        }
    }

    /**
     * 获取当前方块形状中所有单元格的世界坐标
     */
    getCellWorldPositions(): Vec3[] {
        const positions: Vec3[] = [];
        for (const cell of this.cells) {
            const transform = this.node.getComponent(UITransform);
            if (transform) {
                positions.push(transform.convertToWorldSpaceAR(cell.position));
            }
        }
        return positions;
    }

    /**
     * 获取当前方块类型
     */
    getBlockType(): BlockColorType {
        return this.blockType;
    }

    /**
     * 获取当前方块形状
     */
    getCurrentShape(): number[][] {
        return this.currentShape;
    }

    /**
     * 执行消除动画
     */
    playEliminateAnimation(callback?: Function) {
        // 播放消除动画
        const duration = 0.3;

        for (const cell of this.cells) {
            // 确保有 UIOpacity 组件
            let uiOpacity = cell.getComponent(UIOpacity);
            if (!uiOpacity) {
                uiOpacity = cell.addComponent(UIOpacity);
            }

            tween(cell)
                .to(duration, { scale: v3(0, 0, 1) })
                .start();

            tween(uiOpacity)
                .to(duration, { opacity: 0 })
                .start();
        }

        // 动画结束后执行回调
        this.scheduleOnce(() => {
            if (callback) callback();
        }, duration);
    }

    /**
     * 设置是否可拖拽
     */
    setDraggable(draggable: boolean) {
        this.isDraggable = draggable;
    }

    /**
     * 父节点点击事件
     */
    onParentNodeClicked(event: EventTouch) {
        if (!this.isDraggable) return;
        this.isDragging = true;
        this.originalPosition = this.node.position.clone();

        // 通知游戏组件方块被选中
        this.node.emit('block_selected', this);
    }


    /**
     * 设置this.cellPrefab下边icon 的样式
     * 
     */
    setBlockSpriteFrame(spriteFrame: SpriteFrame) {
        for (const cell of this.cells) {
            const sprite = cell.getChildByName("icon")?.getComponent(Sprite);
            if (sprite) {
                sprite.spriteFrame = spriteFrame;
            }
        }
    }
}