/**
 * 这是一个UI工具类
 */

import { ImageAsset, Node, Prefab, Sprite, SpriteFrame, Texture2D, UITransform, Vec3, assetManager, director, resources, v3 } from "cc";
import { GameConst } from "./Config";
import EventManager from "./Manager/EventManager";
import LogMgr from "./Manager/LogMgr";
export default class UIHelp {

    public static log(...data: any[]) {
        if (GameConst.isDebug) {
            LogMgr.log(data);
        }
    }

    public static seek(target, name) {
        let t = null;
        let func = (target, name) => {
            for (let i = 0, j = target.children, len = j.length; i < len; i += 1) {
                let node = j[i];
                if (t) {
                    return t;
                } else if (node.name === name) {
                    return j[i];
                } else if (node.children.length > 0) {
                    t = func(node, name);
                }
            }
            return t;
        };
        return func(target, name);
    }

    /**
     * 根据名称在指定节点下查找子节点，并可执行回调函数和红点逻辑
     * @param parentNode 父节点，用于查找子节点的起点
     * @param widgetName 子节点名称，指定要查找的子节点的名称
     * @param callback 回调函数，在触摸结束事件触发时执行，可选
     * @param target 额外的参数，传递给回调函数
     * @returns 返回找到的子节点
     */
    public static seekWidgetByName(parentNode: Node, widgetName: string, callback?: Function, ...target: any[]): Node {
        // 根据名称在父节点中查找指定的子节点
        let widget = this.seek(parentNode, widgetName);
        // 如果找到了子节点并且有回调函数，则继续以下逻辑
        if (callback && widget) {
            // 移除子节点的触摸结束事件监听器，以更新或重新绑定事件
            widget.off(Node.EventType.TOUCH_END);
            // 绑定新的触摸结束事件监听器，触发时执行回调函数
            widget.on(Node.EventType.TOUCH_END, (event) => {
                callback && callback(event, target);
            });
            // 红点功能实现
            // 在找到的子节点下查找名为"redPoint"的子节点，用于显示红点提示
            let redPoint = UIHelp.seekWidgetByName(widget, "redPoint");
            if (redPoint) {
                // 如果找到了红点节点，则将其赋值给widget的redPoint属性
                widget.redPoint = redPoint;
            }
        }
        // 返回找到的子节点
        return widget;
    }

    /**
     * 获取当前日期和时间的格式化字符串
     * 此方法用于生成一个包含当前年、月、日、时、分、秒的日期时间字符串
     * 格式为：YYYY-MM-DD HH:mm:ss
     * @returns {string} 当前日期和时间的格式化字符串
     */
    public static getNowDate(): string {
        let date = new Date(); // 创建当前日期时间的对象
        let month: string | number = date.getMonth() + 1; // 获取当前月份，加1是因为JavaScript的getMonth()方法返回的是0-11
        let strDate: string | number = date.getDate(); // 获取当前日期

        // 确保月份和日期都是两位数，如果不是，则在其前添加"0"
        if (month <= 9) {
            month = "0" + month;
        }

        if (strDate <= 9) {
            strDate = "0" + strDate;
        }

        // 拼接年、月、日和时间，生成最终的字符串格式
        return date.getFullYear() + "-" + month + "-" + strDate + " "
            + date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds();
    }

    public static loadPrefab(path: string, call: (prefab: Prefab) => void) {

        resources.load<Prefab>(path, Prefab, (err, prefab: Prefab) => {
            if (err) {
                LogMgr.warn(err.message);
                // UIHelp.showTips("磁盘空间不足，请清理后重启游戏");
                return;
            }
            call && call(prefab);
        })

    }

    public static getCurrentScene() {
        return director.getScene();
    }

    /**
     * 将坐标转换为世界坐标
     * @param item 
     * @returns 
     */
    public static toWorldPosition(item: Node): Vec3 {
        // LogMgr.log(item.worldPosition, item.parent.getComponent(UITransform).convertToWorldSpaceAR(item.position))
        // return item.worldPosition;
        return item.parent.getComponent(UITransform).convertToWorldSpaceAR(item.position);
    }

    /**
     * 将世界坐标转换到节点坐标
     * @param item 
     * @param worldPosition 
     * @returns 
     */
    public static toNodeSpacePosition(item: Node, worldPosition: Vec3): Vec3 {
        return item.parent.getComponent(UITransform).convertToNodeSpaceAR(worldPosition);
    }

    public static setIndex(node: Node, index: number) {
        node.setSiblingIndex(index);
    }

    public static getRandomInt(min: number, max: number): number {
        // Math.random() 生成 0 到 1 之间的随机浮点数，不包括 1
        // Math.floor() 向下取整
        return Math.floor(Math.random() * (max - min + 1)) + min;
    }

    /**
     * 随机一个枚举值
     * @param anEnum 
     * @returns 
     */
    public static getRandomEnum<T>(anEnum: T): T[keyof T] {
        const enumValues = Object.keys(anEnum)
            .filter(key => isNaN(Number(key))) // 只获取字符串键（去除反向映射）
            .map(key => anEnum[key as keyof typeof anEnum]); // 将这些键映射为枚举值
        const randomIndex = Math.floor(Math.random() * enumValues.length);
        return enumValues[randomIndex];
    }


    /**
     * 显示提示信息的静态方法
     * 这个方法首先检查Telegram WebApp环境是否提供了showAlert方法，如果提供了，则使用showAlert方法显示信息；
     * 否则，退回到使用浏览器的alert方法显示信息
     * 此方法确保了在不同的环境下都能够以适当的方式向用户显示提示信息
     * 
     * @param message 要显示给用户的消息文本
     */
    public static showTips(message: string | number, durationTime: number = 1) {
        EventManager.emit('showAlert', message, durationTime);
    }


}