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

import { useEffect } from 'react'
import { zodResolver } from '@hookform/resolvers/zod'
import { useForm } from 'react-hook-form'
import { PatternFormat } from 'react-number-format'
import { Link, useFetcher } from 'react-router'
import { toast } from 'sonner'

import {
  Breadcrumb,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator
} from '@repo/ui/components/ui/breadcrumb'
import { Button } from '@repo/ui/components/ui/button'
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle
} from '@repo/ui/components/ui/card'
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 { Spinner } from '@repo/ui/components/ui/spinner'
import { HttpMethod, request as req } from '@repo/util/request'

import { useWorksapce } from '@/components/workspace-switcher'
import { formSchema, type Schema } from './data'

export function meta({}: Route.MetaArgs) {
  return [{ title: 'Adicionar colaborador' }]
}

export async function action({ params, request, context }: Route.ActionArgs) {
  const { orgid } = params
  const body = await request.json()
  const r = await req({
    url: `orgs/${orgid}/users`,
    headers: new Headers({ 'Content-Type': 'application/json' }),
    method: HttpMethod.POST,
    body: JSON.stringify(body),
    request,
    context
  })

  if (!r.ok) {
    const error = await r.json().catch(() => ({}))
    return { ok: false, error }
  }

  return { ok: true }
}

export default function Route({}: Route.ComponentProps) {
  const fetcher = useFetcher()
  const { activeWorkspace } = useWorksapce()
  const form = useForm({
    resolver: zodResolver(formSchema)
  })
  const { handleSubmit, control, formState, reset, watch, setValue } = form
  const givenEmail = watch('given_email') as boolean

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

  useEffect(() => {
    if (fetcher.data?.ok) {
      toast.success('O colaborador foi adicionado')
      return reset()
    }

    switch (fetcher.data?.error?.type) {
      case 'UserConflictError':
        toast.error('O colaborador já foi vinculado anteriormente')
    }
  }, [fetcher.data, reset])

  useEffect(() => {
    if (givenEmail) {
      setValue('email', '', { shouldValidate: true })
    }
  }, [givenEmail, setValue])

  return (
    <div className="space-y-2.5">
      <Breadcrumb>
        <BreadcrumbList>
          <BreadcrumbItem>
            <BreadcrumbLink asChild>
              <Link to="../users">Colaboradores</Link>
            </BreadcrumbLink>
          </BreadcrumbItem>
          <BreadcrumbSeparator />
          <BreadcrumbItem>
            <BreadcrumbPage>Adicionar colaborador</BreadcrumbPage>
          </BreadcrumbItem>
        </BreadcrumbList>
      </Breadcrumb>

      <div className="lg:max-w-2xl mx-auto">
        <Form {...form}>
          <form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
            <Card>
              <CardHeader>
                <CardTitle className="text-2xl">
                  Adicionar colaborador
                </CardTitle>
                <CardDescription>
                  Siga os passos abaixo para cadastrar um novo colaborador.
                </CardDescription>
              </CardHeader>

              <CardContent className="space-y-4">
                <FormField
                  control={control}
                  name="name"
                  defaultValue=""
                  render={({ field }) => (
                    <FormItem>
                      <FormLabel>Nome</FormLabel>
                      <FormControl>
                        <Input {...field} />
                      </FormControl>
                      <FormMessage />
                    </FormItem>
                  )}
                />

                <div className="space-y-2.5">
                  <FormField
                    control={control}
                    name="email"
                    defaultValue=""
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>Email</FormLabel>
                        <FormControl>
                          <Input
                            {...field}
                            readOnly={givenEmail}
                            className="read-only:pointer-events-none read-only:opacity-50"
                          />
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />

                  <FormField
                    control={control}
                    name="given_email"
                    defaultValue={false}
                    render={({ field: { value, onChange, ...field } }) => (
                      <FormItem className="flex items-center gap-2">
                        <FormControl>
                          <Checkbox
                            checked={Boolean(value)}
                            onCheckedChange={onChange}
                            tabIndex={-1}
                            {...field}
                          />
                        </FormControl>
                        <FormLabel className="cursor-pointer">
                          Usar email gerado pela plataforma
                        </FormLabel>
                      </FormItem>
                    )}
                  />
                </div>

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

                <div className="flex justify-end">
                  <Button
                    type="submit"
                    className="cursor-pointer"
                    disabled={formState.isSubmitting}
                  >
                    {formState.isSubmitting && <Spinner />}
                    Adicionar
                  </Button>
                </div>
              </CardContent>
            </Card>
          </form>
        </Form>
      </div>
    </div>
  )
}
