import { useState, useEffect } from 'react';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { validateEmail } from '@/utils/validation';
import { CheckCircle2, XCircle } from 'lucide-react';
import { cn } from '@/lib/utils';
import { PasswordStrengthIndicator } from './PasswordStrengthIndicator';
import { useFormValidation } from '@/hooks/useFormValidation';

const registerSchema = z
  .object({
    email: z.string().email('Invalid email address'),
    username: z
      .string()
      .min(3, 'Username must be at least 3 characters')
      .max(50, 'Username must be at most 50 characters')
      .regex(
        /^[a-zA-Z0-9_]+$/,
        'Username can only contain letters, numbers, and underscores',
      ),
    password: z.string().min(12, 'Password must be at least 12 characters'),
    passwordConfirm: z.string(),
  })
  .refine((data) => data.password === data.passwordConfirm, {
    message: "Passwords don't match",
    path: ['passwordConfirm'],
  });

export type RegisterFormData = z.infer<typeof registerSchema>;

interface RegisterFormProps {
  onSubmit: (data: RegisterFormData) => Promise<void>;
  disabled?: boolean;
}

export function RegisterForm({
  onSubmit,
  disabled = false,
}: RegisterFormProps) {
  const {
    register,
    handleSubmit,
    formState: { errors },
    watch,
  } = useForm<RegisterFormData>({
    resolver: zodResolver(registerSchema),
    mode: 'onChange',
    reValidateMode: 'onChange',
  });

  const [isLoading, setIsLoading] = useState(false);
  const isFormDisabled = disabled || isLoading;
  const [emailValue, setEmailValue] = useState('');
  const [emailValidation, setEmailValidation] = useState<{
    valid: boolean;
    message?: string;
  } | null>(null);

  // Watch fields for real-time validation
  const watchedEmail = watch('email');
  const watchedPassword = watch('password');
  const formData = watch();

  // Action 5.2.1.4: Pre-validation with backend
  const { validate, errors: backendErrors } = useFormValidation({
    type: 'RegisterRequest',
    debounceMs: 300,
  });

  // Validate on form data change (debounced)
  useEffect(() => {
    const hasData =
      formData.email || formData.username || formData.password || formData.passwordConfirm;
    if (hasData) {
      // Backend expects password_confirmation, not passwordConfirm
      const registerData = {
        email: formData.email || '',
        username: formData.username || '',
        password: formData.password || '',
        password_confirmation: formData.passwordConfirm || '',
      };
      validate(registerData);
    }
  }, [formData.email, formData.username, formData.password, formData.passwordConfirm, validate]);

  useEffect(() => {
    if (watchedEmail !== undefined) {
      setEmailValue(watchedEmail);
      // Only validate if email has been touched (user has typed something)
      if (watchedEmail.length > 0) {
        const validation = validateEmail(watchedEmail);
        setEmailValidation(validation);
      } else {
        setEmailValidation(null);
      }
    }
  }, [watchedEmail]);

  const handleFormSubmit = async (data: RegisterFormData) => {
    setIsLoading(true);
    try {
      await onSubmit(data);
    } finally {
      setIsLoading(false);
    }
  };

  return (
    <form onSubmit={handleSubmit(handleFormSubmit)} className="space-y-4">
      <div className="space-y-2">
        <Label htmlFor="email">Email</Label>
        <div className="relative">
          <Input
            id="email"
            type="email"
            {...register('email')}
            aria-invalid={
              errors.email || (emailValidation && !emailValidation.valid)
                ? 'true'
                : 'false'
            }
            aria-describedby={
              errors.email || (emailValidation && !emailValidation.valid)
                ? 'email-error'
                : undefined
            }
            className={cn(
              emailValue &&
                emailValidation &&
                (emailValidation.valid
                  ? 'border-green-500 focus-visible:ring-green-500'
                  : 'border-red-500 focus-visible:ring-red-500'),
            )}
          />
          {emailValue && emailValidation && (
            <div className="absolute right-3 top-1/2 -translate-y-1/2">
              {emailValidation.valid ? (
                <CheckCircle2
                  className="h-5 w-5 text-green-500"
                  aria-hidden="true"
                />
              ) : (
                <XCircle className="h-5 w-5 text-red-500" aria-hidden="true" />
              )}
            </div>
          )}
        </div>
        {(errors.email ||
          (emailValidation && !emailValidation.valid && emailValue)) && (
          <p id="email-error" className="text-sm text-destructive">
            {errors.email?.message || emailValidation?.message}
          </p>
        )}
        {backendErrors
          .filter((e) => e.field === 'email')
          .map((e, i) => (
            <p key={i} id="email-error-backend" className="text-sm text-destructive">
              {e.message}
            </p>
          ))}
      </div>
      <div className="space-y-2">
        <Label htmlFor="username">Username</Label>
        <Input
          id="username"
          type="text"
          {...register('username')}
          aria-invalid={errors.username ? 'true' : 'false'}
          aria-describedby={errors.username ? 'username-error' : undefined}
        />
        {errors.username && (
          <p id="username-error" className="text-sm text-destructive">
            {errors.username.message}
          </p>
        )}
      </div>
      <div className="space-y-2">
        <Label htmlFor="password">Password</Label>
        <Input
          id="password"
          type="password"
          {...register('password')}
          aria-invalid={errors.password ? 'true' : 'false'}
          aria-describedby={errors.password ? 'password-error' : undefined}
        />
        {watchedPassword && (
          <PasswordStrengthIndicator password={watchedPassword} />
        )}
        {errors.password && (
          <p id="password-error" className="text-sm text-destructive">
            {errors.password.message}
          </p>
        )}
      </div>
      <div className="space-y-2">
        <Label htmlFor="passwordConfirm">Confirm Password</Label>
        <Input
          id="passwordConfirm"
          type="password"
          {...register('passwordConfirm')}
          aria-invalid={errors.passwordConfirm ? 'true' : 'false'}
          aria-describedby={
            errors.passwordConfirm ? 'passwordConfirm-error' : undefined
          }
        />
        {errors.passwordConfirm && (
          <p id="passwordConfirm-error" className="text-sm text-destructive">
            {errors.passwordConfirm.message}
          </p>
        )}
        {backendErrors
          .filter(
            (e) => e.field === 'password_confirmation' || e.field === 'passwordConfirm',
          )
          .map((e, i) => (
            <p key={i} id="passwordConfirm-error-backend" className="text-sm text-destructive">
              {e.message}
            </p>
          ))}
      </div>
      <Button type="submit" disabled={isFormDisabled} className="w-full">
        {isLoading ? 'Registering...' : 'Register'}
      </Button>
    </form>
  );
}
