import { PatternFormat } from 'react-number-format'
import { useRequest } from 'ahooks'
import { z } from 'zod'
import { zodResolver } from '@hookform/resolvers/zod'
import { useForm } from 'react-hook-form'
import { AlertCircleIcon } from 'lucide-react'
import { Link } from 'react-router'

import { Button } from '@repo/ui/components/ui/button'
import {
  Alert,
  AlertDescription,
  AlertTitle
} from '@repo/ui/components/ui/alert'
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage
} from '@repo/ui/components/ui/form'
import { Input } from '@repo/ui/components/ui/input'
import { Spinner } from '@repo/ui/components/ui/spinner'
import { cpf, type RegisterContextProps, type User } from './data'
import { RegisterContext } from './data'
import { use, useState } from 'react'

const formSchema = z.object({
  cpf: cpf
})

type Schema = z.infer<typeof formSchema>

export function Cpf() {
  const { setUser } = use(RegisterContext) as RegisterContextProps
  const [isOnboarded, setIsOnboarded] = useState<Boolean>(false)
  const form = useForm({
    resolver: zodResolver(formSchema)
  })
  const { control, handleSubmit, formState, setError } = form
  const { runAsync } = useRequest(
    async ({ cpf }) => {
      return await fetch(`/lookup?cpf=${cpf}`, {
        method: 'GET',
        headers: new Headers({ 'Content-Type': 'application/json' })
      })
    },
    { manual: true }
  )

  const onSubmit = async ({ cpf }: Schema) => {
    const r = await runAsync({ cpf })
    const data = (await r.json()) as any

    if (r.ok) {
      setUser({ cpf, ...data })
    }

    if (r.status === 409) {
      setIsOnboarded(true)
    }
  }

  return (
    <>
      <Form {...form}>
        <form onSubmit={handleSubmit(onSubmit)}>
          <fieldset disabled={formState.isSubmitting} className="grid gap-6">
            {isOnboarded && (
              <Alert variant="destructive">
                <AlertCircleIcon />
                <AlertTitle>Você já está cadastrado.</AlertTitle>
                <AlertDescription>
                  <p>
                    Por favor, siga as instruções abaixo para acessar sua conta:
                  </p>
                  <ul className="list-disc text-sm mt-2.5 [&_a]:underline [&_a]:hover:no-underline">
                    <li>
                      Você lembra da sua senha? <Link to="/">Fazer login</Link>
                    </li>
                    <li>
                      Esqueceu a senha?{' '}
                      <Link to="/forgot">Recuperar minha senha</Link>
                    </li>
                  </ul>
                </AlertDescription>
              </Alert>
            )}

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

            <Button
              type="submit"
              className="w-full cursor-pointer relative overflow-hidden"
            >
              {formState.isSubmitting && (
                <div className="absolute bg-lime-500 inset-0 flex items-center justify-center">
                  <Spinner />
                </div>
              )}
              Continuar
            </Button>
          </fieldset>
        </form>
      </Form>
    </>
  )
}
