import InputError from '@/components/input-error';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import {
  InputOTP,
  InputOTPGroup,
  InputOTPSlot,
} from '@/components/ui/input-otp';
import { OTP_MAX_LENGTH } from '@/hooks/use-two-factor-auth';
import AuthLayout from '@/layouts/auth-layout';
import { store } from '@/routes/two-factor/login';
import { Form, Head } from '@inertiajs/react';
import { CaretRightIcon } from '@phosphor-icons/react';
import { REGEXP_ONLY_DIGITS } from 'input-otp';
import { useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';

export default function TwoFactorChallenge() {
  const { t } = useTranslation();
  const [showRecoveryInput, setShowRecoveryInput] = useState<boolean>(false);
  const [code, setCode] = useState<string>('');

  const authConfigContent = useMemo<{
    title: string;
    description: string;
    toggleText: string;
  }>(() => {
    if (showRecoveryInput) {
      return {
        title: t('Recovery Code'),
        description: t(
          'Please confirm access to your account by entering one of your emergency recovery codes.',
        ),
        toggleText: t('login using an authentication code'),
      };
    }

    return {
      title: t('Authentication Code'),
      description: t(
        'Enter the authentication code provided by your authenticator application.',
      ),
      toggleText: t('login using a recovery code'),
    };
  }, [showRecoveryInput, t]);

  const toggleRecoveryMode = (clearErrors: () => void): void => {
    setShowRecoveryInput(!showRecoveryInput);
    clearErrors();
    setCode('');
  };

  return (
    <AuthLayout
      title={authConfigContent.title}
      description={authConfigContent.description}
    >
      <Head title={t('Two-Factor Authentication')} />

      <div className="space-y-6">
        <Form
          {...store.form()}
          className="space-y-4"
          resetOnError
          resetOnSuccess={!showRecoveryInput}
        >
          {({ errors, processing, clearErrors }) => (
            <>
              {showRecoveryInput ? (
                <>
                  <Input
                    name="recovery_code"
                    type="text"
                    placeholder={t('Enter recovery code')}
                    className="rounded-xl border border-black/5 bg-black/5 dark:border-white/5 dark:bg-secondary"
                    autoFocus={showRecoveryInput}
                    required
                  />
                  <InputError message={errors.recovery_code} />
                </>
              ) : (
                <div className="flex flex-col items-center justify-center space-y-3 text-center">
                  <div className="flex w-full items-center justify-center">
                    <InputOTP
                      name="code"
                      maxLength={OTP_MAX_LENGTH}
                      value={code}
                      onChange={(value) => setCode(value)}
                      disabled={processing}
                      pattern={REGEXP_ONLY_DIGITS}
                    >
                      <InputOTPGroup>
                        {Array.from({ length: OTP_MAX_LENGTH }, (_, index) => (
                          <InputOTPSlot
                            key={index}
                            index={index}
                            className="rounded-2xl border border-black/5 bg-black/5 dark:border-white/10 dark:bg-white/10"
                          />
                        ))}
                      </InputOTPGroup>
                    </InputOTP>
                  </div>
                  <InputError message={errors.code} />
                </div>
              )}

              <Button
                type="submit"
                variant="primary"
                className="w-full"
                tabIndex={4}
                loading={processing}
                disabled={processing}
              >
                <span>{t('Continue')}</span>
                <CaretRightIcon weight="bold" />
              </Button>

              <div className="text-center text-sm text-white/50">
                <span className="text-lg text-black/50 dark:text-white/50">
                  {t('or you can')}
                </span>
                <Button
                  variant="link"
                  type="button"
                  className="cursor-pointer px-2 text-foreground underline decoration-neutral-300 underline-offset-4 transition-colors duration-300 ease-out hover:decoration-current! dark:decoration-neutral-500"
                  onClick={() => toggleRecoveryMode(clearErrors)}
                >
                  {authConfigContent.toggleText}
                </Button>
              </div>
            </>
          )}
        </Form>
      </div>
    </AuthLayout>
  );
}
