import { IActionParam, IParam } from "@core";
import { MainControl } from "../main-control";
import { PanelControlProps } from "./panel-control-prop";
import { PanelControlState } from "./panel-control-state";

/**
 * @description 面板部件
 * @export
 * @class PanelControl
 * @extends {MainControl}
 */
export class PanelControl extends MainControl {

    /**
     * @description 部件状态
     * @type {FormControlState}
     * @memberof PanelControl
     */
    public declare state: PanelControlState;

    /**
     * 面板部件输入参数
     *
     * @type {PanelControlProps}
     * @memberof PanelControl
     */
    public declare props: PanelControlProps;

    /**
     * 获取当前激活数据
     *
     * @return {*} 
     * @memberof PanelControl
     */
    public getData() {
        const { data } = toRefs(this.state);
        return [data.value];
    }

    /**
     * @description 处理导航数据模块
     * @protected
     * @memberof PanelControl
     */
    protected useNavDatas() {
        watch(() => this.props.navDatas, (newVal: any, oldVal: any) => {
            this.load();
        }, { immediate: true, deep: true });
    }

    /**
     * @description 数据加载
     * @protected
     * @param {IParam} [opts={}]
     * @memberof PanelControl
     */
    protected async load(opts: IParam = {}) { }

    /**
     * @description 使用数据加载模块
     * @memberof PanelControl
     */
    public useLoad() {
        const { viewSubject, controlName } = this.state;
        const load = async (opts: IParam = {}) => {
            const { dataMode } = this.state;
            const { navDatas } = toRefs(this.props);
            const { data } = toRefs(this.state);
            if (dataMode === 0) {
                //  不获取，使用传入数据
                if (navDatas && navDatas.value && navDatas.value.length) {
                    data.value = navDatas.value[0];
                }
            } else if (dataMode === 1) {
                //  存在传入数据时，不获取
                if (navDatas && navDatas.value && navDatas.value.length) {
                    data.value = navDatas.value[0];
                } else {
                    await this.loadPanelData(opts);
                }
            } else if (dataMode === 2) {
                //  始终获取
                await this.loadPanelData(opts);
            }
        }
        this.load = load;

        // 订阅viewSubject,监听load行为
        if (viewSubject) {
            let subscription = viewSubject.subscribe(({ tag, action, data }: IActionParam) => {
                if (Object.is(controlName, tag) && Object.is('load', action)) {
                    load(data);
                }
            });

            // 部件卸载时退订viewSubject
            onUnmounted(() => {
                subscription.unsubscribe();
            });
        }
        return load;
    }

    /**
     * 加载面板数据
     *
     * @private
     * @param {IParam} [opts={}]
     * @memberof PanelControl
     */
    private loadPanelData(opts: IParam = {}) {

    }

    /**
     * 处理面板项事件
     *
     * @protected
     * @param {IActionParam} actionParam
     * @memberof PanelControl
     */
    protected onPanelItemEvents(actionParam: IActionParam) {
        const { tag, action, data } = actionParam;
        switch (action) {
            case 'PanelButton':
                this.handleButtonAction(tag, data);
                break;
        }
    }

    /**
     * 处理按钮行为
     *
     * @private
     * @param {string} tag 按钮标识
     * @param {IParam} action 数据源
     * @memberof PanelControl
     */
    private handleButtonAction(tag: string, action: IParam) {
        if (!action) {
            console.warn("面板按钮执行参数不足");
            return;
        }
        const inputParam = {
            context: this.state.context,
            viewParams: this.state.viewParams,
            data: this.getData(),
            event: action.event,
            actionEnvironment: this
        }
        App.getAppActionService().execute(action, inputParam);
    }

    /**
     * @description 安装部件所有功能模块的方法
     * @return {*} 
     * @memberof PanelControl
     */
    public moduleInstall() {
        const superParams = super.moduleInstall();
        this.useLoad();
        this.useNavDatas();
        return {
            ...superParams,
            onPanelItemEvents: this.onPanelItemEvents.bind(this)
        }
    }

}