<template>
  <el-dialog
    v-model="show"
    :fullscreen="smLess"
    align-center
    class="login-register-dialog"
    width="400"
  >
    <el-tabs
      class="login-register-dialog__tabs"
      :class="{ 'login-register-dialog__tabs--center': smLess }"
      stretch
      v-model="loginRegisterDialogActiveName"
    >
      <el-tab-pane label="登录" name="login">
        <el-form ref="loginFormRef" :model="loginFormData" :rules="loginFormRules" @submit.prevent>
          <el-form-item prop="username">
            <el-input
              v-model="loginFormData.username"
              :disabled="logining"
              placeholder="请输入用户名"
            >
              <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"
              :disabled="logining"
              placeholder="请输入密码"
              type="password"
            >
              <template #prepend>
                <el-icon>
                  <icon-cs-lock />
                </el-icon>
              </template>
            </el-input>
          </el-form-item>
          <el-form-item v-if="!DEV" prop="verifyCode">
            <verify-input v-model="loginFormData" :disabled="logining" />
          </el-form-item>
          <el-form-item style="margin-bottom: 0">
            <el-button
              :loading="logining"
              native-type="submit"
              style="width: 100%"
              type="primary"
              @click="submitLoginForm"
            >
              登录
            </el-button>
          </el-form-item>
        </el-form>
      </el-tab-pane>
      <el-tab-pane label="注册" name="register">
        <el-form
          ref="registerFormRef"
          :model="registerFormData"
          :rules="registerFormRules"
          @submit.prevent
        >
          <el-form-item prop="username">
            <el-input
              v-model="registerFormData.username"
              :disabled="registering"
              placeholder="请输入注册用户名"
            >
              <template #prepend>
                <el-icon>
                  <icon-cs-user />
                </el-icon>
              </template>
            </el-input>
          </el-form-item>
          <el-form-item prop="password">
            <el-input
              v-model="registerFormData.password"
              :disabled="registering"
              placeholder="请输入密码"
              type="password"
            >
              <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"
              :disabled="registering"
              placeholder="请确认密码"
              type="password"
            >
              <template #prepend>
                <el-icon>
                  <icon-cs-lock />
                </el-icon>
              </template>
            </el-input>
          </el-form-item>
          <el-form-item v-if="!DEV" prop="verifyCode">
            <verify-input v-model="registerFormData" :disabled="registering" />
          </el-form-item>
          <el-form-item>
            <el-button
              :loading="registering"
              native-type="submit"
              style="width: 100%"
              type="primary"
              @click="submitRegisterForm"
            >
              注册
            </el-button>
          </el-form-item>
        </el-form>
      </el-tab-pane>
    </el-tabs>
  </el-dialog>
</template>
<style lang="scss">
.login-register-dialog {
  &__tabs {
    &--center .el-tabs__nav-scroll {
      display: flex;
      justify-content: center;
    }
  }
  .el-form-item:last-child {
    margin-bottom: 0;
  }
}
</style>
<script lang="ts">
export interface LoginParams {
  username: string;
  password: string;
  key: string;
  code: string;
}
export interface RegisterParams extends LoginParams {
  auth: number;
}
export interface LoginRegisterDialogProps {
  handleLogin: (params: LoginParams) => Promise<boolean>;
  handleRegister: (params: RegisterParams) => Promise<boolean>;
}
export const minUsernameLength = 3;
export const minPasswordLength = minUsernameLength;
</script>
<script lang="ts" setup>
import VerifyInput, { type VerifyImagePath } from '@/components/app/VerifyInput.vue';
import { DEV } from '@/env';
import { useMediaStore } from '@/stores/media';
import { ElMessage, type FormInstance, type FormRules } from 'element-plus';
import { storeToRefs } from 'pinia';
import { reactive, ref, watch } from 'vue';
const { smLess } = storeToRefs(useMediaStore());
const { handleLogin, handleRegister } = defineProps<LoginRegisterDialogProps>();
const show = defineModel<boolean>({ default: false });
const loginRegisterDialogActiveName = ref('login');
const loginFormRef = ref<FormInstance>();
const loginFormData = reactive({
  username: 'wubaopu1',
  password: '123456',
  verifyImage: 'none' as VerifyImagePath,
  verifyCode: '',
});
watch(show, (show) => {
  if (!show) return;
  loginFormRef.value?.resetFields();
  registerFormRef.value?.resetFields();
});
const loginFormRules = reactive<FormRules<typeof loginFormData>>({
  username: [
    { required: true, message: '请输入用户名' },
    { min: minUsernameLength, message: `用户名长度不能小于${minUsernameLength}位` },
  ],
  password: [
    { required: true, message: '请输入密码' },
    { min: minPasswordLength, message: `密码长度不能小于${minPasswordLength}位` },
  ],
  verifyCode: [
    { required: !DEV, message: '请输入验证码' },
    { pattern: /^[0-9A-Za-z]{4}$/, message: '验证码不符合格式' },
  ],
});
const logining = ref(false);
async function submitLoginForm() {
  try {
    await loginFormRef.value?.validate();
  } catch (e) {
    return;
  }
  let key: string;
  if (typeof loginFormData.verifyImage === 'string') {
    if (!DEV) {
      ElMessage.error('请获取验证码');
      return;
    }
    key = '';
  } else {
    ({ key } = loginFormData.verifyImage);
  }
  logining.value = true;
  try {
    const { username, password, verifyCode: code } = loginFormData;
    if (!(await handleLogin({ username, password, key, code }))) return;
    ElMessage.success('登录成功');
    show.value = false;
  } finally {
    loginFormData.verifyImage = 'none';
    loginFormRef.value?.resetFields('verifyCode');
    logining.value = false;
  }
}

const registerFormRef = ref<FormInstance>();
const registerFormData = reactive({
  username: '',
  password: '',
  confirmPassword: '',
  verifyImage: 'none' as VerifyImagePath,
  verifyCode: '',
});
const registerFormRules = reactive<FormRules<typeof registerFormData>>({
  ...loginFormRules,
  confirmPassword: [
    {
      validator(_, value, callback) {
        if (value === '') {
          callback('请输入密码');
        } else if (value !== registerFormData.password) {
          callback('密码不一致');
        } else if (value.length < minPasswordLength) {
          callback(`密码长度不能小于${minPasswordLength}位`);
        } else {
          callback();
        }
      },
    },
  ],
});
const registering = ref(false);
async function submitRegisterForm() {
  try {
    await registerFormRef.value?.validate();
  } catch {
    return;
  }
  let key: string;
  if (typeof registerFormData.verifyImage === 'string') {
    if (!DEV) {
      ElMessage.error('请获取验证码');
      return;
    }
    key = '';
  } else {
    ({ key } = registerFormData.verifyImage);
  }
  registering.value = true;
  try {
    const { username, password, verifyCode: code } = registerFormData;
    if (!(await handleRegister({ username, password, code, key, auth: 1 }))) return;
    ElMessage.success('注册成功');
    show.value = false;
  } finally {
    registerFormData.verifyImage = 'none';
    registerFormRef.value?.resetFields('verifyCode');
    registering.value = false;
  }
}
</script>
