import {
  defineComponent,
  getCurrentInstance,
  onUnmounted,
  ref,
  toRaw,
  watch,
} from 'vue';
import { ModelUtil } from '@ibiz-template/model';
import {
  parseRouteViewData,
  useRoute,
  useRouter,
} from '@ibiz-template/vue-util';
import { Route } from 'vue-router';
import { IBizContext } from '@ibiz-template/core';
import { ViewMode } from '@ibiz-template/runtime';

export default defineComponent({
  name: 'RouterShell',
  props: {
    level: {
      type: Number,
      default: 0,
    },
  },
  setup(props, ctx) {
    const { proxy } = getCurrentInstance()!;
    const router = useRouter(proxy);
    const viewData = ref<{
      viewPath?: string;
      viewType?: string;
      context?: IContext;
      params?: IParams;
      srfnav?: string;
    }>({});
    const isLoaded = ref(false);

    // 销毁视图上下文
    onUnmounted(() => {
      if (viewData.value.context) {
        const context = toRaw(viewData.value).context;
        if (context) context.destroy();
      }
    });

    // 视图初始化事件,往上抛
    const onNeuronInit = (...args: IData[]) => {
      ctx.emit('neuronInit', ...args);
    };

    const viewModal = {
      mode: ViewMode.ROUTE,
      level: props.level,
    };

    /** 计算视图是否有权限访问 */
    const calcViewAccess = (
      accUserMode?: number | 0 | 2 | 3 | 4,
      accessKey?: string,
    ) => {
      // 未指定直接返回true
      if (accUserMode === 0) {
        return true;
      }

      // 2:登录用户、 3:匿名用户及登录用户,看有没有用户登录
      const hasLogin = !!ibiz.appData?.context.srfuserid;
      if (accUserMode === 3 || accUserMode === 2) {
        return hasLogin;
      }

      // 登录用户且拥有指定资源能力,配了资源标识要有资源标识,否则看是否登录
      if (accUserMode === 4) {
        if (accessKey) {
          const unires: string[] = ibiz.appData?.unires;
          return hasLogin && unires.includes(accessKey);
        }
        return hasLogin;
      }

      return true;
    };

    // 根据应用模型解析视图参数
    const calcViewData = async () => {
      const service = await ModelUtil.getModelService();
      const appModel = service.app;
      if (appModel) {
        // 获取视图
        try {
          const route = useRoute(proxy) as Route;
          const _viewData = await parseRouteViewData(
            appModel,
            route,
            props.level,
          );

          const accessAble = calcViewAccess(
            _viewData.accUserMode,
            _viewData.accessKey,
          );
          if (!accessAble) {
            // 没权限跳转403页面
            router.push({ name: `403View${props.level}` });
            return;
          }

          const _context = IBizContext.create(_viewData.context);

          viewData.value = {
            ..._viewData,
            context: _context,
          };
          // 确定视图组件
          isLoaded.value = true;
          ctx.emit('viewFound', { modelPath: viewData.value.viewPath });
        } catch (error) {
          router.push({ name: `404View${props.level}` });
        }
      }
    };
    calcViewData();

    watch(
      () => proxy.$route.params.view1,
      () => {
        if (props.level === 1) {
          // 第一级路由壳监测到view1变化后,就重新计算一遍viewData
          calcViewData();
        }
      },
    );

    return {
      viewData,
      isLoaded,
      onNeuronInit,
      viewModal,
    };
  },
  render(h) {
    if (!this.isLoaded) {
      return null;
    }
    return h('ViewShell', {
      attrs: {
        context: this.viewData.context,
        params: this.viewData.params,
        modelPath: this.viewData.viewPath,
        srfnav: this.viewData.srfnav,
        modal: this.viewModal,
        isRouter: true,
      },
      key: this.viewData.viewPath,
      on: {
        neuronInit: this.onNeuronInit,
      },
    });
  },
});