<script setup lang="ts">
import { z } from 'zod'

const formSchema = z
  .object({
    username: z.string().trim().min(3, '用户名至少需要3个字符').max(30),
    password: z.string().min(8, '密码至少需要8个字符'),
    confirmPassword: z.string(),
    captchaText: z.string().min(1, '请输入验证码'),
  })
  .refine((data) => data.password === data.confirmPassword, {
    message: '两次输入的密码不一致',
    path: ['confirmPassword'],
  })

const state = reactive({
  username: '',
  password: '',
  confirmPassword: '',
  captchaText: '',
})

const captchaToken = ref('')
const captchaSvg = ref('')
const loading = ref(false)
const toast = useToast()

async function fetchCaptcha() {
  const res = await $fetch<{ code: number; data: { token: string; svg: string } }>(
    '/api/auth/captcha'
  )
  captchaToken.value = res.data.token
  captchaSvg.value = res.data.svg
}

async function onSubmit() {
  loading.value = true
  try {
    const res = await $fetch<{ code: number; message: string; data: unknown }>(
      '/api/auth/register',
      {
        method: 'POST',
        body: {
          username: state.username,
          password: state.password,
          confirmPassword: state.confirmPassword,
          captchaToken: captchaToken.value,
          captchaText: state.captchaText,
        },
      }
    )

    if (res.code !== 0) {
      toast.add({ title: res.message, color: 'error' })
      if (res.message.includes('验证码')) {
        fetchCaptcha()
        state.captchaText = ''
      }
      return
    }

    navigateTo('/login?registered=1')
  } catch {
    toast.add({ title: '注册失败，请稍后重试', color: 'error' })
  } finally {
    loading.value = false
  }
}

onMounted(fetchCaptcha)
</script>

<template>
  <div class="flex items-center justify-center py-8">
    <UCard class="w-full max-w-[380px]">
      <template #header>
        <h1 class="text-xl font-semibold">Create Account</h1>
        <p class="text-sm text-muted mt-1">Fill in the details to get started</p>
      </template>

      <UForm :state="state" :schema="formSchema" @submit="onSubmit">
        <UFormField name="username" label="Username" required class="mb-4">
          <UInput v-model="state.username" placeholder="Enter your username" />
        </UFormField>

        <UFormField name="password" label="Password" required class="mb-4">
          <UInput
            v-model="state.password"
            type="password"
            placeholder="At least 8 characters"
          />
        </UFormField>

        <UFormField name="confirmPassword" label="Confirm Password" required class="mb-4">
          <UInput
            v-model="state.confirmPassword"
            type="password"
            placeholder="Re-enter your password"
          />
        </UFormField>

        <UFormField name="captchaText" label="Captcha" required class="mb-4">
          <div class="flex gap-2 items-start">
            <!-- eslint-disable-next-line vue/no-v-html -->
            <div
              class="flex-1 h-10 border rounded-md overflow-hidden bg-[#f8f9fa]"
              v-html="captchaSvg"
            />
            <UButton
              variant="ghost"
              color="neutral"
              icon="i-lucide-refresh-cw"
              square
              @click="fetchCaptcha"
            />
          </div>
          <UInput
            v-model="state.captchaText"
            placeholder="Enter the code above"
            class="mt-2"
          />
        </UFormField>

        <UButton type="submit" block :loading="loading" class="mt-6">
          Create Account
        </UButton>
      </UForm>

      <template #footer>
        <p class="text-sm text-center text-muted">
          Already have an account?
          <NuxtLink to="/login" class="text-primary hover:underline">Log in</NuxtLink>
        </p>
      </template>
    </UCard>
  </div>
</template>
