import { IPSAppDataEntity, IPSAppIndexView, IPSAppView, IPSLanguageRes, IPSSysImage } from '@ibiz/dynamic-model-api';
import { AppServiceBase, EntityPathService, LogUtil, Util } from 'ibiz-core';
import { isNilOrEmpty } from 'qx-util';
import { Component, Emit, Prop } from 'vue-property-decorator';
import { AppViewShell } from './app-view-shell';
import { ViewContainerBase } from './view-container-base';

/**
 * 视图壳
 *
 * @export
 * @class AppIndexViewShell
 * @extends {ViewContainerBase}
 */
@Component({})
export class AppIndexViewShell extends ViewContainerBase {
  /**
   * 数据变化
   *
   * @param {*} val
   * @returns {*}
   * @memberof AppIndexViewShell
   */
  @Emit()
  viewDatasChange(val: any): any {
    return val;
  }

  /**
   * 视图静态参数
   *
   * @type {string}
   * @memberof AppIndexViewShell
   */
  @Prop() declare staticProps: any;

  /**
   * 视图动态参数
   *
   * @type {string}
   * @memberof AppIndexViewShell
   */
  @Prop() declare dynamicProps: any;

  /**
   * 组件初始化
   *
   * @memberof AppIndexViewShell
   */
  created() {
    // 挂载动态路由
    this.mountedDynaRoute(this.$router);
    // 跳转重定向来源路由
    if (AppServiceBase.getInstance().getRedirectedFromRoute()) {
      this.$router.push(AppServiceBase.getInstance().getRedirectedFromRoute());
    }
    const currentParams = this.$route.params;
    let targetIndexView: IPSAppView | undefined = undefined;
    const APP = AppServiceBase.getInstance().getAppModelDataObject();
    if (APP && APP.getAllPSAppViews()) {
      // 多首页 eg：http://localhost:9090/#/index/initiateindexview
      if (currentParams && currentParams.index) {
        targetIndexView = (APP.getAllPSAppViews() as IPSAppView[]).find((view: IPSAppView) => {
          if (view.refM && view.refM.viewType && view.refM.path) {
            return view.refM.viewType === 'APPINDEXVIEW' && view.refM.path.toLowerCase().endsWith(`${currentParams.index}.json`);
          } else {
            return view.viewType === 'APPINDEXVIEW' && view.codeName.toLowerCase() === currentParams.index;
          }
        });
      }
      // 正常启动应用首页视图 eg：http://localhost:9090
      if (!targetIndexView) {
        targetIndexView = (APP.getAllPSAppViews() as IPSAppView[]).find((view) => {
          return view.viewType === 'APPINDEXVIEW' && (view as IPSAppIndexView).defaultPage;
        })
      }
    }
    if (!targetIndexView) {
      this.$throw('未找到应用首页视图且为应用起始视图');
    } else {
      // 计算首页动态模型地址及加载模型数据
      targetIndexView.fill().then((indexView: any) => {
        const indexRoute = this.$router.getRoutes().find((route: any) => {
          return route.name === 'index';
        })
        if (indexRoute && indexRoute.meta) {
          if(indexView.caption){
            indexRoute.meta.caption = indexView.caption;
            document.title = indexView.caption;
          }
          if (indexView.getCapPSLanguageRes()) {
            indexRoute.meta.captionTag = (indexView.getCapPSLanguageRes() as IPSLanguageRes).lanResTag;
          }
          if (indexView.getPSSysImage()) {
            indexRoute.meta.imgPath = (indexView.getPSSysImage() as IPSSysImage).imagePath;
            indexRoute.meta.iconCls = (indexView.getPSSysImage() as IPSSysImage).cssClass;
          }
        }
        this.dynaModelFilePath = indexView.modelPath as string;
        this.loadDynamicModelData();
      })
    }
  }

  /**
   * @description 视图销毁
   * @memberof AppIndexViewShell
   */
  destroyed() {
    super.destroyed();
  }

  /**
   * 挂载动态路由
   *
   * @param {*} router 路由对象
   * @memberof AppIndexViewShell
   */
  public mountedDynaRoute(router: any) {
    if (router && router.getRoutes().length > 0) {
      const indexView = router.getRoutes().find((route: any) => {
        return route.meta && route.meta.viewType && route.meta.viewType === 'APPINDEX';
      })
      if (indexView) {
        const indexPath: string = indexView.name;
        this.mountedAllEntityRoute(indexPath, router);
        // 挂载应用视图路由
        const appRoute = {
          path: 'views/:view?',
          meta: {
            captionTag: '',
            caption: '',
            info: '',
            imgPath: '',
            iconCls: '',
            parameters: [
              { pathName: indexPath, parameterName: indexPath },
              { pathName: 'views', parameterName: 'view' },
            ],
            requireAuth: false,
          },
          component: AppViewShell,
        }
        router.addRoute(indexPath, appRoute);
        LogUtil.log('挂载应用动态路由完成');
      }
    }
  }

  /**
   * 挂载所有应用实体映射路由
   *
   * @param {string} indexPath 首页路径
   * @param {*} router 路径对象
   * @memberof AuthGuard
   */
  public mountedAllEntityRoute(indexPath: string, router: any) {
    const APP = AppServiceBase.getInstance().getAppModelDataObject();
    if (APP.getAllPSAppDataEntities() && (APP.getAllPSAppDataEntities() as IPSAppDataEntity[]).length > 0) {
      (APP.getAllPSAppDataEntities() as IPSAppDataEntity[]).forEach((appDataEntity: IPSAppDataEntity) => {
        let codeName: string = '';
        if (appDataEntity.refM && appDataEntity.refM.codeName) {
          codeName = appDataEntity.refM.codeName;
        } else {
          codeName = appDataEntity.codeName;
        }
        const resPaths = new EntityPathService(codeName).getPSAppDERSPaths();
        this.mountedSingleEntityRoute(indexPath, router, codeName, resPaths);
      })
    }
  }

  /**
   * 初始化单个应用实体映射路由
   *
   * @param {string} indexPath 首页路径
   * @param {*} router 路径对象
   * @param {string} codeName 当前应用实体代码名称
   * @param {string[][]} resPaths 当前应用实体关联路径
   * @memberof AuthGuard
   */
  public mountedSingleEntityRoute(indexPath: string, router: any, codeName: string, resPaths: string[][]) {
    // 挂载关系路由
    if (resPaths && resPaths.length > 0) {
      resPaths.forEach((singleResPaths: string[]) => {
        if (singleResPaths && singleResPaths.length > 0) {
          let currentPath: string = '';
          let currentParameters: any = [
            { pathName: indexPath.toLowerCase(), parameterName: indexPath.toLowerCase() }
          ];
          singleResPaths.forEach((resPath: string) => {
            currentPath += `/${Util.srfpluralize(resPath).toLowerCase()}/:${resPath.toLowerCase()}?`;
            currentParameters.push({ pathName: Util.srfpluralize(resPath).toLowerCase(), parameterName: resPath.toLowerCase() });
          })
          currentPath = `${currentPath.slice(1)}/${Util.srfpluralize(codeName).toLowerCase()}/:${codeName.toLowerCase()}?/views/:view?`;
          currentParameters.push({ pathName: Util.srfpluralize(codeName).toLowerCase(), parameterName: codeName.toLowerCase() }, { pathName: 'views', parameterName: 'view' });
          const route = {
            path: currentPath,
            meta: {
              captionTag: '',
              caption: '',
              info: '',
              imgPath: '',
              iconCls: '',
              parameters: currentParameters,
              resource: codeName.toLowerCase(),
              requireAuth: false,
            },
            component: AppViewShell
          }
          router.addRoute(indexPath, route);
        }
      })
    }
    // 挂载自身路由
    const route = {
      path: `${Util.srfpluralize(codeName).toLowerCase()}/:${codeName.toLowerCase()}?/views/:view?`,
      meta: {
        captionTag: '',
        caption: '',
        info: '',
        imgPath: '',
        iconCls: '',
        parameters: [
          { pathName: indexPath.toLowerCase(), parameterName: indexPath.toLowerCase() },
          { pathName: Util.srfpluralize(codeName).toLowerCase(), parameterName: codeName.toLowerCase() },
          { pathName: 'views', parameterName: 'view' },
        ],
        resource: codeName.toLowerCase(),
        requireAuth: false,
      },
      component: AppViewShell
    }
    router.addRoute(indexPath, route);
  }

  /**
   * 绘制
   *
   * @param {*} h
   * @return {*} 
   * @memberof AppIndexViewShell
   */
  render(h: any) {
    if (isNilOrEmpty(this.viewContainerName)) {
      return;
    }
    return h(this.viewContainerName, {
      props: { dynamicProps: this.dynamicProps, staticProps: this.viewContext },
      on: {
        'view-event': this.handleViewEvent.bind(this),
      },
    });
  }
}