<template>
  <el-container>
    <el-header height="50px">
      <div class="title-container">社团展示系统</div>
      <div class="content">
        <div v-if="userStore.userInfo !== null" class="username">
          {{ userStore.userInfo.name }}
        </div>
        <el-dropdown v-if="userStore.userInfo !== null">
          <el-avatar :icon="userStore.userInfo.avatar || Avatar" :size="40"></el-avatar>
          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item :icon="CloseBold" @click="logout">退出登录</el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
        <el-avatar
          v-else
          style="color: black; user-select: none; cursor: pointer"
          :size="40"
          @click="showLoginRegisterDialog = true"
        >
          登录
        </el-avatar>
      </div>
    </el-header>
  </el-container>
  <el-dialog
    class="login-dialog"
    width="400"
    v-model="showLoginRegisterDialog"
    :align-center="true"
  >
    <el-tabs v-model="loginRegisterDialogActiveName">
      <el-tab-pane label="登录" name="login">
        <el-form ref="loginFormRef" :model="loginFormData" :rules="loginFormRules">
          <el-form-item prop="username">
            <el-input
              v-model="loginFormData.username"
              placeholder="请输入用户名"
              :disabled="logining"
            >
              <template #prepend>
                <el-icon><icon-ep-user-filled /></el-icon>
              </template>
            </el-input>
          </el-form-item>
          <el-form-item prop="password">
            <el-input
              v-model="loginFormData.password"
              type="password"
              placeholder="请输入密码"
              :disabled="logining"
            >
              <template #prepend>
                <el-icon><icon-cs-lock /></el-icon>
              </template>
            </el-input>
          </el-form-item>
          <el-form-item style="margin-bottom: 0">
            <el-button
              type="primary"
              style="width: 100%"
              @click="submitLoginForm"
              :loading="logining"
            >
              登录
            </el-button>
          </el-form-item>
        </el-form>
      </el-tab-pane>
      <el-tab-pane label="注册" name="register">
        <el-form ref="registerFormRef" :model="registerFormData" :rules="registerFormRules">
          <el-form-item prop="username">
            <el-input
              v-model="registerFormData.username"
              placeholder="请输入注册用户名"
              :disabled="registering"
            >
              <template #prepend>
                <el-icon><icon-ep-user-filled /></el-icon>
              </template>
            </el-input>
          </el-form-item>
          <el-form-item prop="password">
            <el-input
              v-model="registerFormData.password"
              type="password"
              placeholder="请输入密码"
              :disabled="registering"
            >
              <template #prepend>
                <el-icon><icon-cs-lock /></el-icon>
              </template>
            </el-input>
          </el-form-item>
          <el-form-item prop="confirmPassword">
            <el-input
              v-model="registerFormData.confirmPassword"
              type="password"
              placeholder="请确认密码"
              :disabled="registering"
            >
              <template #prepend>
                <el-icon><icon-cs-lock /></el-icon>
              </template>
            </el-input>
          </el-form-item>
          <el-form-item style="margin-bottom: 0">
            <el-button
              type="primary"
              style="width: 100%"
              @click="submitRegisterForm"
              :loading="registering"
            >
              注册
            </el-button>
          </el-form-item>
        </el-form>
      </el-tab-pane>
    </el-tabs>
  </el-dialog>
  <router-view />
</template>
<style scoped lang="scss">
.el-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid var(--el-border-color);
}
.content {
  display: flex;
  align-items: center;
}
.title-container {
  font-size: 1.2em;
}
.username {
  margin-right: 10px;
}
</style>
<script setup lang="ts">
import axiosInstance from '@/api';
import { loginResponseSchema, registerResponseSchema } from '@/schemas';
import { useUserStore } from '@/stores';
import { errorMessage, timeout } from '@/utils';
import { Avatar, CloseBold } from '@element-plus/icons-vue';
import { AxiosError } from 'axios';
import { type FormInstance, type FormRules, ElMessage } from 'element-plus';
import { partial, pick } from 'lodash-es';
import { onMounted, reactive, ref, watch } from 'vue';
import { RouterView, useRoute, useRouter } from 'vue-router';
import { z } from 'zod';
const router = useRouter();
const route = useRoute();
const userStore = useUserStore();
const showLoginRegisterDialog = ref(false);
watch(showLoginRegisterDialog, (value) => {
  if (value) {
    logining.value = false;
    loginFormRef.value?.resetFields();
    registering.value = false;
    registerFormRef.value?.resetFields();
  }
});
const loginRegisterDialogActiveName = ref('login');
const loginFormRef = ref<FormInstance>();
const loginFormData = reactive({
  username: 'wubaopu2',
  password: '123456'
});
const loginFormRules = reactive<FormRules<typeof loginFormData>>({
  username: [
    { required: true, message: '请输入用户名', trigger: 'blur' },
    { min: 6, message: '用户名长度不能小于3位', trigger: 'blur' }
  ],
  password: [
    { required: true, message: '请输入密码', trigger: 'blur' },
    { min: 6, message: '密码长度不能小于6位', trigger: 'blur' }
  ]
});
const logining = ref(false);
const registerFormRef = ref<FormInstance>();
const registerFormData = reactive({
  username: '',
  password: '',
  confirmPassword: ''
});
const registerFormRules = reactive<FormRules<typeof registerFormData>>({
  ...loginFormRules,
  confirmPassword: [
    {
      trigger: 'blur',
      validator: (_, value, callback) => {
        console.log(value);
        if (value === '') {
          callback('请输入密码');
        } else if (value !== registerFormData.password) {
          callback('密码不一致');
        } else if (value.length < 6) {
          callback('密码长度不能小于6位');
        } else {
          callback();
        }
      }
    }
  ]
});
const registering = ref(false);
const loginErrorMessage = partial(errorMessage, '登录');
interface LoginParams {
  username: string;
  password: string;
}
async function login(params: LoginParams = pick(loginFormData, 'username', 'password')) {
  try {
    const loginResp = loginResponseSchema.parse(
      (await axiosInstance.post('/api/user/login', params)).data
    );
    if (loginResp.type === 'error') {
      ElMessage.error(loginErrorMessage(loginResp.code, loginResp.msg));
      return false;
    }
    return true;
  } catch (e) {
    if (e instanceof AxiosError) {
      ElMessage.error(loginErrorMessage(e.code, e.message));
    } else if (e instanceof z.ZodError) {
      ElMessage.error('登录失败: 响应数据错误');
    }
    return false;
  }
}
async function submitLoginForm() {
  let succeed = false;
  logining.value = true;
  try {
    try {
      await loginFormRef.value?.validate();
    } catch (e) {
      return;
    }
    succeed = await login();
  } finally {
    if (succeed) {
      // await timeout(1000);
      window.location.reload();
    } else {
      logining.value = false;
    }
  }
}
const registerErrorMessage = partial(errorMessage, '注册');
async function register() {
  try {
    const registerResp = registerResponseSchema.parse(
      (
        await axiosInstance.put('/api/user/create', {
          username: registerFormData.username,
          password: registerFormData.password,
          auth: 1
        })
      ).data
    );
    if (registerResp.type === 'error') {
      ElMessage.error({
        message: registerErrorMessage(registerResp.code, registerResp.msg)
      });
      return false;
    }
    console.log(registerResp);
    return true;
  } catch (e) {
    if (e instanceof AxiosError) {
      ElMessage.error(registerErrorMessage(e.code, e.message));
    } else if (e instanceof z.ZodError) {
      ElMessage.error('注册失败: 响应数据错误');
    }
    console.log('error', e);
    return false;
  }
}
async function submitRegisterForm() {
  let succeed = false;
  registering.value = true;
  try {
    try {
      await registerFormRef.value?.validate();
    } catch {
      return;
    }
    succeed = await register();
  } finally {
    if (succeed) {
      window.location.reload();
    } else {
      registering.value = false;
    }
  }
}
async function logout() {
  userStore.$reset();
  await router.push('/');
  window.location.reload();
}
</script>
