<script setup lang="ts">
import { ViewNeuron } from '@ibiz-template/controller';
import { useIndexViewController, useNamespace } from '@ibiz-template/vue-util';
import {
  computed,
  ComputedRef,
  getCurrentInstance,
  onMounted,
  Ref,
  ref,
} from 'vue';
import { createUUID } from 'qx-util';
import { useIndexRouteManage } from './index-view-default';
import { useIndexExpRouteManage } from './index-view-exp';
import '@ibiz-template/theme/style/components/views/index-view/index-view.scss';

interface IndexViewProps {
  context: IContext;
  params?: IParams;
  modelPath: string;
}

const props = withDefaults(defineProps<IndexViewProps>(), {
  params: () => ({}),
});

const { proxy } = getCurrentInstance()!;

const c = useIndexViewController(proxy, props.modelPath);

const isShowTabPageExp = ibiz.config.isShowTabPageExp; // to define

let onCreated: ((_neuron: ViewNeuron) => void) | null = null;
let onViewFound: ((_opts: IData) => void) | null = null;
let onMenuRouteChange: () => void = () => {};
let deleteRouteCache: ((_keys: string[]) => void) | null = null;
let handleTabClick: ((_index: number) => void) | null = null;
let handleTabDelete: ((_name: number) => void) | null = null;
let handleCloseAll: (() => void) | null = null;
let handleCloseOther: (() => void) | null = null;
let currentPath: ComputedRef<string> | undefined;
let currentKey: Ref<string>;
let keyHistory: Ref<string[]>;
let routeMsgs: Ref<
  {
    key: string;
    fullPath: string;
    modelPath?: string | undefined;
    caption?: string | undefined;
  }[]
>;
const appKeepAliveKey = ref(createUUID());

if (isShowTabPageExp) {
  const {
    currentKey: _currentKey,
    keyHistory: _keyHistory,
    routeMsgs: _routeMsgs,
    updateRouteMsg,
    closeView,
    deleteRouteCache: _deleteRouteCache,
    handleTabClick: _handleTabClick,
    handleTabDelete: _handleTabDelete,
    handleCloseAll: _handleCloseAll,
    handleCloseOther: _handleCloseOther,
  } = useIndexExpRouteManage(proxy, c);

  currentKey = _currentKey;
  keyHistory = _keyHistory;
  routeMsgs = _routeMsgs;
  deleteRouteCache = _deleteRouteCache;
  handleTabClick = _handleTabClick;
  handleTabDelete = _handleTabDelete;
  handleCloseAll = _handleCloseAll;
  handleCloseOther = _handleCloseOther;

  // 视图初始化，监听事件
  onCreated = (neuron: ViewNeuron) => {
    const key = currentKey.value;
    neuron.evt.on('closeView', () => {
      closeView(key);
    });
    neuron.evt.on('setTitle', (title: string) => {
      updateRouteMsg(key, { caption: title });
    });
  };

  onViewFound = (opts: IData) => {
    updateRouteMsg(currentKey.value, opts);
  };

  // 后退按钮触发事件,删除上一个路由的缓存
  window.onpopstate = () => {
    deleteRouteCache!([keyHistory.value[1]]);
  };

  currentPath = computed(() => {
    const routeMsg = routeMsgs.value.find(
      (item: { key: string }) => item.key === currentKey.value,
    );
    return routeMsg?.modelPath || '';
  });
} else {
  const {
    currentKey: _currentKey,
    keyHistory: _keyHistory,
    routeMsgs: _routeMsgs,
    updateRouteMsg,
    closeView,
    deleteRouteCache: _deleteRouteCache,
  } = useIndexRouteManage(proxy, c);

  currentKey = _currentKey;
  keyHistory = _keyHistory;
  routeMsgs = _routeMsgs;
  deleteRouteCache = _deleteRouteCache;

  // 视图初始化，监听事件
  onCreated = (neuron: ViewNeuron) => {
    const key = currentKey.value;
    neuron.evt.on('closeView', () => {
      closeView(key);
    });
    neuron.evt.on('setTitle', (title: string) => {
      updateRouteMsg(key, { caption: title });
    });
  };

  onViewFound = (opts: IData) => {
    updateRouteMsg(currentKey.value, opts);
  };

  onMenuRouteChange = () => {
    deleteRouteCache!(keyHistory.value.slice(1));
    appKeepAliveKey.value = createUUID();
  };

  // 后退按钮触发事件,删除上一个路由的缓存
  window.onpopstate = () => {
    deleteRouteCache!([keyHistory.value[1]]);
  };

  currentPath = computed(() => {
    const routeMsg = routeMsgs.value.find(
      (item: { key: string }) => item.key === currentKey.value,
    );
    return routeMsg?.modelPath || '';
  });
}

onMounted(() => {
  setTimeout(() => {
    const el = document.querySelector('.app-loading-x') as HTMLDivElement;
    if (el) {
      el.style.display = 'none';
    }
  }, 300);
});
const ns = useNamespace('index-view');
// 菜单收缩变化
const collapseChange = (collapse: boolean) => {
  c.collapseChange = collapse;
};
</script>

<template>
  <div :class="ns.b()">
    <AppLayout
      v-if="c.model?.source?.mainMenuAlign !== 'CENTER'"
      :is-complete="c.complete"
      :model="c.model"
      :class="c.model?.source?.mainMenuAlign?.toLowerCase()"
      :is-show-tab-page-exp="isShowTabPageExp"
      @onCollapseChange="collapseChange"
    >
      <template v-if="c.complete">
        <app-menu
          v-if="c.complete"
          slot="menu"
          :current-path="currentPath"
          :model-data="c.model.appMenu"
          :context="c.context"
          :collapse-change="c.collapseChange"
          :menu-model="c.model?.source"
          @menuRouteChange="onMenuRouteChange"
        ></app-menu>
        <tab-page-exp
          v-if="isShowTabPageExp"
          slot="tabPageExp"
          :route-msgs="routeMsgs"
          :current-key="currentKey"
          @tab-click="handleTabClick"
          @tab-delete="handleTabDelete"
          @close-all="handleCloseAll"
          @close-other="handleCloseOther"
        ></tab-page-exp>
        <AppKeepAlive
          v-if="!isShowTabPageExp"
          :key="appKeepAliveKey"
          :key-list="keyHistory"
        >
          <router-view
            :key="currentKey"
            @neuronInit="onCreated"
            @viewFound="onViewFound"
          />
        </AppKeepAlive>
        <AppKeepAlive v-else :key-list="keyHistory">
          <router-view
            :key="currentKey"
            @neuronInit="onCreated"
            @viewFound="onViewFound"
          />
        </AppKeepAlive>
      </template>
    </AppLayout>
    <div v-else>
      <app-menu
        v-if="c.complete"
        :current-path="currentPath"
        :model-data="c.model.appMenu"
        :context="c.context"
        :collapse-change="c.collapseChange"
        :menu-model="c.model?.source"
        @menuRouteChange="onMenuRouteChange"
      ></app-menu>
    </div>
  </div>
</template>
