<script lang="ts" setup>
import {useToast} from "#imports";

import Vcode from "vue3-puzzle-vcode";

definePageMeta({
  layout: 'login',
})
import * as Yup from 'yup';
import {Minus} from 'lucide-vue-next'
import type {HttpType} from "~/types/baseType";

const toast = useToast()
const form = reactive({
  username: '',
  nickname: '',
  email: '',
  phoneNumber: '',
  password: '',
  confirmPassword: '',
  remember: false
});
type FormErrorMessages = {
  [K in keyof typeof form]?: string;
};
const EmailDialog = ref(false);
const isShow = ref(false);
const errors = ref<FormErrorMessages>({});
const code = ref<string>();
const schema = Yup.object().shape({
  username: Yup.string()
      .required('用户名是必填项')
      .min(3, '用户名至少需要3个字符')
      .max(15, '用户名不能超过15个字符'),
  nickname: Yup.string()
      .max(15, '昵称不能超过15个字符')
      .required('昵称是必填项'),
  email: Yup.string()
      .email('邮箱地址格式不正确')
      .required('邮箱地址是必填项'),
  phoneNumber: Yup.string()
      .matches(/^1[3-9]\d{9}$/, '手机号码格式不正确'), // 这里使用了正则表达式匹配中国大陆的手机号码
  password: Yup.string()
      .required('密码是必填项')
      .min(6, '密码至少需要6个字符')
      .matches(/(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[!@#$%^&*()_+])[0-9a-zA-Z!@#$%^&*()_+]{6,}/, '密码必须包含字母、数字和至少一个特殊字符'),
  confirmPassword: Yup.string()
      .oneOf([Yup.ref('password')], '两次输入的密码必须一致')
      .required('请再次输入密码'),
  remember: Yup.boolean().oneOf([true], '请同意用户协议')
});

const handleSubmit = async () => {
  try {
    // 验证表单
    await schema.validate(form, {abortEarly: false});
    errors.value = {}; // 清空错误信息
    isShow.value = true;

  } catch (error) {
    // 处理验证错误
    if (error instanceof Yup.ValidationError) {
      const errorMessages: FormErrorMessages = {};
      error.inner.forEach((e) => {
        // 确保e.path是form对象的有效键
        if (e.path) {
          errorMessages[e.path as keyof typeof form] = e.message;
        }
      });
      errors.value = errorMessages;
    }
  }
};
const onSuccess = () => {
  // 表单验证通过，处理登录逻辑
  code.value = "";
  //请求验证码发送程序
  isShow.value = false;
  $fetch('/Api/Account/VerifyEmailName', {
    method: 'POST',
    body: {
      email: form.email,
      username: form.username
    },
    baseURL: useRuntimeConfig().public.baseUrl
  }).then(res => {
    const data = res as HttpType
    if (data.code === 200) {
      $fetch('/Api/Account/SendVerificationCode', {
        method: 'POST',
        body: {
          email: form.email
        },
        baseURL: useRuntimeConfig().public.baseUrl
      }).then(res => {
        toast.add({
          severity: 'success',
          summary: '验证码发送成功',
          detail: '请查收邮箱',
          life: 3000
        })
        EmailDialog.value = true;
      })
    } else {
      toast.add({
        severity: 'error',
        summary: data.message,
        detail: '错误',
        life: 3000
      })
    }
  })


};
const submitCode = () => {
  $fetch('/Api/Account/Register', {
    method: 'POST',
    body: {
      username: form.username,
      nickname: form.nickname,
      email: form.email,
      phone: form.phoneNumber,
      password: form.password,
      code: code.value
    },
    baseURL: useRuntimeConfig().public.baseUrl,
  }).then(res => {
    const data = res as HttpType<any>
    if (data.code === 200) {
      toast.add({
        severity: 'success',
        summary: '注册成功',
        detail: '即将跳转登录页面',
        life: 3000
      })
      setTimeout(() => {
        navigateTo('/SignIn')
      }, 1000)
    }
  })
}
</script>

<template>
  <div class="SignUp-Box">
    <Vcode :show="isShow" @success="onSuccess"/>
    <Dialog v-model:visible="EmailDialog" :style="{ width: '25rem' }" header="验证你的账户" modal>
      <div class="Email-Box">
        <h2>验证您的帐户</h2>
        <p>请输入发送到您邮箱的代码。</p>
        <div>
          <InputOtp v-model="code" :length="6" style="gap: 0">
            <template #default="{ attrs, events, index }">
              <input class="custom-otp-input" type="text" v-bind="attrs" v-on="events"/>
              <div v-if="index === 3" style="padding-inline: 5px">
                <Minus/>
              </div>
            </template>
          </InputOtp>
        </div>
        <div class="Email-Box-Action">
          <Button label="重新发送" link></Button>
          <Button label="提交验证码" @click.prevent="submitCode"></Button>
        </div>
      </div>
    </Dialog>
    <div class="SignUp-Box-Header">
      <h1>注册</h1>
      <h3>创建你的帐户</h3>
    </div>
    <div class="SignUp-Box-Form">
      <form @submit.prevent="handleSubmit">
        <div class="From-Item">
          <div class="From-Group">
            <label for="username">用户名</label>
            <InputText id="username" v-model="form.username" aria-describedby="username-help"/>
            <small id="username-help" class="p-error">{{ errors.username }}</small>
          </div>
          <div class="From-Group">
            <label for="nickname">昵称</label>
            <InputText id="nickname" v-model="form.nickname" aria-describedby="username-help"/>
            <small id="username-help" class="p-error">{{ errors.nickname }}</small>
          </div>
        </div>
        <div class="From-Item">
          <div class="From-Group">
            <label for="email">邮箱</label>
            <InputText id="email" v-model="form.email" aria-describedby="username-help"/>
            <small id="username-help" class="p-error">{{ errors.email }}</small>
          </div>
          <div class="From-Group">
            <label for="phoneNumber">手机号</label>
            <InputText id="phoneNumber" v-model="form.phoneNumber" aria-describedby="username-help"/>
            <small id="username-help" class="p-error">{{ errors.phoneNumber }}</small>
          </div>
        </div>
        <div class="From-Item">
          <div class="From-Group">
            <label for="password">密码</label>
            <Password id="password" v-model="form.password" toggleMask>
              <template #header>
                <h6>检查你的密码</h6>
              </template>
              <template #footer>
                <Divider/>
                <p>需求</p>
                <ul>
                  <li>至少一个特殊字符</li>
                  <li>至少一个字母</li>
                  <li>至少一个数字</li>
                  <li>至少6个字符</li>
                </ul>
              </template>
            </Password>
            <small id="username-help" class="p-error">{{ errors.password }}</small>
          </div>
          <div class="From-Group">
            <label for="confirmPassword">确认密码</label>
            <Password id="confirmPassword" v-model="form.confirmPassword" :feedback="false" aria-describedby="username-help"
                      toggleMask/>
            <small id="username-help" class="p-error">{{ errors.confirmPassword }}</small>
          </div>
        </div>
        <div class="From-Check">
          <div>
            <Checkbox v-model="form.remember" :binary="true" inputId="remember" name="remember"/>
            <label class="ml-2" for="remember"> 我同意使用条款</label>
            <small id="username-help" class="p-error">{{ errors.remember }}</small>
          </div>
        </div>
        <div class="From-Action">
          <Button label="注册" type="submit"/>
        </div>
      </form>
    </div>
    <div class="SignIn-Box-Bottom">
      <p>还是使用其他帐户登录？</p>
      <div>
        <NuxtImg height="40" src="/Gmail.svg" width="40"/>
        <NuxtImg height="40" src="/Facebook.svg" width="40"/>
        <NuxtImg height="40" src="/Instagram.svg" width="40"/>
        <NuxtImg height="40" src="/Linkedin.svg" width="40"/>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
@import "base";

.SignUp-Box {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: $gap*2;

  > * {
    transition: all 0.3s ease;
  }
}

.SignUp-Box-Header {
  display: flex;
  justify-content: center;
  flex-direction: column;
  align-items: center;
  gap: $gap*2;

  h3 {
    color: $unfocused-color;
    font-size: 16px;
    font-style: normal;
    font-weight: 400;
    line-height: 175%; /* 28px */
  }
}

.SignUp-Box-Form {
  display: flex;
  align-items: center;

  form {
    width: 100%;
    display: flex;
    gap: $gap*2;
    flex-direction: column;
  }
}

.Email-Box {
  display: flex;
  flex-direction: column;
  gap: $gap*2;
  justify-content: center;
  align-items: center;

  > p {
    color: $light-unfocused-color;
    font-size: 16px;
    margin-top: -10px;
  }

  .Email-Box-Action {
    display: flex;
    gap: $gap;
    width: 100%;

    > button {
      width: 100%;
    }
  }
}

.From-Item {
  display: flex;
  align-items: center;
  gap: $gap;
  justify-content: space-between;
}

.From-Group {
  display: flex;
  flex-direction: column;
  gap: $gap;

  small {
    max-height: 5px;
  }
}

.From-Group {
  display: flex;
  flex-direction: column;
  gap: $gap;
  width: 240px;

  label {
    color: $unfocused-color;
    font-size: 16px;
    font-style: normal;
    font-weight: 400;
    line-height: 175%; /* 28px */
  }
}

.From-Check {
  display: flex;
  justify-content: center;
  color: $unfocused-color;
}

.From-Action {
  display: flex;
  justify-content: center;
  margin-top: $padding*.5;

  .p-button {
    display: flex;
    width: 100%;
    padding: $padding*.75;
    justify-content: center;
    align-items: center;
    border-radius: $radius;
    background: $primary-color;
  }
}

.SignIn-Box-Bottom {
  display: flex;
  gap: $gap*2;
  flex-direction: column;
  align-items: center;
  justify-content: center;

  > p {
    color: $light-text-color;
    font-size: 16px;
  }

  > div {
    display: flex;
    height: 30px;
    overflow: hidden;
    gap: 24px;
  }
}

.custom-otp-input {
  width: 48px;
  height: 48px;
  font-size: 24px;
  appearance: none;
  text-align: center;
  border-radius: 0;
  border: 1px solid var(--surface-400);
  background: transparent;
  outline-offset: -2px;
  outline-color: transparent;
  border-right: 0 none;
  transition: outline-color 0.3s;
  color: var(--text-color);
}

.custom-otp-input:focus {
  outline: 2px solid var(--primary-color);
}

.custom-otp-input:first-child,
.custom-otp-input:nth-child(5) {
  border-top-left-radius: 12px;
  border-bottom-left-radius: 12px;
}

.custom-otp-input:nth-child(3),
.custom-otp-input:last-child {
  border-top-right-radius: 12px;
  border-bottom-right-radius: 12px;
  border-right-width: 1px;
  border-right-style: solid;

  border-color: var(--surface-400);
}


:deep(.p-input-icon) {
  top: 30%
}


//primeVue
:deep(.p-inputtext) {
  padding: $padding*.5 $padding;
  border-radius: $radius;
  width: 100%;
  border: 1px solid $primary-color;

  &:enabled:hover {
    border: 1px solid $primary-color;
    box-shadow: 0 0 0 2px $primary-color;
  }

  &:enabled:focus {
    outline: 2px solid $primary-color;
  }
}

:deep(.p-password-panel) {
  padding: $padding;
  background: red;
}

.dark-mode {
  h1, h2, h3, p {
    color: $dark-text-color;
  }
}

</style>