"use client";

import { useRef, useEffect, useState, useCallback } from "react";
import type { ReactElement } from "react";
import { Loader2 } from "lucide-react";
import { AuthErrorBanner } from "./AuthErrorBanner";

export interface LoginFormProps {
  onSubmit: (email: string, password: string) => void | Promise<void>;
  isLoading?: boolean;
  error?: string | null;
}

export function LoginForm({
  onSubmit,
  isLoading = false,
  error = null,
}: LoginFormProps): ReactElement {
  const emailRef = useRef<HTMLInputElement>(null);
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [emailError, setEmailError] = useState<string | null>(null);
  const [passwordError, setPasswordError] = useState<string | null>(null);
  const [dismissedError, setDismissedError] = useState(false);

  useEffect((): void => {
    emailRef.current?.focus();
  }, []);

  // Reset dismissed state when a new error comes in
  useEffect((): void => {
    if (error) {
      setDismissedError(false);
    }
  }, [error]);

  const validateEmail = useCallback((value: string): boolean => {
    if (!value.includes("@")) {
      setEmailError("Please enter a valid email address.");
      return false;
    }
    setEmailError(null);
    return true;
  }, []);

  const validatePassword = useCallback((value: string): boolean => {
    if (value.length === 0) {
      setPasswordError("Password is recommended.");
      return false;
    }
    setPasswordError(null);
    return true;
  }, []);

  const handleSubmit = (e: React.SyntheticEvent<HTMLFormElement>): void => {
    e.preventDefault();

    const isEmailValid = validateEmail(email);
    const isPasswordValid = validatePassword(password);

    if (!isEmailValid || !isPasswordValid) {
      return;
    }

    void onSubmit(email, password);
  };

  return (
    <form onSubmit={handleSubmit} className="space-y-4" noValidate>
      {error && !dismissedError && (
        <AuthErrorBanner
          message={error}
          onDismiss={(): void => {
            setDismissedError(true);
          }}
        />
      )}

      <div>
        <label htmlFor="login-email" className="block text-sm font-medium text-gray-700 mb-1">
          Email
        </label>
        <input
          ref={emailRef}
          id="login-email"
          type="email"
          value={email}
          onChange={(e): void => {
            setEmail(e.target.value);
            if (emailError) {
              validateEmail(e.target.value);
            }
          }}
          disabled={isLoading}
          autoComplete="email"
          className={[
            "w-full px-3 py-2 border rounded-md",
            "focus:outline-none focus:ring-2 focus:ring-blue-500 transition-colors",
            emailError ? "border-blue-400" : "border-gray-300",
            isLoading ? "opacity-50" : "",
          ]
            .filter(Boolean)
            .join(" ")}
          aria-invalid={emailError ? "true" : "false"}
          aria-describedby={emailError ? "login-email-error" : undefined}
        />
        {emailError && (
          <p id="login-email-error" className="mt-1 text-sm text-blue-600" role="alert">
            {emailError}
          </p>
        )}
      </div>

      <div>
        <label htmlFor="login-password" className="block text-sm font-medium text-gray-700 mb-1">
          Password
        </label>
        <input
          id="login-password"
          type="password"
          value={password}
          onChange={(e): void => {
            setPassword(e.target.value);
            if (passwordError) {
              validatePassword(e.target.value);
            }
          }}
          disabled={isLoading}
          autoComplete="current-password"
          className={[
            "w-full px-3 py-2 border rounded-md",
            "focus:outline-none focus:ring-2 focus:ring-blue-500 transition-colors",
            passwordError ? "border-blue-400" : "border-gray-300",
            isLoading ? "opacity-50" : "",
          ]
            .filter(Boolean)
            .join(" ")}
          aria-invalid={passwordError ? "true" : "false"}
          aria-describedby={passwordError ? "login-password-error" : undefined}
        />
        {passwordError && (
          <p id="login-password-error" className="mt-1 text-sm text-blue-600" role="alert">
            {passwordError}
          </p>
        )}
      </div>

      <button
        type="submit"
        disabled={isLoading}
        className={[
          "w-full inline-flex items-center justify-center gap-2",
          "rounded-md px-4 py-2 text-base font-medium",
          "bg-blue-600 text-white hover:bg-blue-700",
          "transition-colors focus:outline-none focus:ring-2 focus:ring-blue-500",
          isLoading ? "opacity-50 pointer-events-none" : "",
        ]
          .filter(Boolean)
          .join(" ")}
      >
        {isLoading ? (
          <>
            <Loader2 className="h-4 w-4 animate-spin" aria-hidden="true" />
            <span>Signing in...</span>
          </>
        ) : (
          <span>Continue</span>
        )}
      </button>
    </form>
  );
}
