<template>
  <el-container class="app__container">
    <el-header class="app-header flex items-center">
      <el-icon v-show="mdLess" size="30" @click="showVerticalHeaderMenu = true">
        <icon-cs-menu />
      </el-icon>
      <router-link custom to="/" v-slot="{ navigate }">
        <el-icon size="50" @click="navigate"><icon-cs-club /></el-icon>
        <h3 v-show="showAppTitle" class="app__title" @click="navigate">社团展示系统</h3>
      </router-link>
      <header-menu v-show="!mdLess" mode="horizontal" />
      <el-dropdown v-if="!mdLess && userStore.logined">
        <header-user @login="onLoginButtonClick" @logout="logout" />
        <template #dropdown>
          <el-dropdown-menu>
            <el-dropdown-item :icon="CloseBold" @click="logout">退出登录</el-dropdown-item>
          </el-dropdown-menu>
        </template>
      </el-dropdown>
      <header-user v-else @login="onLoginButtonClick" @logout="logout" @click="onUserClick" />
    </el-header>
    <el-main class="app-main" v-loading="!!pageStore.pageLoadingCount">
      <el-container>
        <router-view v-slot="{ Component: comp }">
          <transition appear mode="out-in" name="app-router-view">
            <component class="app-router-component" :is="comp" />
          </transition>
        </router-view>
      </el-container>
    </el-main>
  </el-container>
  <login-register-dialog v-model="showLoginRegisterDialog" />
  <el-drawer
    class="app-vertical-drawer"
    v-model="showVerticalHeaderMenu"
    direction="ltr"
    size="250"
    :with-header="false"
  >
    <h3 v-show="!showAppTitle" class="app__title text-center">社团展示系统</h3>
    <header-user v-if="userStore.logined" @login="showLoginRegisterDialog = true" />
    <div v-else class="app-vertical-drawer__not-login-title flex justify-center items-center">
      尚未登录
    </div>
    <el-button
      v-if="userStore.logined"
      class="app-vertical-drawer__logout"
      type="primary"
      :icon="CloseBold"
      @click="logout"
    >
      退出登录
    </el-button>
    <header-menu mode="vertical" @select="showVerticalHeaderMenu = false" />
  </el-drawer>
</template>
<style lang="scss">
.app-vertical-drawer {
  --el-drawer-padding-primary: 0;
  .el-drawer__body {
    gap: 10px;
    display: flex;
    flex-direction: column;
  }
  > :first-child:not(.app-header-menu) {
    margin-top: 10px;
  }
  &__not-login-title {
    font-weight: bold;
  }
  &__logout {
    margin: 0 10px;
  }
}
</style>
<style lang="scss" scoped>
@use '@/assets/mixins' as m;
.app__container {
  min-height: 100vh;
}
.app-header {
  @include m.header(0);
  --el-loading-spinner-size: 30px;
  user-select: none;
  // 侧边栏需要居中
  .app-header-user {
    margin-left: auto;
  }
}
.app-main {
  --el-main-padding: 0 0 0 0;
  margin-top: var(--header-height);
  display: flex;
}
.app-router-component {
  --el-main-padding: 0;
}
.app-router-view-enter-active,
.app-router-view-leave-active {
  transition: opacity 0.25s ease;
}

.app-router-view-enter-from,
.app-router-view-leave-to {
  opacity: 0;
}
</style>
<script setup lang="ts">
import axiosInstance, { type RawResp } from '@/api/index';
import HeaderMenu from '@/components/app/HeaderMenu.vue';
import HeaderUser from '@/components/app/HeaderUser.vue';
import LoginRegisterDialog, {
  loginImplKey,
  registerImplKey,
} from '@/components/app/LoginRegisterDialog.vue';
import { useMediaStore } from '@/stores/media';
import { usePageStore } from '@/stores/page.js';
import { useUserStore } from '@/stores/user';
import { CloseBold } from '@element-plus/icons-vue';
import { useMediaQuery } from '@vueuse/core';
import type { AxiosError } from 'axios';
import { ElMessage } from 'element-plus';
import { storeToRefs } from 'pinia';
import { provide, ref, watch } from 'vue';
import { loginResponseSchema, registerResponseSchema } from './schemas/response';
const userStore = useUserStore();
const pageStore = usePageStore();
const { mdLess } = storeToRefs(useMediaStore());
const showAppTitle = useMediaQuery('(width >= 390px)');
const showLoginRegisterDialog = ref(false);
provide(loginImplKey, async (params) => {
  const loginRespRaw = await axiosInstance
    .post<RawResp>('/api/user/login', params)
    .then((r) => r.data)
    .catch((err: AxiosError) => {
      ElMessage.error([err.code, err.message].join(':'));
    });
  if (!loginRespRaw) return false;
  const resp = loginResponseSchema.parse(loginRespRaw);
  if (resp.type === 'error') {
    ElMessage.error([resp.code, resp.msg].join(':'));
    return false;
  }
  return userStore.updateSelfUserInfo(true);
});
provide(registerImplKey, async (params) => {
  const raw = await axiosInstance
    .put<RawResp>('/api/user/create', params)
    .then((r) => r.data)
    .catch((err: AxiosError) => {
      ElMessage.error([err.code, err.message].join(':'));
    });
  if (!raw) return false;
  const resp = registerResponseSchema.parse(raw);
  if (resp.type === 'error') {
    ElMessage.error([resp.code, resp.msg].join(':'));
    return false;
  }
  return userStore.updateSelfUserInfo(true);
});
async function logout() {
  showVerticalHeaderMenu.value = false;
  await userStore.logout();
}
const showVerticalHeaderMenu = ref(false);
watch(mdLess, (v) => {
  if (v) return;
  showVerticalHeaderMenu.value = false;
});
function onLoginButtonClick() {
  showLoginRegisterDialog.value = true;
}
function onUserClick() {
  showVerticalHeaderMenu.value = true;
}
// onMounted(() => {
//   userStore.token = null;
//   userStore.updateSelfUserInfo(true);
// });
</script>
