<script setup lang="ts">
import type { AuthFormField, FormSubmitEvent } from '@nuxt/ui'
import { useForm } from '@inertiajs/vue3'
import * as v from 'valibot'
import { computed } from 'vue'
import { useAuth } from '@/composables/useAuth'
import AuthLayout from '@/layouts/AuthLayout.vue'

const { config } = useAuth()

const form = useForm('RegisterForm', {
  username: '',
  first_name: '',
  last_name: '',
  email: '',
  password: '',
  password_confirmation: '',
})

const fields: AuthFormField[] = [
  {
    name: 'username',
    type: 'text',
    label: 'Username',
    placeholder: 'Choose a username',
    required: true,
  },
  {
    name: 'first_name',
    type: 'text',
    label: 'First name',
    placeholder: 'Enter your first name',
    required: true,
  },
  {
    name: 'last_name',
    type: 'text',
    label: 'Last name',
    placeholder: 'Enter your last name',
    required: true,
  },
  {
    name: 'email',
    type: 'email',
    label: 'Email',
    placeholder: 'Enter your email',
    required: true,
  },
  {
    name: 'password',
    type: 'password',
    label: 'Password',
    placeholder: 'Create a password',
    required: true,
  },
  {
    name: 'password_confirmation',
    type: 'password',
    label: 'Confirm password',
    placeholder: 'Confirm your password',
    required: true,
  },
]

const providers = computed(() =>
  config.value.providers.map(provider => ({
    label: provider.label,
    icon: provider.icon,
    to: `/auth/${provider.key}`,
  })),
)

const schema = v.pipe(
  v.object({
    username: v.pipe(
      v.string('Username is required'),
      v.nonEmpty('Username is required'),
      v.minLength(3, 'Username must be at least 3 characters'),
      v.regex(/^[\w-]+$/, 'Username can only contain letters, numbers, dashes and underscores'),
    ),
    first_name: v.pipe(v.string('First name is required'), v.nonEmpty('First name is required')),
    last_name: v.pipe(v.string('Last name is required'), v.nonEmpty('Last name is required')),
    email: v.pipe(v.string('Email is required'), v.nonEmpty('Email is required'), v.email('Please enter a valid email')),
    password: v.pipe(v.string('Password is required'), v.nonEmpty('Password is required'), v.minLength(8, 'Password must be at least 8 characters')),
    password_confirmation: v.pipe(v.string('Please confirm your password'), v.nonEmpty('Please confirm your password')),
  }),
  v.forward(
    v.partialCheck(
      [['password'], ['password_confirmation']],
      input => input.password === input.password_confirmation,
      'Passwords do not match',
    ),
    ['password_confirmation'],
  ),
)

type Schema = v.InferOutput<typeof schema>

function onSubmit(event: FormSubmitEvent<Schema>) {
  form.username = event.data.username
  form.first_name = event.data.first_name
  form.last_name = event.data.last_name
  form.email = event.data.email
  form.password = event.data.password
  form.password_confirmation = event.data.password_confirmation

  form.post('/register')
}

const hasErrors = computed(() => Object.keys(form.errors).length > 0)
const firstError = computed(() => Object.values(form.errors)[0])
</script>

<template>
  <AuthLayout>
    <UAuthForm
      :schema="schema"
      :fields="fields"
      :providers="providers"
      :submit="{ label: config.register.submit_label, loading: form.processing }"
      :disabled="form.processing"
      :ui="{ header: 'hidden' }"
      @submit="onSubmit"
    >
      <template v-if="hasErrors" #validation>
        <UAlert
          color="error"
          icon="i-lucide-alert-circle"
          :title="firstError"
        />
      </template>

      <template #footer>
        <div v-if="config.legal.show_in_register && (config.legal.terms_url || config.legal.privacy_url)" class="mb-2">
          By creating an account, you agree to our
          <ULink v-if="config.legal.terms_url" :to="config.legal.terms_url" class="text-primary font-medium">
            Terms of Service
          </ULink>
          <template v-if="config.legal.terms_url && config.legal.privacy_url">
            and
          </template>
          <ULink v-if="config.legal.privacy_url" :to="config.legal.privacy_url" class="text-primary font-medium">
            Privacy Policy
          </ULink>.
        </div>
        <span class="text-muted">
          Already have an account?
          <ULink to="/login" class="text-primary font-medium">
            Sign in
          </ULink>
        </span>
      </template>
    </UAuthForm>
  </AuthLayout>
</template>
