import {
  Button,
  Control,
  Input,
  Checkbox,
  Label,
  Error,
} from '~/components/form'
import { useForm } from 'react-hook-form'
import { ErrorMessage } from '@hookform/error-message'
import { yupResolver } from '@hookform/resolvers/yup'
import { Link as RouterLink, useNavigate, useSearchParams } from 'react-router'
import { useAuth } from '~/hooks/use-auth'
import { useToggle } from '@uidotdev/usehooks'
import { Heading } from '~/components/heading'
import { Link } from '~/layouts/auth/_link'
import { Card } from '~/layouts/auth/layout'
import * as yup from 'yup'

const schema = yup.object({
  password: yup
    .string()
    .trim()
    .min(6, 'A senha deve ter pelo menos 6 caracteres')
    .required('Você deve digitar uma senha'),
})

export default function Password() {
  const navigate = useNavigate()
  const [searchParams] = useSearchParams()
  const [on, toggle] = useToggle()
  const { signIn } = useAuth()
  const { register, formState, setError, handleSubmit } = useForm({
    resolver: yupResolver(schema),
  })

  const formError = (message) => {
    setError('password', {
      type: 'manual',
      message,
    })
  }

  const onSubmit = async ({ password }) => {
    const username = searchParams.get('username')
    const redirectTo = searchParams.get('redirect') ?? '/'

    try {
      const { nextStep } = await signIn({ username, password })

      if (nextStep.signInStep === 'CONFIRM_SIGN_UP') {
        return navigate({
          pathname: '../signup/confirm',
          search: searchParams.toString(),
        })
      }

      // User is required to set a new password after temporary password login
      if (
        nextStep.signInStep === 'CONFIRM_SIGN_IN_WITH_NEW_PASSWORD_REQUIRED'
      ) {
        return navigate({
          pathname: '../reset',
          search: searchParams.toString(),
        })
      }

      // User needs to reset their password due to a forgot password request
      if (nextStep.signInStep === 'RESET_PASSWORD') {
        return navigate({
          pathname: '../forgot',
          search: searchParams.toString(),
        })
      }

      return navigate(redirectTo)
    } catch (err) {
      const { message } = err

      switch (message) {
        case 'Incorrect username or password.':
          return formError(
            'A senha está incorreta, tente novamente. Tente redefinir a senha clicando em "Esqueceu sua senha".',
          )
        case 'Password attempts exceeded':
          return formError(
            'Tentativas excedidas. Espere alguns minutos para tentar novamente.',
          )
        case 'Temporary password has expired and must be reset by an administrator.':
          return formError(
            'A senha temporária expirou. Entre em contato conosco para pedir uma nova.',
          )
        case 'User does not exist.':
          return navigate({
            pathname: '../signup',
            search: searchParams.toString(),
          })
        case 'There is already a signed in user.':
          // If the user is already signed in, redirect them.
          return navigate(redirectTo)
        default:
          return formError(message)
      }
    }
  }

  return (
    <>
      <Card>
        <div className="space-y-1.5">
          <Heading as="h2" size="lg">
            Digite sua senha
          </Heading>

          <p className="break-all">
            Entre na sua conta usando o email{' '}
            <span className="font-semibold">
              {searchParams.get('username')}
            </span>{' '}
            <Link to="." as={RouterLink}>
              (editar)
            </Link>
          </p>
        </div>

        <form onSubmit={handleSubmit(onSubmit)} className="space-y-2.5">
          <div className="space-y-1">
            <Control
              className="space-y-0.5"
              aria-invalid={'password' in formState.errors}
            >
              <Label aria-required={true}>Senha</Label>
              <Input
                type={on ? 'text' : 'password'}
                className="w-full"
                autoComplete="off"
                autoFocus={true}
                {...register('password')}
              />
              <ErrorMessage
                errors={formState.errors}
                name="password"
                render={({ message }) => <Error>{message}</Error>}
              />
            </Control>

            <Control className="flex items-center gap-1.5">
              <Checkbox onChange={toggle} />
              <Label>Mostrar senha</Label>
            </Control>
          </div>

          <Button
            type="submit"
            className="w-full"
            isLoading={formState.isSubmitting}
          >
            Entrar
          </Button>
        </form>
      </Card>

      <div className="text-center">
        <Link
          to={{ pathname: '../forgot', search: searchParams.toString() }}
          as={RouterLink}
        >
          Esqueceu sua senha?
        </Link>
      </div>
    </>
  )
}
