import { IPSAppMenu } from '@ibizstudio-ex/runtime';
import { AuthServiceBase, LogUtil, MenuControlInterface, Util } from '@ibizstudio-ex/runtime';
import { ControlBase } from "./control-base";
import { AppFuncService, NavDataService } from '../app-service';
import { AppMenuService } from "../ctrl-service";

/**
 * 菜单部件基类
 *
 * @export
 * @class AppMenuControlBase
 * @extends {ControlBase}
 */
export class AppMenuControlBase extends ControlBase implements MenuControlInterface {

    /**
     * 菜单部件实例
     *
     * @memberof AppMenuControlBase
     */
    declare controlInstance: IPSAppMenu;

    /**
     * 部件名称
     *
     * @memberof AppMenuControlBase
     */
    declare name: string;

    /**
     * 显示处理提示
     *
     * @memberof AppMenuControlBase
     */
    showBusyIndicator: boolean = true;

    /**
     * 视图参数
     *
     * @type {*}
     * @memberof AppMenuControlBase
     */
    declare viewparams: any;

    /**
     * 应用上下文
     *
     * @type {*}
     * @memberof AppMenuControlBase
     */
    declare context: any;

    /**
     * 菜单收缩改变
     *
     * @type {boolean}
     * @memberof AppMenuControlBase
     */
    collapseChange!: boolean;

    /**
     * 当前模式，菜单在顶部还是在底部
     *
     * @type {*}
     * @memberof AppMenuControlBase
     */
    mode!: string;

    /**
     * 当前选中主题
     *
     * @type {*}
     * @memberof AppMenuControlBase
     */
    selectTheme!: string;

    /**
     * 默认激活的index
     *
     * @type {*}
     * @memberof AppMenuControlBase
     */
    defaultActive: any = null;

    /**
     * 触发方式，默认click
     *
     * @type {string}
     * @memberof AppMenuControlBase
     */
    trigger: string = 'click';

    /**
     * 默认打开的index数组
     *
     * @type {any[]}
     * @memberof AppMenuControlBase
     */
    defaultOpeneds: any[] = [];

    /**
     * 应用起始页面
     *
     * @type {boolean}
     * @memberof AppMenuControlBase
     */
    isDefaultPage: boolean = false;

    /**
     * 空白视图模式
     *
     * @type {boolean}
     * @memberof AppMenuControlBase
     */
    isBlankMode: boolean = false;

    /**
     * 应用导航服务
     *
     * @type {*}
     * @memberof AppMenuControlBase
     */
    navDataService: NavDataService = NavDataService.getInstance(this.$store);

    /**
     * 默认打开视图
     *
     * @type {boolean}
     * @memberof AppMenuControlBase
     */
    defPSAppView: any;

    /**
     * 计数器数据
     *
     * @type {*}
     * @memberof AppMenuControlBase
     */
    counterdata: any;

    /**
     * 菜单模型
     *
     * @public
     * @type
     * @memberof AppMenuControlBase
     */
    menuMode: any;

    /**
     * 菜单数据
     *
     * @public
     * @type {any[]}
     * @memberof AppMenuControlBase
     */
    menus: any[] = [];

    /**
     * 建构权限服务对象
     *
     * @type {AuthService}
     * @memberof AppMenuControlBase
     */
    authService!: AuthServiceBase;

    /**
     * 提示框主题样式
     *
     * @type {string}
     * @memberof AppMenuControlBase
     */
    popperClass(): string {
        return 'app-popper-menu ' + this.selectTheme;
    }

    /**
     * 监听部件动态参数变化
     *
     * @param {*} newVal
     * @param {*} oldVal
     * @memberof AppMenuControlBase
     */
    onDynamicPropsChange(newVal: any, oldVal: any) {
        super.onDynamicPropsChange(newVal, oldVal);
        this.collapseChange = newVal.collapseChange;
        this.$forceUpdate();
    }

    /**
     * 监听部件参数变化
     *
     * @param {*} newVal
     * @param {*} oldVal
     * @memberof AppMenuControlBase
     */
    onStaticPropsChange(newVal: any, oldVal: any) {
        this.mode = newVal.mode ? newVal.mode : 'LEFT';
        this.selectTheme = newVal.selectTheme;
        this.isDefaultPage = newVal.isDefaultPage ? newVal.isDefaultPage : this.isDefaultPage;
        this.isBlankMode = newVal.isBlankMode ? newVal.isBlankMode : this.isBlankMode;
        this.defPSAppView = newVal.defPSAppView;
        this.counterdata = newVal.counterdata;
        super.onStaticPropsChange(newVal, oldVal)
    }

    /**
     * 部件模型数据初始化
     *
     * @memberof AppMenuControlBase
     */
    async ctrlModelInit(args?: any) {
        await super.ctrlModelInit();
        this.service = new AppMenuService(this.controlInstance, this.context);
        await this.service.initServiceParam(this.context, this.controlInstance);
    }

    /**
     * 应用菜单初始化
     *
     * @memberof AppMenuControlBase
     */
    ctrlInit(args?: any) {
        super.ctrlInit();
        let _this: any = this;
        this.authService = new AuthServiceBase({ $store: _this.$store })
    }

    viewStateAction(tag: string, action: string, data: any) {
      if (!Object.is(tag, this.name)) {
        return;
      }
      super.viewStateAction(tag, action, data);
      this.load();
    }

    /**
     * 数据加载
     *
     * @memberof AppMenuControlBase
     */
    load() {
        this.handleMenusResource(this.service.getAllMenuItems());
        this.isControlLoaded = true;
    }

    /**
     * 菜单项选中处理
     *
     * @param {menuName } 选中菜单名称
     * @returns
     * @memberof AppMenuControlBase
     */
    select(menuName: any) {
        let item = this.compute(this.menus, menuName);
        if (Object.keys(item).length === 0) {
            return;
        }
        this.click(item);
    }

    /**
     * 处理菜单默认选中项
     *
     * @public
     * @memberof AppMenuControlBase
     */
    defaultMenuSelect(): void {
        if (!this.isDefaultPage || this.isBlankMode) {
            return;
        }
        const appFuncs: Array<any> = this.service.getAllFuncs();
        if (this.$route && this.$route.matched && this.$route.matched.length == 2) { // 存在二级路由
            const [{ }, matched] = this.$route.matched;
            const appfunc: any = appFuncs?.find((_appfunc: any) => Object.is(_appfunc.routepath, matched.path) && Object.is(_appfunc.appfunctype, 'APPVIEW'));
            if (appfunc) {
                this.computeMenuSelect(this.menus, appfunc.appfunctag);
            }
            return;
        } else if (this.defPSAppView && Object.keys(this.defPSAppView).length > 0) { // 存在默认视图
            const appfunc: any = appFuncs?.find((_appfunc: any) => Object.is(_appfunc.routepath, this.defPSAppView.routepath) && Object.is(_appfunc.appfunctype, 'APPVIEW'));
            if (appfunc) {
                this.computeMenuSelect(this.menus, appfunc.appfunctag);
            }
            const viewparam: any = {};
            const path: string = this.$viewTool.buildUpRoutePath(this.$route, {}, this.defPSAppView.deResParameters, this.defPSAppView.parameters, [], viewparam);
            this.$router.push(path);
            return;
        }
        this.computeMenuSelect(this.menus, '');
        let item = this.compute(this.menus, this.defaultActive);
        if (Object.keys(item).length === 0) {
            return;
        }
        if (!item.hidden) {
            this.click(item);
        }
    }

    /**
     * 计算菜单选中项
     *
     * @public
     * @param {Array<any>} items 菜单数据
     * @param {string} appfunctag 应用功能tag
     * @return {*}  {boolean}
     * @memberof AppMenuControlBase
     */
    computeMenuSelect(items: Array<any>, appfunctag: string): boolean {
        const appFuncs: Array<any> = this.service.getAllFuncs();
        return items.some((item: any) => {
            if (Object.is(appfunctag, '') && item.getPSAppFunc && item.openDefault && !item.hidden) {
                const appfunc = appFuncs?.find((_appfunc: any) => Object.is(_appfunc.appfunctag, item.getPSAppFunc.codeName));
                if (appfunc) {
                    this.defaultActive = item.name;
                    this.setHideSideBar(item);
                    return true;
                }
            }
            if (item.getPSAppFunc && Object.is(item.getPSAppFunc.codeName, appfunctag)) {
                this.setHideSideBar(item);
                this.defaultActive = item.name;
                return true;
            }
            if (item.getPSAppMenuItems && item.getPSAppMenuItems.length > 0) {
                const state = this.computeMenuSelect(item.getPSAppMenuItems, appfunctag);
                if (state) {
                    this.defaultOpeneds.push(item.name);
                    return true;
                }
            }
            return false;
        });
    }

    /**
     * 获取菜单项数据
     *
     * @public
     * @param {any[]} items
     * @param {string} name
     * @returns
     * @memberof AppMenuControlBase
     */
    compute(items: any[], name: string) {
        const item: any = {};
        items.some((_item: any) => {
            if (name && Object.is(_item.name, name)) {
                Object.assign(item, _item);
                this.setHideSideBar(_item);
                return true;
            }
            if (_item.getPSAppMenuItems && Array.isArray(_item.getPSAppMenuItems)) {
                const subItem = this.compute(_item.getPSAppMenuItems, name);
                if (Object.keys(subItem).length > 0) {
                    Object.assign(item, subItem);
                    return true;
                }
            }
            return false;
        });
        return item;
    }

    /**
     * 设置是否隐藏菜单栏
     *
     * @public
     * @param {*} item
     * @memberof AppMenuControlBase
     */
    setHideSideBar(item: any): void {
        if (this.isDefaultPage && item.hidesidebar) {
            this.$emit('collapsechange', true);
        }
    }

    /**
     * 菜单点击
     *
     * @param {*} item 点击项
     * @memberof AppMenuControlBase
     */
    click(item: any) {
        if (Object.is((this.controlInstance as any)?.parentModel?.viewStyle, 'STYLE4') && (!this.mode || Object.is(this.mode, 'LEFT'))) {
            this.$store.commit('removeAllPage');
            this.navDataService.removeNavDataFrist();
        }
        let tempContext: any = Util.deepCopy(this.context);
        if (item.getPSNavigateContexts) {
            const localContext = Util.formatNavParam(item.getPSNavigateContexts);
            Object.assign(tempContext, localContext);
        } else {
            if (tempContext.hasOwnProperty("srfdynainstid")) {
                delete tempContext.srfdynainstid;
            }
        }
        if (item.getPSAppFunc) {
            const appFuncs: Array<any> = this.service.getAllFuncs();
            const appFunc = appFuncs.find((element: any) => {
                return element.appfunctag === item.getPSAppFunc.codeName;
            });
            if (appFunc) {
                AppFuncService.getInstance().executeApplication(appFunc, tempContext);
            }
        } else {
            LogUtil.warn(this.$t('app.commonwords.noassign'));
        }
    }

    /**
     * 通过统一资源标识计算菜单
     *
     * @param {*} data
     * @memberof AppMenuControlBase
     */
    handleMenusResource(inputMenus: Array<any>) {
        let _this: any = this;
        if (_this.$store.getters['authresource/getEnablePermissionValid']) {
            this.computedEffectiveMenus(inputMenus);
            // this.computeParentMenus(inputMenus);
        }
        this.dataProcess(inputMenus);
        this.menus = inputMenus;
        this.defaultMenuSelect();
    }

    /**
     * 计算有效菜单项
     *
     * @param {*} inputMenus
     * @memberof AppMenuControlBase
     */
    computedEffectiveMenus(inputMenus: Array<any>) {
        inputMenus.forEach((_item: any) => {
            if (!this.authService.getMenusPermission(_item)) {
                _item.hidden = true;
            }
            if (_item.getPSAppMenuItems && _item.getPSAppMenuItems.length > 0) {
                this.computedEffectiveMenus(_item.getPSAppMenuItems);
            }
        })
    }

    /**
     * 数据处理
     *
     * @public
     * @param {any[]} items
     * @memberof AppMenuControlBase
     */
    dataProcess(items: any[]): void {
        items.forEach((_item: any) => {
            if (_item.expanded) {
                this.defaultOpeneds.push(_item.name);
            }
            if (_item.getPSAppMenuItems && _item.getPSAppMenuItems.length > 0) {
                this.dataProcess(_item.getPSAppMenuItems)
            }
        });
    }

    /**
     * @description 处理关闭菜单
     * @param {*} key 菜单项标识
     * @param {*} keyPath 标识集合
     * @memberof AppMenuControlBase
     */
    handleCloseMenu(key: any, keyPath: any){
      const refs: any = this.$refs;
      if (refs[this.controlInstance?.codeName] && refs[this.controlInstance?.codeName].close instanceof Function) {
        refs[this.controlInstance?.codeName].close(key);
      }
    }
}