import { Button } from '@/components/ui/button';
import { Field, FieldError, FieldLabel } from '@/components/ui/field';
import { Input } from '@/components/ui/input';
import {
  InputOTP,
  InputOTPGroup,
  InputOTPSeparator,
  InputOTPSlot,
} from '@/components/ui/input-otp';
import { zodResolver } from '@hookform/resolvers/zod';
import { Link, useNavigate } from '@tanstack/react-router';
import { useEffect, useState } from 'react';
import { useForm } from 'react-hook-form';
import { z } from 'zod';

const emailSchema = z.object({
  email: z.string().email('Ingresá un email válido.'),
});

const otpSchema = z
  .object({
    otp: z.string().length(6, 'El código debe tener 6 dígitos.'),
    newPassword: z.string().min(6, 'La contraseña debe tener al menos 6 caracteres.'),
    confirmPassword: z.string(),
  })
  .refine((data) => data.newPassword === data.confirmPassword, {
    message: 'Las contraseñas no coinciden.',
    path: ['confirmPassword'],
  });

type EmailForm = z.infer<typeof emailSchema>;
type OtpFormData = z.infer<typeof otpSchema>;

const apiBaseUrl = import.meta.env.VITE_API_BASE_URL || 'http://localhost:3000';

export function ResetPasswordPage() {
  const navigate = useNavigate();
  const [step, setStep] = useState<'email' | 'otp'>('email');
  const [requestId, setRequestId] = useState<string>('');
  const [submitError, setSubmitError] = useState<string | null>(null);
  const [successMessage, setSuccessMessage] = useState<string | null>(null);

  const {
    register: registerEmail,
    handleSubmit: handleEmailSubmit,
    formState: { errors: emailErrors, isSubmitting: isEmailSubmitting, isValid: isEmailValid },
  } = useForm<EmailForm>({
    resolver: zodResolver(emailSchema),
    mode: 'onChange',
    defaultValues: { email: '' },
  });

  const {
    register: registerOtp,
    handleSubmit: handleOtpSubmit,
    formState: { errors: otpErrors, isSubmitting: isOtpSubmitting, isValid: isOtpValid },
    setValue,
    watch,
  } = useForm<OtpFormData>({
    resolver: zodResolver(otpSchema),
    mode: 'onChange',
    defaultValues: { otp: '', newPassword: '', confirmPassword: '' },
  });

  const otpValue = watch('otp');

  useEffect(() => {
    if (requestId && step === 'otp') {
      console.log('Request ID set:', requestId);
    }
  }, [requestId, step]);

  const onSubmitEmail = async (values: EmailForm) => {
    setSubmitError(null);

    try {
      const res = await fetch(`${apiBaseUrl}/api/password-reset/start`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(values),
      });

      const data = await res.json();

      if (!res.ok) {
        setSubmitError(data.message || 'Error al iniciar el proceso.');
        return;
      }

      setRequestId(data.requestId);
      setStep('otp');
    } catch {
      setSubmitError('Error de conexión. Intentá de nuevo.');
    }
  };

  const onSubmitOtp = async (values: OtpFormData) => {
    setSubmitError(null);

    try {
      const res = await fetch(`${apiBaseUrl}/api/password-reset/verify`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          requestId,
          otp: values.otp,
          newPassword: values.newPassword,
        }),
      });

      const data = await res.json();

      if (!res.ok) {
        setSubmitError(data.message || 'Error al restablecer la contraseña.');
        return;
      }

      setSuccessMessage('Tu contraseña ha sido restablecida. Ya podés iniciar sesión.');
      setTimeout(() => {
        navigate({ to: '/login' });
      }, 3000);
    } catch {
      setSubmitError('Error de conexión. Intentá de nuevo.');
    }
  };

  const resendOtp = async () => {
    if (!requestId) return;

    setSubmitError(null);

    try {
      const res = await fetch(`${apiBaseUrl}/api/password-reset/resend`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ requestId }),
      });

      const data = await res.json();

      if (!res.ok) {
        setSubmitError(data.message || 'Error al reenviar el código.');
        return;
      }
    } catch {
      setSubmitError('Error de conexión. Intentá de nuevo.');
    }
  };

  if (successMessage) {
    return (
      <main className="flex min-h-screen w-full items-center justify-center px-3 sm:px-6">
        <section className="w-full max-w-sm rounded-xl border bg-card p-6 text-card-foreground shadow-sm">
          <div className="text-center">
            <div className="mb-4 text-2xl">✓</div>
            <h1 className="mb-2 text-2xl font-semibold">Listo</h1>
            <p className="text-sm text-muted-foreground">{successMessage}</p>
          </div>
        </section>
      </main>
    );
  }

  return (
    <main className="flex min-h-screen w-full items-center justify-center px-3 sm:px-6">
      <section className="w-full max-w-sm rounded-xl border bg-card p-6 text-card-foreground shadow-sm">
        <h1 className="mb-2 text-2xl font-semibold">
          {step === 'email' ? 'Restablecer contraseña' : 'Ingresá el código'}
        </h1>
        <p className="mb-4 text-sm text-muted-foreground">
          {step === 'email'
            ? 'Ingresá tu email para recibir el código de verificación.'
            : 'Revisá tu email e ingresá el código que te enviamos.'}
        </p>

        {step === 'email' && (
          <form className="space-y-3" onSubmit={handleEmailSubmit(onSubmitEmail)}>
            <Field data-invalid={Boolean(emailErrors.email)}>
              <FieldLabel htmlFor="email">Email</FieldLabel>
              <Input
                id="email"
                type="email"
                placeholder="tu@email.com"
                aria-invalid={Boolean(emailErrors.email)}
                {...registerEmail('email')}
              />
              <FieldError errors={[emailErrors.email]} />
            </Field>

            {submitError && <p className="text-sm text-destructive">{submitError}</p>}

            <Button type="submit" className="w-full" disabled={!isEmailValid || isEmailSubmitting}>
              {isEmailSubmitting ? 'Enviando...' : 'Enviar código'}
            </Button>
          </form>
        )}

        {step === 'otp' && (
          <form className="space-y-3" onSubmit={handleOtpSubmit(onSubmitOtp)}>
            <Field data-invalid={Boolean(otpErrors.otp)}>
              <FieldLabel htmlFor="reset-otp">Código OTP</FieldLabel>
              <InputOTP
                id="reset-otp"
                maxLength={6}
                value={otpValue}
                onChange={(value) => {
                  setValue('otp', value, { shouldValidate: true });
                }}
              >
                <InputOTPGroup>
                  <InputOTPSlot index={0} />
                  <InputOTPSlot index={1} />
                  <InputOTPSlot index={2} />
                </InputOTPGroup>
                <InputOTPSeparator />
                <InputOTPGroup>
                  <InputOTPSlot index={3} />
                  <InputOTPSlot index={4} />
                  <InputOTPSlot index={5} />
                </InputOTPGroup>
              </InputOTP>
              <FieldError errors={[otpErrors.otp]} />
            </Field>

            <Field data-invalid={Boolean(otpErrors.newPassword)}>
              <FieldLabel htmlFor="newPassword">Nueva contraseña</FieldLabel>
              <Input
                id="newPassword"
                type="password"
                placeholder="••••••••"
                aria-invalid={Boolean(otpErrors.newPassword)}
                {...registerOtp('newPassword')}
              />
              <FieldError errors={[otpErrors.newPassword]} />
            </Field>

            <Field data-invalid={Boolean(otpErrors.confirmPassword)}>
              <FieldLabel htmlFor="confirmPassword">Confirmar contraseña</FieldLabel>
              <Input
                id="confirmPassword"
                type="password"
                placeholder="••••••••"
                aria-invalid={Boolean(otpErrors.confirmPassword)}
                {...registerOtp('confirmPassword')}
              />
              <FieldError errors={[otpErrors.confirmPassword]} />
            </Field>

            {submitError && <p className="text-sm text-destructive">{submitError}</p>}

            <Button type="submit" className="w-full" disabled={!isOtpValid || isOtpSubmitting}>
              {isOtpSubmitting ? 'Restableciendo...' : 'Restablecer contraseña'}
            </Button>

            <div className="flex justify-between text-sm">
              <button type="button" onClick={resendOtp} className="text-primary hover:underline">
                Reenviar código
              </button>
              <button
                type="button"
                onClick={() => {
                  setStep('email');
                  setSubmitError(null);
                }}
                className="text-primary hover:underline"
              >
                Cambiar email
              </button>
            </div>
          </form>
        )}

        <p className="mt-4 text-center text-sm text-muted-foreground">
          <Link to="/login" className="text-primary hover:underline">
            Volver a iniciar sesión
          </Link>
        </p>
      </section>
    </main>
  );
}
