<script setup lang="ts">
import type { ActionSheetProps, PopoverProps } from 'vant';
import type { MenuModel } from '@/request/model/manage.model';
import { tryOnBeforeMount } from '@vueuse/core';
import { useRequest } from 'alova/client';
import { getApplicationMethod } from '@/request/api';
import { useAccountStore } from '@/stores';
import { startDirective, useStart } from '@/composables/start';
import { useUpdatePassword } from '@/modules/system/useUpdatePassword';

const { data } = useRequest(getApplicationMethod, { initialData: { image: { copyright: '' } } });
const title = computed(() => data.value.image.title || import.meta.env.SIX_APP_TITLE);
const copyright = computed(() => data.value.copyright);

const Account = useAccountStore();
const { loading, menus, token } = storeToRefs(Account);
const router = useRouter();
tryOnBeforeMount(() => {
  if (!unref(token)) router.replace({ name: 'login' });
});

/** 右上角菜单 */
const settingProps = reactive<Partial<PopoverProps> & { onSelect: any }>({
  placement: 'bottom-end',
  theme: 'dark',
  closeOnClickAction: true,
  actions: [
    {
      text: '重置密码',
      async callback() {
        const pid = unref(Account.user)?.id;
        if (pid && (await password.open({ pid }))) logout().then();
      },
    },
    {
      text: '退出登录',
      async callback() {
        await showConfirmDialog({ title: '退出登录' });
        await logout();
      },
    },
  ],
  onSelect(action: any) {
    action?.callback?.();
  },
});
const logout = async () => {
  await router.replace({ path: '/login' });
  Account.logout();
};

const vStart = startDirective;
const { handle: start, extra } = useStart(true);

const route = useRoute();
const menuActionSheetProps = reactive<Partial<ActionSheetProps>>({
  title: '',
  cancelText: '关闭',
  closeable: false,
  actions: [],
  closeOnClickAction: true,
});
const handle = (menu: MenuModel) => {
  if (menu.children && menu.children.length > 0) {
    menuActionSheetProps.actions = menu.children.map((child) => ({
      name: child.meta.title,
      icon: child.meta.icon,
      callback: () => handle(child),
    }));
    menuActionSheetProps.title = menu.meta.title;
    menuActionSheetProps.show = true;
  } else if (menu.path === route.path) start();
  else router.push({ path: menu.path, query: { title: menu.meta.title } });
};

const [Password, password] = useUpdatePassword();
</script>

<template>
  <div class="page-container">
    <div class="page-header flex py-4 px-4 overflow-hidden">
      <div class="grow shrink-0 h-full min-w-16"></div>
      <div class="grow-[3] shrink mx-2 flex flex-col justify-center overflow-hidden"></div>
      <div class="grow shrink-0 h-full min-w-16 flex items-center justify-end overflow-hidden">
        <van-popover v-bind="settingProps">
          <template #reference>
            <van-icon name="setting-o" style="font-size: 32px" />
          </template>
        </van-popover>
      </div>
    </div>
    <div class="page-content flex flex-col">
      <div class="flex-none h-[106px]">
        <div class="h-full flex justify-center items-center text-4xl" style="letter-spacing: 0.2em">{{ title }}</div>
      </div>
      <div class="flex-auto flex justify-center items-center">
        <div v-if="loading" class="menu-loading">
          <van-loading size="24px" vertical>加载中...</van-loading>
        </div>
        <van-empty v-else-if="!menus.length" class="menu-empty" description="请联系管理员添加菜单" style="" />
        <van-grid v-else class="flex-auto max-h-[60vh] overflow-y-auto" direction="horizontal" :column-num="1" clickable gutter="24">
          <van-grid-item v-for="menu in menus" :key="menu.id" :icon="menu.meta.icon" :text="menu.meta.title" v-start="extra" @click="handle(menu)" />
        </van-grid>
        <van-action-sheet v-bind="menuActionSheetProps" v-model:show="menuActionSheetProps.show" />
      </div>
      <div class="flex-none text-xl p-2 text-center tracking-widest" v-html="copyright"></div>
    </div>
    <Password />
  </div>
</template>

<style scoped lang="scss">
.menu-loading {
  --van-loading-text-font-size: 24px;
  --van-loading-spinner-color: hsl(var(--primary-hover) / 1);
  --van-loading-text-color: hsl(var(--primary-hover) / 0.5);
}
.menu-empty {
  --van-empty-description-font-size: 24px;
  --van-empty-description-color: hsl(var(--primary-hover) / 0.5);
}
.van-grid {
  --van-grid-item-text-font-size: 1.25rem;
}
</style>
