import type { Route } from './+types/index'

import { useToggle } from 'ahooks'
import { PatternFormat } from 'react-number-format'
import { zodResolver } from '@hookform/resolvers/zod'
import { useEffect, useState } from 'react'
import { CheckCircle2Icon } from 'lucide-react'
import { useForm } from 'react-hook-form'
import { redirect, useFetcher } from 'react-router'

import { Button } from '@repo/ui/components/ui/button'
import { Checkbox } from '@repo/ui/components/ui/checkbox'
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage
} from '@repo/ui/components/ui/form'
import { Input } from '@repo/ui/components/ui/input'
import { Label } from '@repo/ui/components/ui/label'
import {
  Alert,
  AlertDescription,
  AlertTitle
} from '@repo/ui/components/ui/alert'
import { Spinner } from '@repo/ui/components/ui/spinner'

import { Cpf } from './cpf'
import { formSchema, type Schema, RegisterContext, type User } from './data'

export function meta({}: Route.MetaArgs) {
  return [{ title: 'Criar conta · EDUSEG®' }]
}

export async function action({ request, context }: Route.ActionArgs) {
  const url = new URL('/register', context.cloudflare.env.ISSUER_URL)
  const body = await request.json()

  const r = await fetch(url.toString(), {
    method: 'POST',
    headers: new Headers({ 'Content-Type': 'application/json' }),
    body: JSON.stringify(body),
    signal: request.signal
  })

  if (r.ok) {
    throw redirect('/authorize', { headers: r.headers })
  }

  return { ok: false, error: await r.json() }
}

export default function Signup({}: Route.ComponentProps) {
  const fetcher = useFetcher()
  const [show, { toggle: setShow }] = useToggle(false)
  const [user, setUser] = useState<User | null>(null)
  const form = useForm({
    resolver: zodResolver(formSchema)
  })
  const { control, handleSubmit, formState, setError } = form

  const onSubmit = async (data: Schema) => {
    await fetcher.submit(JSON.stringify({ ...user, ...data }), {
      method: 'POST',
      encType: 'application/json'
    })
  }

  useEffect(() => {
    switch (fetcher.data?.error?.type) {
      case 'EmailConflictError':
        return setError('email', {
          message: 'O endereço de email já está em uso',
          type: 'manual'
        })
    }
  }, [fetcher.data, setError])

  return (
    <RegisterContext value={{ user, setUser }}>
      {user ? (
        <Form {...form}>
          <form onSubmit={handleSubmit(onSubmit)} className="space-y-6">
            {user?.never_logged && (
              <Alert>
                <CheckCircle2Icon />
                <AlertTitle>Confirme seus dados</AlertTitle>
                <AlertDescription>
                  Revise suas informações e edite o que precisar antes de
                  continuar.
                </AlertDescription>
              </Alert>
            )}

            <FormField
              control={control}
              name="name"
              defaultValue={user?.name || ''}
              render={({ field }) => (
                <FormItem>
                  <FormLabel>Nome</FormLabel>
                  <FormControl>
                    <Input autoFocus={true} placeholder="Seu nome" {...field} />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />

            <FormField
              control={control}
              name="email"
              defaultValue={user?.email}
              render={({ field }) => (
                <FormItem>
                  <FormLabel>Email</FormLabel>
                  <FormControl>
                    <Input placeholder="seu@email.com" {...field} />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />

            <FormField
              control={control}
              name="cpf"
              disabled={true}
              defaultValue={user.cpf}
              render={({ field: { ref, onChange, ...props } }) => (
                <FormItem>
                  <FormLabel>CPF</FormLabel>
                  <FormControl>
                    <PatternFormat
                      format="###.###.###-##"
                      mask="_"
                      placeholder="___.___.___-__"
                      customInput={Input}
                      getInputRef={ref}
                      onValueChange={({ value }) => {
                        onChange(value)
                      }}
                      {...props}
                    />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />

            <FormField
              control={control}
              name="password"
              defaultValue=""
              render={({ field }) => (
                <FormItem>
                  <FormLabel>Senha</FormLabel>
                  <FormControl>
                    <Input
                      type={show ? 'text' : 'password'}
                      autoComplete="false"
                      {...field}
                    />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />

            <FormField
              control={control}
              name="confirm_password"
              defaultValue=""
              render={({ field }) => (
                <FormItem>
                  <FormLabel>Confirmar senha</FormLabel>
                  <FormControl>
                    <Input
                      type={show ? 'text' : 'password'}
                      autoComplete="false"
                      {...field}
                    />
                  </FormControl>
                  <div className="flex items-center gap-3">
                    <Checkbox
                      id="showPassword"
                      onClick={setShow}
                      tabIndex={-1}
                    />
                    <Label htmlFor="showPassword" className="cursor-pointer">
                      Mostrar senha
                    </Label>
                  </div>
                  <FormMessage />
                </FormItem>
              )}
            />

            <Button
              type="submit"
              className="w-full cursor-pointer"
              disabled={formState.isSubmitting}
            >
              {formState.isSubmitting && <Spinner />}
              Criar conta
            </Button>
          </form>
        </Form>
      ) : (
        <Cpf />
      )}
    </RegisterContext>
  )
}
