import { Button, Canvas, Component, EventHandler, EventTouch, Node, SpriteFrame, _decorator, warn } from "cc";
// import GlobalDC from "../common/data.global.center";

const { ccclass, property } = _decorator;

@ccclass
export class UI extends Component {

    /** 获取节点深度 */
    public static getDepth(node: Node) {
        let d: number;
        if (node.getComponent(Canvas)) d = 0;
        else d = this.getDepth(node.parent) + 1;
        return d;
    }
    /** 节点层级深度 */
    protected get depth() {
        return UI.getDepth(this.node);
    }
    /** 组件名称 */
    get comp_name() {
        let reg = new RegExp('(?<=<)(?<comp_name>[\\w, \\W]+)(?=>)', 'g');
        return reg.exec(this.name).groups.comp_name;
    }

    /** 给按钮绑定点击事件 */
    private __ButtonBindCall() {
        this.__handle = mtec.cc.creatEventHandle({
            target: this.node,
            component: this.comp_name,
            handler: '__ClickButton',
        });

        this.node.getComponentsInChildren(Button)
            .filter(btn => {
                let pass = false;
                // 如果btn的事件列表是空的，则直接无脑把自己的中继事件放进去
                if (btn.clickEvents.length === 0) pass = true;
                else {
                    // 分别收集手动绑定事件和自动绑定事件
                    let [hand_event, auto_event] = [[], []] as EventHandler[][];
                    btn.clickEvents.forEach(hdl => {
                        if (hdl.handler === '__ClickButton') auto_event.push(hdl);
                        else hand_event.push(hdl);
                    });

                    // 如果脚本中初始化了按钮事件，并且按钮事件列表中没有其它初始化事件，则直接添加
                    if (auto_event.length === 0 && this._click_event_[btn.node.name]) pass = true;
                    // 如果存在其它初始化事件，则以组件的深度优先（即距离按钮最近的组件为准）覆盖，相同深度则以当前为准覆盖
                    else if (auto_event.length > 0) {
                        let power = this.depth;
                        if (this._click_event_[btn.node.name]) power += 10000;

                        let el = auto_event.map(h => {
                            let comp = h.target.getComponent(UI);
                            let p = comp.depth;
                            if (comp._click_event_[btn.node.name]) p += 10000;
                            return { h, p };
                        }).sort((a, b) => a.p - b.p).pop();

                        if (el.p <= power) pass = true;
                        else auto_event.splice(auto_event.indexOf(el.h), 1);

                        auto_event.forEach(h => btn.clickEvents.splice(btn.clickEvents.indexOf(h), 1));
                    }
                }

                return pass;
            }).forEach(btn => {
                btn.clickEvents.push(this.__handle);
                this.__btn_map__.set(btn.node.name, btn);
            });
    }

    /** 按钮点击事件中继 */
    protected __ClickButton(event: EventTouch) {
        let node = event.currentTarget as Node;

        let btn = node.getComponent(Button);
        let call = Reflect.get(this._click_event_, node.name);
        if (node.name in this._click_event_) {
            Reflect.apply(call, this, [btn]);

            // 发送点击事件,只对初始化的按钮发送事件
            // GlobalDC.Trigger.CLICK = {
            // 	component: this.comp_name,
            // 	button: node.name
            // };
        } else this.ClickBtn(btn);
    }

    /** 没有被初始化的按钮 */
    protected ClickBtn(btn: Button) {
        btn.interactable
        warn(`<${this.comp_name}> 按钮[${btn.node.name}]未被初始化`);
    }

    /** ui交互控制 */
    protected interactable(able: boolean) {
        this.__btn_map__.forEach(btn => btn.interactable = able);
    }

    /** 初始化组件基本逻辑 */
    private __init() {
        if (!this._click_event_.__common) this._click_event_.__common = (() => { }).bind(this);
        this.__ButtonBindCall();
        if (this.sframe.length > 0) {
            this.sframe.forEach(frame => this.smap.set(frame.name, frame));
            this.sframe = undefined;
        }
        if (this.initAfterOnLoad) this.initAfterOnLoad();
    }

    /** 组件事件对象 */
    protected _click_event_: { [name: string]: (this: UI, button: Button) => void } = {};
    /** 组件上的按钮通用回调 */
    protected __handle: EventHandler = null;
    protected __btn_map__: Map<string, Button> = new Map();
    /** ui常用贴图映射 */
    protected smap: Map<string, SpriteFrame> = new Map();

    /** 在加载后的一些自定义初始化 */
    protected initAfterOnLoad(): void {

    };

    @property([SpriteFrame])
    /** ui常用贴图 */
    private sframe: SpriteFrame[] = [];

    protected onLoad() {
        this.__init();
    }
}