/**
 * 负责单个滚轮的创建、滚动、停止等逻辑
 */
import {
    _decorator,
    Node,
    UITransform,
    Vec2,
    v2,
    Vec3,
    v3,
    tween,
    Tween,
    Mask,
} from 'cc';
import { IconFactory } from './IconFactory';
import { Icon } from './Icon';
import { BaseRoller, ROLLER_STATE } from './BaseRoller';
import { ROLLER_EVENT } from './Define';
import { callGameApi } from 'db://assets/Loading/scripts/comm';

let { ccclass, property, executeInEditMode } = _decorator;

/**
 * 滚轮组件类
 */
@ccclass('HRoller')
@executeInEditMode
export class HRoller extends BaseRoller {

    // 编辑器属性
    @property({ tooltip: '列数' })
    col: number = 3;

    // 本地格式化相关
    @property
    _format = false;
    @property({ tooltip: '本地格式化' })
    get format(): boolean {
        return this._format;
    }
    set format(b: boolean) {
        this._format = b;
        this.resizeContentSize();

        if (!this.iconFactory) {
            console.error('IconFactory没有设置');
            return;
        }

        // 重新创建图标
        this._content.removeAllChildren();
        this._info.icons = [];
        this._allIcons.clear();
        this._posToIconKey.clear();
        // 清除位置缓存 - 添加这一行
        this._positionCache.clear();

        for (let i = 0; i < this.col; i++) {
            let randomIndex = Math.floor(Math.random() * this.iconFactory.getIconNum());
            this.createNormalIcon(i, randomIndex);
        }
    }

    _cachedContentWidth: number = 0;
    _cachedAnchorX: number = 0;

    /**
     * 创建滚轮实例
     * @param id 滚轮ID
     * @param row 行数
     * @param iconWidth 图标宽度
     * @param iconHeight 图标高度
     * @param iconFactory 图标工厂实例
     * @param anchor 锚点位置
     * @returns 新创建的滚轮实例
     */
    static create(
        id: number,
        col: number,
        iconWidth: number,
        iconHeight: number,
        iconFactory: IconFactory,
        anchor: Vec2 = v2(0.5, 0.5)
    ): HRoller {
        let rollerNode = new Node(`Roller${id}`);
        rollerNode.addComponent(UITransform);

        let roller = rollerNode.addComponent(HRoller);
        roller._rollerId = id;
        roller.col = col;
        roller.iconWidth = iconWidth;
        roller.iconHeight = iconHeight;
        roller.iconFactory = iconFactory;

        rollerNode.getComponent(UITransform).setAnchorPoint(anchor);
        roller.resizeContentSize();
        roller.initRoller(id);
        return roller;
    }

    /**
     * 设置节点尺寸和位置
     */
    setupNodesSizeAndPosition() {
        let totalWidth = this.iconWidth * this.col;
        let anchorPoint = this.node.getComponent(UITransform).anchorPoint;

        // 设置主节点尺寸
        this.node.getComponent(UITransform).setContentSize(totalWidth, this.iconHeight);

        // 设置view节点
        this._view.setPosition(0, 0);
        this._view.getComponent(UITransform).setContentSize(totalWidth, this.iconHeight);
        this._view.getComponent(UITransform).setAnchorPoint(anchorPoint);
        this._view.getComponent(UITransform).height *= 2;

        // 设置content节点
        this._content.setPosition(0, 0);
        this._content.getComponent(UITransform).setContentSize(totalWidth, this.iconHeight);
        this._content.getComponent(UITransform).setAnchorPoint(anchorPoint);
        this._content.removeAllChildren();
    }

    /**
     * 获取图标的实际坐标
     * @param pos 图标位置索引
     * @param height 图标高度
     * @returns 图标的世界坐标
     */
    getIconPosition(pos: number, size: number = 1): Vec3 {
        // 创建缓存键
        let cacheKey = size > 1 ? (pos + 1) * 1000 + size : pos;

        if (this._positionCache.has(cacheKey)) {
            return this._positionCache.get(cacheKey).clone();
        }

        // 确保缓存数据已初始化
        if (!this._cachedContentWidth) {
            this._cachedContentWidth = this._content.getComponent(UITransform).width;
            this._cachedAnchorX = this._content.getComponent(UITransform).anchorX;
        }

        // 计算基准位置
        let contentWidth = this._cachedContentWidth;
        let anchorX = this._cachedAnchorX;

        // 计算最左边位置
        let leftX = -contentWidth * (1 - anchorX);

        // 计算第一个位置的中心x坐标
        let firstCenterX = leftX + this.iconWidth / 2;

        // 计算当前位置的中心X坐标
        let centerX = firstCenterX + pos * this.iconWidth;

        // 对于大图标，需要调整位置
        let finalX = centerX;
        if (size > 1) {
            // 大图标的中心点应该下移，使其顶部对齐格子
            // 对于高度为3的图标，中心点应该下移1个格子高度
            finalX = centerX + (size - 1) * this.iconWidth / 2;
        }

        // 创建最终位置
        let position = v3(finalX, 0, 0);

        // 缓存结果
        this._positionCache.set(cacheKey, position.clone());
        return position;
    }

    /**
     * 初始化性能优化相关的缓存
     */
    initCache() {
        this._cachedUITransform = this._content.getComponent(UITransform);
        this._cachedContentWidth = this._cachedUITransform.width;
        this._cachedAnchorX = this._cachedUITransform.anchorX;
    }

    /**
     * 收集现有图标
     */
    collectExistingIcons() {
        for (let i = 0; i < this.col; i++) {
            let icon = this._allIcons.get(this._posToIconKey.get(i));
            if (icon) {
                this._allIcons.delete(this._posToIconKey.get(i));
                this._posToIconKey.delete(i);
                this._info.icons.push(icon);
            }
        }
    }

    /**
     * 手动停止滚动
     * @param data 停止时的图标数据
     */
    async manualStopScroll(data: number[]) {
        if (this._info.isManualStop ||
            this._info.state === ROLLER_STATE.STOP) {
            return;
        }

        this.changeState(ROLLER_STATE.STOP);
        this._info.resetLxInfo();
        this._stopData = data;
        this._info.isManualStop = true;
        Tween.stopAllByTarget(this._info.speedNode);

        // 直接回收所有动态图标
        while (this._info.icons.length > 0) {
            let icon = this._info.icons.pop();
            this.iconFactory.recycleIcon(icon);
        }

        // 回收固定位置图标
        for (let i = 0; i < this.col; i++) {
            let icon = this._allIcons.get(this._posToIconKey.get(i));
            if (icon) {
                this._allIcons.delete(this._posToIconKey.get(i));
                this._posToIconKey.delete(i);
                this.iconFactory.recycleIcon(icon);
            }
        }
        this._allIcons.clear();
        this._posToIconKey.clear();

        this.createInitIcons(data);
        // 为所有创建的图标播放动画
        for (let icon of this._allIcons.values()) {
            icon.getComponent(Icon).playSpawnAni();
        }
    }

    /**
     * 创建最后一页图标
     */
    createLastPage() {
        let data = this._stopData;
        if (!data) return;

        // 计算最右边icon基准位置
        let rightX = this.getIconPosition(this.col - 1).x;
        let icons = this._info.icons;
        if (icons.length > 0) {
            rightX = Math.max(rightX, this.findHighestIconXorY(icons));
        }

        // 清除已有的位置映射，准备重新创建
        this._allIcons.clear();
        this._posToIconKey.clear();

        // 从左到右依次创建图标（从位置0开始）
        for (let i = 0; i < data.length; i++) {
            // 如果当前位置已被特殊图标占用，跳过
            if (this._posToIconKey.has(i)) continue;

            // 生成图标ID
            let pos = i;
            let iconIndex = data[i];
            let iconKey = this.generateIconKey(pos, 1, pos);

            // 创建图标节点
            let icon = this.iconFactory.icfactoryCreateIcon(iconIndex);
            icon.getComponent(Icon).initIcon(iconIndex, 1, iconKey, 0, this._rollerId);

            // 计算位置
            let x = rightX + (pos + 1) * this.iconWidth;
            icon.setPosition(x, 0, 0);

            this._content.addChild(icon);

            // 存储图标节点
            this._allIcons.set(iconKey, icon);
            this._posToIconKey.set(pos, iconKey);

        }
        this.node.emit(ROLLER_EVENT.LAST_PAGE_CREATE, this._rollerId);
    }


    /**
     * 检查图标是否超出显示范围
     */
    checkDeadLine(icon: Node): boolean {
        if (!this._cachedContentWidth) {
            this._cachedContentWidth = this._content.getComponent(UITransform).width;
            this._cachedAnchorX = this._content.getComponent(UITransform).anchorX;
        }

        let iconComponent = icon.getComponent(Icon);
        let lheight = iconComponent.lHeight;
        let iconBody = (lheight - 1) * this.iconWidth + this.iconWidth / 2;
        let deadLine = -(this._cachedContentWidth * this._cachedAnchorX) - iconBody;

        return icon.position.x <= deadLine;
    }

    /**
     * 补充新的图标
     */
    suppleIcon() {
        let bornLine = this.getIconPosition(this.col - 1).x;
        let icons = this._info.icons;

        // 找到最右边的的图标X坐标
        let rightX = this.findHighestIconXorY(icons);

        // 如果最右边的图标低于出生线，创建新图标
        if (rightX < bornLine) {
            this.createRandomIcon();
        }
    }


    /**
     * 创建随机图标
     */
    createRandomIcon() {
        let iconIndex = this.getRandomIconIndex();
        let newX = this.computeNewIconXorY();
        let icon = this.iconFactory.icfactoryCreateIcon(iconIndex);

        // 设置快速图标效果
        if (this.shouldShowFastIcon()) {
            icon.getComponent(Icon).showFastIcon(true);
        }
        icon.setPosition(newX, 0, 0);
        this._content.addChild(icon);


        this._info.icons.push(icon);
        this.node.emit(ROLLER_EVENT.ON_R_ICON_CREATE, this._rollerId, icon);
    }


    /**
     * 找到最右边的图标X坐标
     * @param icons 图标数组
     * @returns 最右边的X坐标
     */
    findHighestIconXorY(icons: Node[]): number {
        return icons.reduce((maxX, icon) => {
            if (!icon || !icon.active) return maxX;

            let iconComponent = icon.getComponent(Icon);
            if (!iconComponent) return maxX;

            let lHeight = iconComponent.lHeight || 1;
            let iconX = icon.position.x;

            // 对于高度大于1的图标，考虑其顶部位置
            if (lHeight > 1) {
                // 计算图标顶部位置：当前位置 + 高度差 * 图标高度 / 2
                return Math.max(maxX, iconX + (lHeight - 1) * this.iconWidth / 2);
            } else {
                return Math.max(maxX, iconX);
            }
        }, -999);
    }



    /**
     * 计算新图标的X坐标
     */
    computeNewIconXorY(): number {
        let icons = this._info.icons;

        // 如果没有图标，使用初始位置
        if (!icons.length) {
            return this.getIconPosition(this.col - 1).x + this.iconWidth;
        }

        // 找到最右边的图标X坐标
        let rightX = this.findHighestIconXorY(icons);

        // 新图标位置 = 最高图标位置 + 图标高度
        return rightX + this.iconWidth;
    }

    /**
     * 清理资源
     */
    onDestroy() {
        this._cachedUITransform = null;
        this._cachedContentWidth = 0;
        this._cachedAnchorX = 0;
        this._positionCache.clear();
    }

    /**
     * 滚轮移动
     * @param dt 时间增量
     */
    rollerMove(dt: number) {
        // 计算移动向量
        let speed = this._info.speed;
        let move = speed * dt;
        let moveVec = v3(move, 0, 0);



        // 更新动态图标位置
        this._info.icons.forEach(icon => {
            if (!icon || !icon.isValid) return;

            if (icon.active) {
                let newPosition = icon.position.clone().subtract(moveVec);
                icon.setPosition(newPosition);
            }
        });
        // 获取所有图标
        let allIcons = Array.from(this._allIcons.values());
        allIcons.forEach(icon => {
            if (!icon || !icon.isValid) return;
            let newPosition = icon.position.clone().subtract(moveVec);
            icon.setPosition(newPosition);
        });


    }

    /**
     * 回收滚轮图标
     */
    recycleRollerIcon() {
        // 回收动态图标
        let icons = this._info.icons;
        for (let i = icons.length - 1; i >= 0; i--) {
            let icon = icons[i];
            if (!icon || !icon.isValid) {
                icons.splice(i, 1);
                continue;
            }

            if (this.checkDeadLine(icon)) {
                // 从数组中移除
                icons.splice(i, 1);
                // 回收图标
                this.iconFactory.recycleIcon(icon);
            }
        }

        // 回收固定位置图标（非最后一页创建状态）
        if (this._info.state !== ROLLER_STATE.LAST_PAGE_CREATE) {
            for (let i = 0; i < this.col; i++) {
                let iconKey = this._posToIconKey.get(i);
                if (!iconKey) continue;

                let icon = this._allIcons.get(iconKey);
                if (!icon || !icon.isValid) {
                    this._posToIconKey.delete(i);
                    this._allIcons.delete(iconKey);
                    continue;
                }

                if (this.checkDeadLine(icon)) {
                    // 从映射中移除
                    this._allIcons.delete(iconKey);
                    this._posToIconKey.delete(i);
                    // 回收图标
                    this.iconFactory.recycleIcon(icon);
                }
            }
        }

        // 处理特殊图标（n*1图标）
        if (this._info.state !== ROLLER_STATE.LAST_PAGE_CREATE) {
            // 获取所有特殊图标的key
            let specialIconKeys = Array.from(this._allIcons.keys())
                .filter(key => key.startsWith('large_'));

            for (let iconKey of specialIconKeys) {
                let icon = this._allIcons.get(iconKey);
                if (!icon || !icon.isValid) {
                    this._allIcons.delete(iconKey);
                    continue;
                }

                if (this.checkDeadLine(icon)) {
                    // 从映射中移除
                    this._allIcons.delete(iconKey);

                    // 移除所有关联的位置映射
                    for (let [pos, key] of this._posToIconKey.entries()) {
                        if (key === iconKey) {
                            this._posToIconKey.delete(pos);
                        }
                    }

                    // 回收图标
                    this.iconFactory.recycleIcon(icon);
                }
            }
        }
    }



    /**
     * 停止处理
     */
    stopProcess() {
        let rightIcon = this.getIconPosition(this.col - 1);
        let stopline = rightIcon.x - 100; // 偏移量100
        let topX = this.findHighestIconXorY(Array.from(this._allIcons.values()));

        if (topX <= stopline) {
            this.changeState(ROLLER_STATE.BOUNCE);
            this.playBounceAnimation();
        }
    }

    /**
     * 播放回弹动画
     */
    playBounceAnimation() {
        let time = 0.1;
        let offset = 50;

        // 获取所有图标
        let allIcons = Array.from(this._allIcons.values());

        allIcons.forEach(icon => {

            if (!icon || !icon.isValid) return;

            let iconComponent = icon.getComponent(Icon);
            if (!iconComponent) return;

            // 获取图标的起始位置和高度
            let startPos = iconComponent.startPos;
            let lHeight = iconComponent.lHeight || 1;

            // 获取图标应该在的位置
            let position = this.getIconPosition(startPos, lHeight);

            // 设置初始位置（向下偏移）
            // icon.setPosition(position.add(v3(-offset, 0, 0)));
            icon.setPosition(position);
            iconComponent.playSpawnAni();

            // 创建回弹动画
            // tween(icon)
            //     .by(time, { position: v3(offset, 0, 0) })
            //     .start();
        });

        // 延迟切换到停止状态
        this.scheduleOnce(() => {
            this.changeState(ROLLER_STATE.STOP);
        }, time);
    }

    /**
     * 消除逻辑 
     * 一定是在静止状态消除的
     * @param deleteMsg 删除信息
     * */
    deleteIconNode(positions: number[]) {
        // 记录被处理过的图标键
        let processedPos = new Set<number>();

        // 处理每个位置
        for (let pos of positions) {
            // 如果此图标已处理过，跳过
            if (processedPos.has(pos)) {
                continue;
            }
            let iconKey = this._posToIconKey.get(pos);
            if (!iconKey) {
                console.error('deleteIconNode iconKey is null', pos);
                continue;
            }



            let iconNode = this._allIcons.get(iconKey);
            if (!iconNode || !iconNode.isValid) {
                console.error('deleteIconNode iconNode is null', pos);
                continue;
            }

            let iconComponent = iconNode.getComponent(Icon);
            if (!iconComponent) {
                console.error('deleteIconNode iconComponent is null', pos);
                continue;
            }


            let startPos = iconComponent.startPos;
            // 从allIcons中删除图标
            this._allIcons.delete(iconKey);

            let height = iconComponent.lHeight || 1;
            // 移除所有关联的位置映射
            if (height > 1) {
                // 对于n*1图标，需要清除所有占用的位置
                for (let i = 0; i < height; i++) {
                    this._posToIconKey.delete(startPos + i);
                    // 标记此图标已处理
                    processedPos.add(startPos + i);
                }
            } else {
                this._posToIconKey.delete(pos);
                // 标记此图标已处理
                processedPos.add(pos);

            }
            iconComponent.playWinAni(true);
            iconComponent.playDeleteAni();
            this.scheduleOnce(() => {
                this.iconFactory.recycleIcon(iconNode);
            }, 1.2)
        }

        this.node.emit(ROLLER_EVENT.ICON_DELETED, this._rollerId);
    }

    playFrameTypeChangeAni(positions: number[]): void {
        for (let pos of positions) {

            let iconKey = this._posToIconKey.get(pos);
            if (!iconKey) continue;

            let iconNode = this._allIcons.get(iconKey);
            if (!iconNode || !iconNode.isValid) continue;

            let iconComponent = iconNode.getComponent(Icon);
            if (!iconComponent) continue;

            iconComponent.playWinAni(true);
        }
    }

    chanegeIconAndFrameType(data: any[]): void {
        return;
    }

    /**
     * 创建新icon
     * @param createMsg 信息
     */
    createNewIconTop(createDatas: number[]) {
        // 获取所有图标        
        let rightX = this.getIconPosition(this.col - 1, 1).x;
        for (let i = 0; i < createDatas.length; i++) {
            let pos = this.col + i + 1;
            let iconIndex = createDatas[i];
            let iconKey = this.generateIconKey(pos, 1, pos);
            let icon = this.iconFactory.icfactoryCreateIcon(iconIndex);
            icon.getComponent(Icon).initIcon(iconIndex, 1, iconKey, 0, this._rollerId);

            let x = rightX + (i + 1) * this.iconWidth;
            icon.setPosition(x, 0, 0);
            this._content.addChild(icon);

            this._allIcons.set(iconKey, icon);
            this._posToIconKey.set(pos, iconKey);
        }
        this.node.emit(ROLLER_EVENT.ICON_CREATE, this._rollerId);
    }


    /** icon进行掉落移动 */
    iconFallDown(data: number[], CroSymbols: any) {
        // 更新所有icon的iconKey和posToIconKey

        let updates = [];
        let sortNewIconStartPos = this.getNewIconsStartPos(data, CroSymbols);
        let sortIcons = this.getSortIcons();
        for (let i = 0; i < sortNewIconStartPos.length; i++) {
            let newStartPos = sortNewIconStartPos[i];
            let oldIcon = sortIcons[i];
            let oldIconStartPos = oldIcon.startPos;


            if (oldIconStartPos === newStartPos) {
                continue;
            }
            let oldIconNode = oldIcon.icon;
            let oldIconComponent = oldIcon.component;
            let oldIconkey = oldIconComponent.iconKey;
            let lHeight = oldIconComponent.lHeight || 1;
            let newIconkey = this.generateIconKey(newStartPos, 1, newStartPos);
            let newX = this.getIconPosition(newStartPos, lHeight).x;
            let oldX = oldIconNode.position.x;

            updates.push({
                node: oldIconNode,
                component: oldIconComponent,
                oldKey: oldIconkey,
                oldStartPos: oldIconStartPos,
                newStartPos: newStartPos,
                newKey: newIconkey,
                height: lHeight
            })


            let time = 0.3;
            tween(oldIconNode)
                .to(time, { position: v3(newX, 0, 0) })
                .start();
        }

        for (let update of updates) {
            this._allIcons.delete(update.oldKey);
            for (let i = 0; i < update.height; i++) {
                this._posToIconKey.delete(update.oldStartPos + i);
            }
        }

        // 再添加所有新映射
        for (let update of updates) {
            // 添加新的映射
            update.component.iconKey = update.newKey;
            this._allIcons.set(update.newKey, update.node);
            for (let i = 0; i < update.height; i++) {
                this._posToIconKey.set(update.newStartPos + i, update.newKey);
            }
        }
        this.scheduleOnce(() => {
            this.node.emit(ROLLER_EVENT.ICON_FALLEN, this._rollerId);
        }, 0.5)
    }


    getSortIcons() {
        let iconInfos: { icon: Node, component: Icon, startPos: number }[] = [];

        // 收集所有图标信息
        for (let [iconKey, iconNode] of this._allIcons.entries()) {
            if (!iconNode || !iconNode.isValid) continue;

            let iconComponent = iconNode.getComponent(Icon);
            if (!iconComponent) continue;

            // 记录图标信息
            iconInfos.push({
                icon: iconNode,
                component: iconComponent,
                startPos: iconComponent.startPos
            });
        }

        // 按startPos从小到大排序
        iconInfos.sort((a, b) => a.startPos - b.startPos);

        return iconInfos;
    }



    getNewIconsStartPos(data: number[], CroSymbols: any) {
        // 存储所有图标的startPos
        let startPositions: number[] = [];

        // 记录已处理的位置
        let processedPositions = new Set<number>();
        // 记录已经处理的pos
        let processedPos = new Set<number>();
        // 首先处理不规则图标（n*1图标）
        if (CroSymbols) {
            for (let pos in CroSymbols) {
                let id = CroSymbols[pos].id;
                if (processedPos.has(id)) continue;
                processedPos.add(id);
                let iconSpecialMsg = CroSymbols[pos];
                let startPos = iconSpecialMsg.startPos;
                let endPos = iconSpecialMsg.endPos;

                // 添加不规则图标的startPos
                startPositions.push(startPos);

                // 标记所有被占用的位置
                for (let i = startPos; i <= endPos; i++) {
                    processedPositions.add(i);
                }
            }
        }

        // 然后处理常规图标
        for (let i = 0; i < data.length; i++) {
            // 如果该位置未被处理（不是不规则图标的一部分）
            if (!processedPositions.has(i)) {
                startPositions.push(i);
            }
        }

        // 从小到大排序
        startPositions.sort((a, b) => a - b);
        return startPositions;
    }

}
