import { _decorator, Color, Component, find, Label, Node, Sprite, Tween, tween, UITransform, v3 } from 'cc';
import { PoolManager } from '../core/manager/PoolManager';
import { bundleMgr } from '../core/manager/BundleManager';
import { ResUtil } from './ResUtil';
const { ccclass, property } = _decorator;

/** 
 * 通用消息提示框
 * 使用示例:
 * MsgHints.show("这是一条提示消息");
 * 
 * 特性:
 * 1. 使用对象池管理
 * 2. 动态创建节点(无需预制体)
 * 3. 内置Tween动画效果
 * 4. 自动回收机制
 */
@ccclass("MsgHints")
export default class MsgHints extends Component {
    //节点对象次的名字
    private static readonly node_name = "MsgHints";
    //默认显示时长(秒)
    private static readonly default_duration = 1.5; 
    //文本最大宽度
    private static readonly max_width = 430; 
    //边距
    private static readonly padding = 15; 
    
    /**
     * 创建一个msgNode节点
     * @returns 
     */
    private static createMsgNode() {
        let node: Node | null = PoolManager.getName(MsgHints.node_name);
        if(!node){
            //创建背景
            node = new Node(MsgHints.node_name);
            node.addComponent(MsgHints);
            node.active = true;
            const bgTransform = node.addComponent(UITransform);
            bgTransform.width = MsgHints.max_width;
            bgTransform.height = 50;
            node.setPosition(0, 0, 0);
            let sp:Sprite = node.addComponent(Sprite);
            sp.sizeMode = Sprite.SizeMode.TRIMMED;
            sp.type = Sprite.Type.SIMPLE;
            ResUtil.setSpriteFrame("msg_hint",sp);

            //创建文本标签
            const labelNode = new Node('label');
            const laTransform = labelNode.addComponent(UITransform);
            laTransform.width = MsgHints.max_width - MsgHints.padding * 2;
            laTransform.height = 50;
            let label = labelNode.addComponent(Label);
            label.fontSize = 25;
            label.color = Color.WHITE;
            label.lineHeight = 30;
            label.horizontalAlign = Label.HorizontalAlign.CENTER;
            label.verticalAlign = Label.VerticalAlign.CENTER;
            label.overflow = Label.Overflow.NONE;
            label.isBold = true;
            labelNode.parent = node;
        }
        return node;
    }

    /**
     * 设置提示消息内容
     * @param msg 消息内容
     */
    public setMsg(msg: string) {
        let label:Label = this.reset();
        if (!label) return;
        label.string = msg;
        this._adjustLayout();
        this._playAnimation();
    }

    /**
     * 调整对齐
     * @returns 
     */
    private _adjustLayout() {
        let padding: number = 20.0;
        const label = this.getMsgLable();
        const labelTransform = label?.node.getComponent(UITransform);
        const bgTransform = this.node.getComponent(UITransform);
        if (!labelTransform || !bgTransform) return;
        // 计算文本实际宽度（不超过 maxWidth）
        let labelMax: number = MsgHints.max_width - MsgHints.padding * 2;
        const textWidth = Math.min(labelTransform.width, MsgHints.max_width - MsgHints.padding * 2);
        if(textWidth >= labelMax){
           label.overflow = Label.Overflow.RESIZE_HEIGHT;
           labelTransform.width = MsgHints.max_width - padding * 2;
           bgTransform.width = MsgHints.max_width;
           bgTransform.height = labelTransform.height + 10;
        }else{
           label.overflow = Label.Overflow.NONE;
           labelTransform.width = textWidth;
           bgTransform.width = textWidth + padding * 2;
           bgTransform.height = labelTransform.height + 10 * 3;
        }
    }

    /**
     * 播放展示动画
     */
    private _playAnimation() {
        Tween.stopAllByTarget(this.node);
        this.node.setScale(v3(0, 0, 0));
        tween(this.node)
            .to(0.1, { scale: v3(1.1, 1.1, 1) })
            .to(0.1, { scale: v3(0.9, 0.9, 1) })
            .to(0.1, { scale: v3(1, 1, 1) })
            .delay(MsgHints.default_duration)
            .by(0.5, { position: v3(0, 100, 0) })
            .call(() => {
                this.reset();
                PoolManager.putNode(this.node);
            })
            .start();
    }

    /**
     * 重置lable一些属性
     */
    public reset(): Label{
        let lable:Label = this.getMsgLable();
        let laTransform:UITransform = lable.node.getComponent(UITransform);
        laTransform.width = MsgHints.max_width - MsgHints.padding * 2;
        laTransform.height = 50;
        lable.overflow = Label.Overflow.NONE;
        this.node.setScale(v3(1, 1, 1));
        return lable;
    }

    /**
     * 显示提示消息
     * @param msg 消息内容
     */
    public static show(msg: string): Promise<void> {
        if(!msg)return;
        //尝试从对象池获取
        let node: Node = this.createMsgNode();
        //设置节点到Canvas
        const canvas = find("Canvas");
        if (canvas) {
            node.active = true;
            node.parent = canvas;
            //确保在最上层
            node.setSiblingIndex(9999);
            //设置消息内容
            const comp = node.getComponent(MsgHints);
            if (comp) {
                comp.setMsg(msg);
            }
        }
    }

    /**
     * 得到文本节点
     */
    public getMsgLable(){
        return this.node.getChildByName("label").getComponent(Label);
    }
}