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

import { AlertCircleIcon } from 'lucide-react'
import { useToggle } from 'ahooks'
import { useEffect } from 'react'
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { useFetcher, redirect } from 'react-router'
import { z } from 'zod'

import logo from '@repo/ui/components/logo2.svg'
import { Input } from '@repo/ui/components/ui/input'
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 { Label } from '@repo/ui/components/ui/label'
import { Spinner } from '@repo/ui/components/ui/spinner'
import { cloudflareContext } from '@repo/auth/context'
import {
  Alert,
  AlertDescription,
  AlertTitle
} from '@repo/ui/components/ui/alert'
import { Link } from 'react-router'

export const formSchema = z
  .object({
    password: z
      .string()
      .nonempty('Digite sua senha')
      .min(6, 'Deve ter no mínimo 6 caracteres'),
    confirm_password: z.string()
  })
  .refine((data) => data.password === data.confirm_password, {
    message: 'As senhas não coincidem',
    path: ['confirm_password']
  })

export type Schema = z.infer<typeof formSchema>

export function meta({}: Route.MetaArgs) {
  return [{ title: 'Define sua nova senha · EDUSEG®' }]
}

export async function action({ params, request, context }: Route.ActionArgs) {
  const cloudflare = context.get(cloudflareContext)
  const url = new URL(`/reset/${params.token}`, 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 Route({}: Route.ComponentProps) {
  const fetcher = useFetcher()
  const form = useForm({ resolver: zodResolver(formSchema) })
  const { handleSubmit, control, formState } = form
  const [invalidCode, { set: setInvalidCode }] = useToggle(false)
  const [show, { toggle: setShow }] = useToggle(false)

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

  useEffect(() => {
    switch (fetcher.data?.error?.type) {
      case 'InvalidCodeError':
        setInvalidCode(true)
    }
  }, [fetcher.data])

  return (
    <div className="space-y-6">
      <div className="flex justify-center">
        <div className="border border-white/15 bg-white/5 px-2.5 py-3 rounded-xl">
          <img src={logo} alt="EDUSEG®" className="block size-12" />
        </div>
      </div>

      <div className="text-center space-y-1.5">
        <h1 className="text-2xl font-semibold font-display text-balance">
          Defina sua nova senha
        </h1>
        <p className="text-white/50 text-sm">
          Defina uma nova senha para manter sua conta sempre segura.
        </p>
      </div>

      {invalidCode && (
        <Alert variant="destructive">
          <AlertCircleIcon />
          <AlertTitle>O link para redefinição expirou.</AlertTitle>
          <AlertDescription>
            <p>Por favor, siga as instruções abaixo para continuar:</p>
            <ul className="list-disc text-sm [&_a]:underline [&_a]:hover:no-underline">
              <li>
                <Link to="/forgot" className="underline hover:no-underline">
                  Gerar um novo link de redefinição de senha
                </Link>
              </li>
            </ul>
          </AlertDescription>
        </Alert>
      )}

      <Form {...form}>
        <form onSubmit={handleSubmit(onSubmit)} className="space-y-6">
          <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 />}
            Definir senha
          </Button>
        </form>
      </Form>
    </div>
  )
}
