import { _decorator, Component, instantiate, Node, Prefab, Sprite, tween, UIOpacity, v3, Vec3, view } from 'cc';
import { BlockController } from './Block/BlockController';
import { BlockBaData, BlockConfig, BlocksAll, BlockState, BlockType, BlockWeights, ReConfig } from './Block/BlockData';
import GlobalData from './GlobalData';
import { LocalStorageMgr } from './LocalStorageMgr';
import { MainGameLogic } from './MainGameLogic';
import { TouchMgr } from './TouchMgr';
import { AudioManager } from '../AudioManager';
import { Url } from '../Url';
import ResSprite from '../ResSprite';
const { ccclass, property } = _decorator;

@ccclass('GridBlockMgr')
export class GridBlockMgr extends Component {

    /** 单例模式 */
    private static _ins: GridBlockMgr;
    constructor() {
        super();
        GridBlockMgr._ins = this;
    }
    public static get ins(): GridBlockMgr {
        if (!GridBlockMgr._ins) {
            GridBlockMgr._ins = new GridBlockMgr();
        }
        return GridBlockMgr._ins;
    }

    @property(Prefab)
    block: Prefab = null;
    @property(Node)
    gridcontainer: Node = null;
    @property(Node)
    selects: Node[] = [];
    @property(Node)
    SelectionContainer: Node = null;

    private boardSize: number = 8;
    private cellSize: number = 122.5;


    block_ba_data: BlockBaData[][];
    temp_block_ba_data: BlockBaData[][];
    temp_block_ba_data1: BlockBaData[][];
    selection_block_type: BlockType[];
    selection_block_config: BlockConfig[]

    protected onLoad(): void {
        this.temp_block_ba_data = this.initializeBlockData();
        this.temp_block_ba_data1 = this.initializeBlockData();
    }

    async start() {

    }
    protected update(dt: number): void {

    }
    // 初始化 temp_block_ba_data 的方法
    initializeBlockData(): BlockBaData[][] {
        const size = 8; // 根据实际情况设置
        const data: BlockBaData[][] = [];
        for (let i = 0; i < size; i++) {
            const row: BlockBaData[] = [];
            for (let j = 0; j < size; j++) {
                row.push({
                    block_state: BlockState.HIDE,
                    block_ba_node: null, // 根据实际情况初始化
                    index_i: i,
                    index_j: j,
                    block_sprite: null, // 根据实际情况初始化
                    block_color: Url.BLOCK.ORANGE
                });
            }
            data.push(row);
        }
        return data;
    }
    // 检测消除
    checkAndUpdateBlocks(): Vec3 | null {
        const size = 8;
        const rowsToClear = new Set<number>();
        const colsToClear = new Set<number>();
        let anyCleared = false;

        let eliminNum = 0;   // 消除的总块数
        let totalRow = 0;    // 累积的行索引总和
        let totalCol = 0;    // 累积的列索引总和
        let clearedRowCount = 0; // 消除的行数
        let clearedColCount = 0; // 消除的列数

        // 检查每一行
        for (let i = 0; i < size; i++) {
            let rowAllOnes = true;
            for (let j = 0; j < size; j++) {
                if (this.block_ba_data[i][j].block_state !== BlockState.SHOW) {
                    rowAllOnes = false;
                    break;
                }
            }
            if (rowAllOnes) {
                rowsToClear.add(i);
                anyCleared = true;
                clearedRowCount++;
            }
        }

        // 检查每一列
        for (let j = 0; j < size; j++) {
            let colAllOnes = true;
            for (let i = 0; i < size; i++) {
                if (this.block_ba_data[i][j].block_state !== BlockState.SHOW) {
                    colAllOnes = false;
                    break;
                }
            }
            if (colAllOnes) {
                colsToClear.add(j);
                anyCleared = true;
                clearedColCount++;
            }
        }

        let centerX = null;
        let centerY = null;
        let centerPosition: Vec3 = null;

        // 统一处理需要消除的行和列
        rowsToClear.forEach((i) => {
            for (let j = 0; j < size; j++) {
                const node = this.block_ba_data[i][j].block_ba_node;
                node.getComponent(UIOpacity).opacity = 0;
                this.block_ba_data[i][j].block_state = BlockState.HIDE;
                MainGameLogic.ins.createOneBlockEfEffect(node, this.block_ba_data[i][j].block_color);
                eliminNum++;
                totalRow += i;
                totalCol += j;
            }
        });

        colsToClear.forEach((j) => {
            for (let i = 0; i < size; i++) {
                const node = this.block_ba_data[i][j].block_ba_node;
                node.getComponent(UIOpacity).opacity = 0;
                this.block_ba_data[i][j].block_state = BlockState.HIDE;
                MainGameLogic.ins.createOneBlockEfEffect(node, this.block_ba_data[i][j].block_color);
                eliminNum++;
                totalRow += i;
                totalCol += j;
            }
        });

        if (anyCleared) {
            AudioManager.ins.playOneShot(Url.AUDIO.SFX10, 1);
            // 计算最中间块的索引位置
            centerX = Math.floor(totalRow / eliminNum);
            centerY = Math.floor(totalCol / eliminNum);

            // 获取最中间块的实际位置
            const centerNode: Node = this.block_ba_data[centerX][centerY].block_ba_node;
            centerPosition = centerNode.getPosition(); // 获取世界坐标

            // 将消除的行数和列数相加，传递给 detectGuideAndElimiTimes
            // console.log(clearedRowCount, clearedColCount);

            const totalClearedLines = clearedRowCount + clearedColCount;
            MainGameLogic.ins.detectGuideAndElimiTimes(totalClearedLines);
            // MainGameLogic.ins.getElimitateCash();

            // console.log('消除格子数', eliminNum);
            // console.log('最中间块坐标', centerPosition);

            let baseScore = mtec.number.random(GlobalData.addScoreFloor, GlobalData.addScoreUp);

            MainGameLogic.ins.createConsecutiveEffect(centerPosition, totalClearedLines);
            this.scheduleOnce(() => {
                MainGameLogic.ins.createEleAddScoreEff(centerPosition, baseScore * eliminNum);
            }, 1)

        }

        this.scheduleOnce(() => {
            this.saveCurrentBoardState();

        }, 1)

        // 返回最中间块的世界坐标
        return centerPosition;
    }
    /** 保存当前地图数据的方法 */
    saveCurrentBoardState(): void {
        const size = 8;
        const currentBoardData = [];

        for (let i = 0; i < size; i++) {
            const row = [];
            for (let j = 0; j < size; j++) {
                row.push(this.block_ba_data[i][j].block_state === BlockState.SHOW ? 1 : 0);
            }
            currentBoardData.push(row);
        }

        LocalStorageMgr.setItem(LocalStorageMgr.lastGameBoardData_key, currentBoardData)

    }
    //  检测棋盘相连区域，并将最多块数的区域消除-----道具使用
    chechBlockArea() {
        //  根据this.block_ba_data棋盘数据，检测格子相互之间相连的区域
        //  计算每个区域相邻的格子有多少，得出格子最最多的区域，将这个区域的格子全部隐藏（消除）
        // 定义方向数组，用于移动上下左右四个方向
        const directions = [
            { x: 0, y: 1 },  // 上
            { x: 1, y: 0 },  // 右
            { x: 0, y: -1 }, // 下
            { x: -1, y: 0 }  // 左
        ];
        // 用于记录已经访问过的格子
        const visited = new Array(this.boardSize).fill(false).map(() => new Array(this.boardSize).fill(false));
        let maxArea = 0;
        let maxAreaBlocks: BlockBaData[] = [];

        // 深度优先搜索，检测相连区域
        const dfs = (i: number, j: number, currentBlocks: BlockBaData[]) => {
            visited[i][j] = true;
            currentBlocks.push(this.block_ba_data[i][j]);

            for (const direction of directions) {
                const newRow = i + direction.x;
                const newCol = j + direction.y;

                if (
                    newRow >= 0 && newRow < this.boardSize &&
                    newCol >= 0 && newCol < this.boardSize &&
                    !visited[newRow][newCol] &&
                    this.block_ba_data[newRow][newCol].block_state === BlockState.SHOW
                ) {
                    dfs(newRow, newCol, currentBlocks);
                }
            }
        };

        // 遍历棋盘，找到所有区域
        for (let i = 0; i < this.boardSize; i++) {
            for (let j = 0; j < this.boardSize; j++) {
                if (
                    !visited[i][j] &&
                    this.block_ba_data[i][j].block_state === BlockState.SHOW
                ) {
                    const currentBlocks: BlockBaData[] = [];
                    dfs(i, j, currentBlocks);

                    if (currentBlocks.length > maxArea) {
                        maxArea = currentBlocks.length;
                        maxAreaBlocks = currentBlocks;
                    }
                }
            }
        }

        // 消除最大区域的格子
        for (const block of maxAreaBlocks) {
            block.block_ba_node.getComponent(UIOpacity).opacity = 0;
            block.block_state = BlockState.HIDE;
        }

        // console.log('最大区域的格子数：', maxArea);
        // console.log('消除的格子：', maxAreaBlocks);
    }
    // 检查并消除2x2区域，并返回消除区域的中心坐标
    chechAndEliminateRandomArea(): boolean {
        const regions: { blocks: BlockBaData[], row: number, col: number }[] = [];

        // 遍历棋盘，以2x2区域为单位进行划分
        for (let i = 0; i < this.boardSize; i += 4) {
            for (let j = 0; j < this.boardSize; j += 4) {
                const currentRegion: BlockBaData[] = [];

                // 遍历当前2x2区域的格子
                for (let x = i; x < i + 4; x++) {
                    for (let y = j; y < j + 4; y++) {
                        if (this.block_ba_data[x][y].block_state === BlockState.SHOW) {
                            currentRegion.push(this.block_ba_data[x][y]);
                        }
                    }
                }

                // 如果该区域内有显示状态的格子，记录下来
                if (currentRegion.length > 0) {
                    regions.push({ blocks: currentRegion, row: i, col: j });
                }
            }
        }

        // 如果没有找到任何显示状态的区域，直接返回 null
        if (regions.length === 0) {
            // console.log('没有区域内有格子处于显示状态');
            MainGameLogic.ins.propInUse = false;
            MainGameLogic.ins.createOneTipTpast('game_tip_noblock')
            return false;
        }

        // 随机选择一个区域
        const randomIndex = Math.floor(Math.random() * regions.length);
        const selectedRegion = regions[randomIndex];

        // 计算四个格子中心位置的平均值
        let centerX = 0, centerY = 0, centerZ = 0;
        for (const block of selectedRegion.blocks) {
            const position = block.block_ba_node.getPosition();
            centerX += position.x;
            centerY += position.y;
            centerZ += position.z;
        }
        const centerPosition = new Vec3(centerX / selectedRegion.blocks.length, centerY / selectedRegion.blocks.length, centerZ / selectedRegion.blocks.length);

        let fun = () => {
            // 消除选中区域的格子
            for (const block of selectedRegion.blocks) {
                block.block_ba_node.getComponent(UIOpacity).opacity = 0;
                block.block_state = BlockState.HIDE;
                MainGameLogic.ins.createOneBlockEfEffect(block.block_ba_node, block.block_color);
            }
            MainGameLogic.ins.propInUse = false;
            // console.log(`消除了区域 [${selectedRegion.row}, ${selectedRegion.col}] 内的格子`);
        }
        this.saveCurrentBoardState();
        // MainGameLogic.ins.usePropHummerEffect(centerPosition, fun)

        return true;
    }
    // 根据数据设置棋盘格子
    async generateBoard(_boardData) {
        // 初始化block_ba_data二维数组
        this.block_ba_data = [];

        for (let i = 0; i < this.boardSize; i++) {
            this.block_ba_data[i] = [];
            for (let j = 0; j < this.boardSize; j++) {
                let state = _boardData[i][j];
                let name = (i + 1) + '_' + (j + 1);
                let _block_ba = this.gridcontainer.getChildByName(name);
                _block_ba.getComponent(UIOpacity).opacity = state == 1 ? 255 : 0;
                _block_ba.getComponent(ResSprite).setSpriteFrame(Url.BLOCK.ORANGE + '/spriteFrame');
                // 创建BlockBaData对象并赋值
                const blockBaData: BlockBaData = {
                    index_i: i,
                    index_j: j,
                    block_ba_node: _block_ba,
                    block_state: state == 1 ? BlockState.SHOW : BlockState.HIDE,
                    block_sprite: _block_ba.getComponent(ResSprite),
                    block_color: Url.BLOCK.ORANGE
                };
                // 将blockBaData对象保存到block_ba_data二维数组中
                this.block_ba_data[i][j] = blockBaData;
            }
        }
    }
    // 根据数据设置棋盘格子_带效果
    async generateBoard_effect(_boardData) {
        // 播放音效
        AudioManager.ins.playOneShot(Url.AUDIO.SFX12, 1);

        // 初始化block_ba_data二维数组，快速完成初始化，没有延迟
        this.block_ba_data = [];
        for (let i = 0; i < this.boardSize; i++) {
            this.block_ba_data[i] = [];
            for (let j = 0; j < this.boardSize; j++) {
                let name = (i + 1) + '_' + (j + 1);
                let _block_ba = this.gridcontainer.getChildByName(name);

                // 创建BlockBaData对象并初始化状态为隐藏
                const blockBaData: BlockBaData = {
                    index_i: i,
                    index_j: j,
                    block_ba_node: _block_ba,
                    block_state: BlockState.HIDE,
                    block_sprite: _block_ba.getComponent(ResSprite),
                    block_color: Url.BLOCK.ORANGE
                };
                // 将blockBaData对象保存到block_ba_data二维数组中
                this.block_ba_data[i][j] = blockBaData;
            }
        }

        // 设置透明度的逐行显示效果，添加延迟
        for (let i = this.boardSize - 1; i >= 0; i--) {
            for (let j = 0; j < this.boardSize; j++) {
                let _block_ba = this.block_ba_data[i][j].block_ba_node;
                tween(_block_ba.getComponent(UIOpacity))
                    .to(0.1, { opacity: 255 })  // 显示块
                    .start();
            }
            // 等待一段时间以便逐行显示
            await this.delay(100); // 可以调整延迟时间
        }

        // 根据数据设置状态，并从最上面一行开始逐行隐藏state为0的块
        for (let i = 0; i < this.boardSize; i++) {
            for (let j = 0; j < this.boardSize; j++) {
                let state = _boardData[i][j];
                this.block_ba_data[i][j].block_state = state == 1 ? BlockState.SHOW : BlockState.HIDE;

                // 如果状态是隐藏，调整透明度
                if (state == 0) {
                    let _block_ba = this.block_ba_data[i][j].block_ba_node;
                    tween(_block_ba.getComponent(UIOpacity))
                        .to(0.1, { opacity: 0 })  // 隐藏块
                        .start();
                }
            }
            // 等待一段时间以便逐行隐藏
            await this.delay(100); // 可以调整延迟时间
        }

        // 保存当前的棋盘状态
        this.saveCurrentBoardState();
    }

    // 延迟函数
    delay(ms: number): Promise<void> {
        return new Promise(resolve => setTimeout(resolve, ms));
    }
    //  更新棋盘
    updateBoard() {
        for (let i = 0; i < this.block_ba_data.length; i++) {
            for (let j = 0; j < this.block_ba_data[i].length; j++) {
                let state = this.block_ba_data[i][j].block_state
                this.block_ba_data[i][j].block_ba_node.getComponent(UIOpacity).opacity = state == 1 ? 255 : 0;
            }
        }
    }
    // 根据权重随机返回一个图块数据
    getRandomBlockConfig(): BlockConfig | undefined {
        let totalWeight = 0;
        const cumulativeWeights: { type: BlockType, weight: number }[] = [];
        // 累积权重
        for (const type in BlockWeights) {
            if (BlockWeights.hasOwnProperty(type)) {
                const blockType = Number(type) as BlockType;
                const weight = BlockWeights[blockType];
                totalWeight += weight;
                cumulativeWeights.push({ type: blockType, weight: totalWeight });
            }
        }
        const random = Math.random() * totalWeight;
        let selectedType: BlockType | undefined = undefined;
        let low = 0;
        let high = cumulativeWeights.length - 1;
        // 二分查找
        while (low <= high) {
            const mid = Math.floor((low + high) / 2);
            if (random < cumulativeWeights[mid].weight) {
                selectedType = cumulativeWeights[mid].type;
                high = mid - 1;
            } else {
                low = mid + 1;
            }
        }
        if (selectedType !== undefined) {
            const filteredBlocks = BlocksAll.filter(block => block.block_type === selectedType);
            // console.log('Filtered Blocks:', filteredBlocks);
            if (filteredBlocks.length > 0) {
                const randomIndex = Math.floor(Math.random() * filteredBlocks.length);
                let colorIandU = mtec.number.random(0, 6, 0);
                switch (colorIandU) {
                    case 0:
                        filteredBlocks[randomIndex].block_color = Url.BLOCK.BLUE;
                        break;
                    case 1:
                        filteredBlocks[randomIndex].block_color = Url.BLOCK.DEEPBLUE;
                        break;
                    case 2:
                        filteredBlocks[randomIndex].block_color = Url.BLOCK.GREEN;
                        break;
                    case 3:
                        filteredBlocks[randomIndex].block_color = Url.BLOCK.ORANGE;
                        break;
                    case 4:
                        filteredBlocks[randomIndex].block_color = Url.BLOCK.PURPLE;
                        break;
                    case 5:
                        filteredBlocks[randomIndex].block_color = Url.BLOCK.RED;
                        break;
                    case 6:
                        filteredBlocks[randomIndex].block_color = Url.BLOCK.YELLOW;
                        break;
                    default:
                        filteredBlocks[randomIndex].block_color = Url.BLOCK.BLUE;
                        break;
                }
                return filteredBlocks[randomIndex];
            }
        }
        return undefined;
    }
    /**
     *  选择区刷新生成三个图块
     * @param isPropFrash 是否使用道具刷新-用作效果判断
     * @param blockConfig 是否指定块，传块配置
     */
    generateSelectionBlock(isPropFrash: boolean, blockConfig?: BlockConfig[]) {

        let configs = [];
        if (blockConfig) {
            for (let i = 0; i < blockConfig.length; i++) {
                configs.push(blockConfig[i]);
                TouchMgr.ins.selectCanTouch[i] = true;
            }
        } else {
            for (let i = 0; i < 3; i++) {
                configs.push(GridBlockMgr.ins.getRandomBlockConfig())
                TouchMgr.ins.selectCanTouch[i] = true;
            }
        }
        if (isPropFrash) {
            this.selects.forEach((block, index) => {
                tween(block)
                    .to(0.2, { scale: v3(0, 0, 1) })
                    .call(() => {
                        const blockConfig = configs[index];
                        block.setPosition(new Vec3(0, 0, 0))
                        block.getComponent(BlockController).updateBlockSet(true, blockConfig);
                        block.getComponent(BlockController).addBlockOffset(4);
                        block.active = true
                    })
                    .to(0.2, { scale: v3(0.5, 0.5, 1) })
                    .start()
            })
            MainGameLogic.ins.propInUse = false;
        } else {
            this.SelectionContainer.setPosition(v3(view.getVisibleSize().width, 0, 0))
            this.SelectionContainer.setScale(0, 0, 1);
            tween(this.SelectionContainer)
                .parallel(
                    tween().to(0.5, { position: v3(0, 0, 0) }),
                    tween().to(0.5, { scale: v3(1, 1, 1) })
                )
                .start()
            this.selects.forEach((block, index) => {
                const blockConfig = configs[index];
                block.setPosition(new Vec3(0, 0, 0))
                block.getComponent(BlockController).updateBlockSet(true, blockConfig);
                block.getComponent(BlockController).addBlockOffset(4);
                block.active = true
            })
        }

        this.detectSelectsBlockCanUse(true);
    }
    //  选择区生成引导图块
    generareGuideSelectionBlock(blockConfig: BlockConfig[]) {
        let configs = [];
        for (let i = 0; i < blockConfig.length; i++) {
            configs.push(blockConfig[i]);

        }
        this.selects.forEach((block, index) => {
            const blockConfi = configs[index];
            block.setPosition(new Vec3(0, 0, 0))
            block.getComponent(BlockController).updateBlockSet(true, blockConfi);
            block.getComponent(BlockController).addBlockOffset(4);
            block.active = index == 0 || index == 2 ? false : true;
        })
        TouchMgr.ins.selectCanTouch = [false, true, false];
    }
    // 重置 temp_block_ba_data
    resetTempBlockData() {
        for (let i = 0; i < this.block_ba_data.length; i++) {
            for (let j = 0; j < this.block_ba_data[i].length; j++) {
                this.temp_block_ba_data[i][j] = {
                    index_i: this.block_ba_data[i][j].index_i,
                    index_j: this.block_ba_data[i][j].index_j,
                    block_state: this.block_ba_data[i][j].block_state,
                    block_ba_node: this.block_ba_data[i][j].block_ba_node,
                    block_sprite: this.block_ba_data[i][j].block_ba_node.getComponent(ResSprite),
                    block_color: this.block_ba_data[i][j].block_color
                };
            }
        }
    }
    // 获取选择区的图块数据，用于检测游戏结束
    getSelectionBlockConfig() {
        this.selection_block_config = []; // 清空之前的配置
        for (let i = 0; i < TouchMgr.ins.selectCanTouch.length; i++) {
            if (TouchMgr.ins.selectCanTouch[i]) {
                const element = this.selects[i].getComponent(BlockController).curBlockConfig;
                this.selection_block_config.push(element);
            }
        }
    }
    // 检测游戏结束, 结束返回 true，否则返回 false
    detectGameOver(): boolean {
        this.detectSelectsBlockCanUse(false);
        this.getSelectionBlockConfig();
        const results_block_config: BlockConfig[] = [];

        if (GlobalData.isRotate) {
            //  根据 this.selection_block_config 里的 block_type，从 blocks 中找到所有对应的 BlockConfig，存到 results 里
            for (let i = 0; i < this.selection_block_config.length; i++) {
                const blockType = this.selection_block_config[i];
                // results_block_config.push(blockType);
                for (let j = 0; j < BlocksAll.length; j++) {
                    if (BlocksAll[j].block_type === blockType.block_type) {
                        results_block_config.push(BlocksAll[j]);
                    }
                }
            }
        } else {
            for (let i = 0; i < this.selection_block_config.length; i++) {
                results_block_config.push(this.selection_block_config[i])

            }
        }


        // console.log(results_block_config);

        //  循环遍历results里的BlockConfig能不能放置
        for (let i = 0; i < this.block_ba_data.length; i++) {
            for (let j = 0; j < this.block_ba_data[i].length; j++) {
                for (let k = 0; k < results_block_config.length; k++) {
                    // 重置 temp_block_ba_data
                    this.resetTempBlockData();
                    const blockArr = results_block_config[k].block_arr;
                    const date = this.temp_block_ba_data[i][j];
                    // 检测放置的方法
                    let config = this.getCenteredBlocks(date.index_i, date.index_j, blockArr);
                    let isCanPlaced = config.iscanplaced;
                    // 如果可以放置
                    if (isCanPlaced) {
                        return false;
                    }
                }
            }
        }
        // 移除道具检查逻辑
        return true;
    }
    // 遍历检测每个块能否消除,并选择最优的三个块生成（生成特定选择块的方法）
    generateSpecificSelectionBlock(isPropFrash) {

        const results: { block: BlockConfig; totalEliminate: number }[] = [];
        for (let i = 0; i < this.block_ba_data.length; i++) {
            for (let j = 0; j < this.block_ba_data.length; j++) {
                for (let k = 0; k < BlocksAll.length; k++) {
                    // 重置 temp_block_ba_data
                    this.resetTempBlockData();
                    const blockArr = BlocksAll[k].block_arr;
                    const date = this.temp_block_ba_data[i][j];
                    // 检测放置的方法
                    let config = this.getCenteredBlocks(date.index_i, date.index_j, blockArr);
                    let isCanPlaced = config.iscanplaced;
                    let placedIndexArr = config.indexarr;

                    // 如果可以放置
                    if (isCanPlaced) {
                        // 根据返回结果修改temp_block_ba_data对应位置的数据
                        for (let idx = 0; idx < placedIndexArr.length; idx++) {
                            let boardindex_i = placedIndexArr[idx][0];
                            let boardindex_j = placedIndexArr[idx][1];
                            this.temp_block_ba_data[boardindex_i][boardindex_j].block_state = BlockState.SHOW;
                        }

                        // 返回消除的行列数
                        let totalEliminate = this.checkAndUpdateTempBlocks();
                        // 只有在 totalEliminate > 0 时才保存到 results
                        if (totalEliminate > 0) {
                            // 检查是否已经存在相同 block_type 的数据
                            const existingIndex = results.findIndex(result => result.block.block_type === BlocksAll[k].block_type);
                            if (existingIndex !== -1) {
                                // 如果存在且新的 totalEliminate 更大，则替换
                                if (results[existingIndex].totalEliminate < totalEliminate) {
                                    results[existingIndex] = { block: BlocksAll[k], totalEliminate };
                                }
                            } else {
                                // 如果不存在，则添加到 results
                                results.push({ block: BlocksAll[k], totalEliminate });
                            }
                        }
                    }
                }
            }
        }
        // console.log(this.temp_block_ba_data);
        // console.log(this.block_ba_data);
        // 按 totalEliminate 排序，totalEliminate 最大的数据排在最前面
        results.sort((a, b) => {
            if (b.totalEliminate !== a.totalEliminate) {
                return b.totalEliminate - a.totalEliminate;
            } else {
                // 如果 totalEliminate 相同，则按 block_arr 中 1 的数量排序，数量越少越排在前面
                const countOnesA = this.countOnes(a.block.block_arr);
                const countOnesB = this.countOnes(b.block.block_arr);
                return countOnesA - countOnesB;
            }
        });
        // console.log(results);

        let configs: BlockConfig[] = [];
        if (results.length >= 3) {
            for (let i = 0; i < 3; i++) {
                let colorIandU = mtec.number.random(0, 6, 0);
                switch (colorIandU) {
                    case 0:
                        results[i].block.block_color = Url.BLOCK.BLUE;
                        break;
                    case 1:
                        results[i].block.block_color = Url.BLOCK.DEEPBLUE;
                        break;
                    case 2:
                        results[i].block.block_color = Url.BLOCK.GREEN;
                        break;
                    case 3:
                        results[i].block.block_color = Url.BLOCK.ORANGE;
                        break;
                    case 4:
                        results[i].block.block_color = Url.BLOCK.PURPLE;
                        break;
                    case 5:
                        results[i].block.block_color = Url.BLOCK.RED;
                        break;
                    case 6:
                        results[i].block.block_color = Url.BLOCK.YELLOW;
                        break;
                    default:
                        results[i].block.block_color = Url.BLOCK.BLUE;
                        break;
                }
                configs.push(results[i].block)
                TouchMgr.ins.selectCanTouch[i] = true;
            }
            if (isPropFrash) {
                this.selects.forEach((block, index) => {
                    tween(block)
                        .to(0.2, { scale: v3(0, 0, 1) })
                        .call(() => {
                            const blockConfig = configs[index];
                            block.setPosition(new Vec3(0, 0, 0))
                            block.getComponent(BlockController).updateBlockSet(true, blockConfig);
                            block.getComponent(BlockController).addBlockOffset(4);
                            block.active = true;

                        })
                        .to(0.2, { scale: v3(0.5, 0.5, 1) })
                        .start()
                })
                MainGameLogic.ins.propInUse = false;
            } else {
                this.SelectionContainer.setPosition(v3(view.getVisibleSize().width, 0, 0))
                this.SelectionContainer.setScale(0, 0, 1);
                tween(this.SelectionContainer)
                    .parallel(
                        tween().to(0.5, { position: v3(0, 0, 0) }),
                        tween().to(0.5, { scale: v3(1, 1, 1) })
                    )
                    .start()
                this.selects.forEach((block, index) => {
                    const blockConfig = configs[index];
                    block.setPosition(new Vec3(0, 0, 0))
                    block.getComponent(BlockController).updateBlockSet(true, blockConfig);
                    block.getComponent(BlockController).addBlockOffset(4);
                    block.active = true
                })
            }


        } else if (results.length == 2) {
            for (let i = 0; i < 2; i++) {
                let colorIandU = mtec.number.random(0, 6, 0);
                switch (colorIandU) {
                    case 0:
                        results[i].block.block_color = Url.BLOCK.BLUE;
                        break;
                    case 1:
                        results[i].block.block_color = Url.BLOCK.DEEPBLUE;
                        break;
                    case 2:
                        results[i].block.block_color = Url.BLOCK.GREEN;
                        break;
                    case 3:
                        results[i].block.block_color = Url.BLOCK.ORANGE;
                        break;
                    case 4:
                        results[i].block.block_color = Url.BLOCK.PURPLE;
                        break;
                    case 5:
                        results[i].block.block_color = Url.BLOCK.RED;
                        break;
                    case 6:
                        results[i].block.block_color = Url.BLOCK.YELLOW;
                        break;
                    default:
                        results[i].block.block_color = Url.BLOCK.BLUE;
                        break;
                }
                configs.push(results[i].block)
                TouchMgr.ins.selectCanTouch[i] = true;
            }
            configs.push(GridBlockMgr.ins.getRandomBlockConfig())
            TouchMgr.ins.selectCanTouch[2] = true;
            if (isPropFrash) {
                this.selects.forEach((block, index) => {
                    tween(block)
                        .to(0.2, { scale: v3(0, 0, 1) })
                        .call(() => {
                            const blockConfig = configs[index];
                            block.setPosition(new Vec3(0, 0, 0))
                            block.getComponent(BlockController).updateBlockSet(true, blockConfig);
                            block.getComponent(BlockController).addBlockOffset(4);
                            block.active = true
                        })
                        .to(0.2, { scale: v3(0.5, 0.5, 1) })
                        .start()
                })
                MainGameLogic.ins.propInUse = false;
            } else {
                this.SelectionContainer.setPosition(v3(view.getVisibleSize().width, 0, 0));
                this.SelectionContainer.setScale(0, 0, 1);
                tween(this.SelectionContainer)
                    .parallel(
                        tween().to(0.5, { position: v3(0, 0, 0) }),
                        tween().to(0.5, { scale: v3(1, 1, 1) })
                    )
                    .start()
                this.selects.forEach((block, index) => {
                    const blockConfig = configs[index];
                    block.setPosition(new Vec3(0, 0, 0))
                    block.getComponent(BlockController).updateBlockSet(true, blockConfig);
                    block.getComponent(BlockController).addBlockOffset(4);
                    block.active = true
                })
            }

        } else if (results.length == 1) {
            let colorIandU = mtec.number.random(0, 6, 0);
            switch (colorIandU) {
                case 0:
                    results[0].block.block_color = Url.BLOCK.BLUE;
                    break;
                case 1:
                    results[0].block.block_color = Url.BLOCK.DEEPBLUE;
                    break;
                case 2:
                    results[0].block.block_color = Url.BLOCK.GREEN;
                    break;
                case 3:
                    results[0].block.block_color = Url.BLOCK.ORANGE;
                    break;
                case 4:
                    results[0].block.block_color = Url.BLOCK.PURPLE;
                    break;
                case 5:
                    results[0].block.block_color = Url.BLOCK.RED;
                    break;
                case 6:
                    results[0].block.block_color = Url.BLOCK.YELLOW;
                    break;
                default:
                    results[0].block.block_color = Url.BLOCK.BLUE;
                    break;
            }
            configs.push(results[0].block)
            TouchMgr.ins.selectCanTouch[0] = true;
            for (let i = 1; i < 3; i++) {
                configs.push(GridBlockMgr.ins.getRandomBlockConfig())
                TouchMgr.ins.selectCanTouch[i] = true;
            }
            if (isPropFrash) {
                this.selects.forEach((block, index) => {
                    tween(block)
                        .to(0.2, { scale: v3(0, 0, 1) })
                        .call(() => {
                            const blockConfig = configs[index];
                            block.setPosition(new Vec3(0, 0, 0))
                            block.getComponent(BlockController).updateBlockSet(true, blockConfig);
                            block.getComponent(BlockController).addBlockOffset(4);
                            block.active = true
                        })
                        .to(0.2, { scale: v3(0.5, 0.5, 1) })
                        .start()
                })
                MainGameLogic.ins.propInUse = false;
            } else {
                this.SelectionContainer.setPosition(v3(view.getVisibleSize().width, 0, 0))
                this.SelectionContainer.setScale(0, 0, 1);
                tween(this.SelectionContainer)
                    .parallel(
                        tween().to(0.5, { position: v3(0, 0, 0) }),
                        tween().to(0.5, { scale: v3(1, 1, 1) })
                    )
                    .start()
                this.selects.forEach((block, index) => {
                    const blockConfig = configs[index];
                    block.setPosition(new Vec3(0, 0, 0))
                    block.getComponent(BlockController).updateBlockSet(true, blockConfig);
                    block.getComponent(BlockController).addBlockOffset(4);
                    block.active = true
                })
            }

        } else {
            this.generateSelectionBlock(isPropFrash)
        }

        this.detectSelectsBlockCanUse(true)

    }

    /**
     *  检测选择的三个块是否可以使用
     * @param switchF 
     */
    detectSelectsBlockCanUse(switchF: boolean) {
        for (let i = 0; i < this.selects.length; i++) {
            const element = this.selects[i].getComponent(BlockController);
            if (switchF) {
                this.selects[i].parent.getChildByName('frash').active = false;
            }
            element.checkGray();
        }
    }
    // 重置 temp_block_ba_data1
    resetTempBlockData1() {
        for (let i = 0; i < this.block_ba_data.length; i++) {
            for (let j = 0; j < this.block_ba_data[i].length; j++) {
                this.temp_block_ba_data1[i][j] = {
                    index_i: this.block_ba_data[i][j].index_i,
                    index_j: this.block_ba_data[i][j].index_j,
                    block_state: this.block_ba_data[i][j].block_state,
                    block_ba_node: this.block_ba_data[i][j].block_ba_node,
                    block_sprite: this.block_ba_data[i][j].block_ba_node.getComponent(ResSprite),
                    block_color: this.block_ba_data[i][j].block_color
                };
            }
        }
    }
    // 检测传入的块能否放置棋盘，不能则置灰
    detectIsCanPlaced(block_arr: number[][], block_node: Node) {
        //  循环遍历results里的BlockConfig能不能放置
        for (let i = 0; i < this.block_ba_data.length; i++) {
            for (let j = 0; j < this.block_ba_data[i].length; j++) {
                // 重置 temp_block_ba_data1
                GridBlockMgr.ins.resetTempBlockData1();
                const blockArr = block_arr
                const date = this.temp_block_ba_data1[i][j];
                // 检测放置的方法
                let config = this.getCenteredBlocks(date.index_i, date.index_j, blockArr);
                let isCanPlaced = config.iscanplaced;
                // 如果可以放置
                if (isCanPlaced) {
                    for (let i = 0; i < block_node.children.length; i++) {
                        const element = block_node.children[i].getComponent(Sprite);
                        element.grayscale = false;
                    }
                    return
                } else {
                    for (let i = 0; i < block_node.children.length; i++) {
                        const element = block_node.children[i].getComponent(Sprite);
                        element.grayscale = true;
                    }
                }
            }
        }
    }
    // 计算 block_arr 中 1 的数量的方法
    countOnes(blockArr: number[][]): number {
        let count = 0;
        for (let i = 0; i < blockArr.length; i++) {
            for (let j = 0; j < blockArr[i].length; j++) {
                if (blockArr[i][j] === 1) {
                    count++;
                }
            }
        }
        return count;
    }
    // 检测temp格子 消除方法
    checkAndUpdateTempBlocks(): number {
        const size = this.temp_block_ba_data.length;
        let totalEliminated = 0;

        // 检查每一行
        for (let i = 0; i < size; i++) {
            let rowAllOnes = true;
            for (let j = 0; j < size; j++) {
                if (this.temp_block_ba_data[i][j].block_state !== BlockState.SHOW) {
                    rowAllOnes = false;
                    break;
                }
            }
            if (rowAllOnes) {
                totalEliminated++;
                for (let j = 0; j < size; j++) {
                    this.temp_block_ba_data[i][j].block_state = BlockState.HIDE;
                }
            }
        }

        // 检查每一列
        for (let j = 0; j < size; j++) {
            let colAllOnes = true;
            for (let i = 0; i < size; i++) {
                if (this.temp_block_ba_data[i][j].block_state !== BlockState.SHOW) {
                    colAllOnes = false;
                    break;
                }
            }
            if (colAllOnes) {
                totalEliminated++;
                for (let i = 0; i < size; i++) {
                    this.temp_block_ba_data[i][j].block_state = BlockState.HIDE;
                }
            }
        }

        return totalEliminated;
    }
    //  判断当前位置是否可以放置块
    getCenteredBlocks(index_i: number, index_j: number, curBlockArr: number[][]): ReConfig {
        if (!curBlockArr) {
            return
        }
        const blocks: (number | null)[][] = Array(5).fill(null).map(() => Array(5).fill(null));
        const blocks_ba_node: (Node | null)[][] = Array(5).fill(null).map(() => Array(5).fill(null));
        const blocks_index: (number[] | null)[][] = Array(5).fill(null).map(() => Array(5).fill(null));

        const startI = Math.max(index_i - 2, 0);
        const endI = Math.min(index_i + 2, this.temp_block_ba_data.length - 1);
        const startJ = Math.max(index_j - 2, 0);
        const endJ = Math.min(index_j + 2, this.temp_block_ba_data[0].length - 1);

        for (let i = startI; i <= endI; i++) {
            for (let j = startJ; j <= endJ; j++) {
                const block = this.temp_block_ba_data[i][j].block_state;
                const block_ba_node = this.temp_block_ba_data[i][j].block_ba_node;
                const block_index = [this.temp_block_ba_data[i][j].index_i, this.temp_block_ba_data[i][j].index_j];
                blocks[i - (index_i - 2)][j - (index_j - 2)] = block;
                blocks_ba_node[i - (index_i - 2)][j - (index_j - 2)] = block_ba_node;
                blocks_index[i - (index_i - 2)][j - (index_j - 2)] = block_index
            }
        }
        for (let i = 0; i < 5; i++) {
            for (let j = 0; j < 5; j++) {
                const block = blocks[i][j];
                const curBlock = curBlockArr[i][j];
                if ((block === 1 && curBlock === 1) || (block === null && curBlock === 1)) {
                    return { iscanplaced: false, indexarr: null };
                }
            }
        }
        let returnIndexArr = [];
        //  显示提示位置
        for (let i = 0; i < 5; i++) {
            for (let j = 0; j < 5; j++) {
                const block = blocks[i][j];
                const curBlock = curBlockArr[i][j];
                if ((block === 0 && curBlock === 1)) {
                    // blocks_ba_node[i][j].getComponent(UIOpacity).opacity = 150;
                    returnIndexArr.push(blocks_index[i][j])
                }

            }
        }

        return { iscanplaced: true, indexarr: returnIndexArr };
    }
    //  生成一个展示的临时图块
    generateTempBlock(blockConfig: BlockConfig) {
        let tempblock = instantiate(this.block);
        tempblock.getComponent(BlockController).updateBlockSet(false, blockConfig);
        return tempblock;
    }
}
