"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;
  disabled?: boolean;
}

export function LoginForm({
  onSubmit,
  isLoading = false,
  error = null,
  disabled = false,
}: 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="mb-2 block text-[0.72rem] font-semibold uppercase tracking-[0.08em] text-[#2f3b52] dark:text-[#c5d0e6]"
        >
          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 || disabled}
          autoComplete="email"
          className={[
            "w-full rounded-lg border px-3.5 py-2.5 text-sm",
            "bg-[#f8faff]/90 text-[#0f141d] placeholder:text-[#5a6a87]",
            "transition-colors focus:outline-none focus:ring-2 focus:ring-[#56a0ff]/25",
            "dark:bg-[#0f141d]/80 dark:text-[#eef3ff] dark:placeholder:text-[#8f9db7]",
            emailError
              ? "border-[#f06a6f] focus:border-[#e5484d]"
              : "border-[#b8c4de] focus:border-[#2f80ff] dark:border-[#2f3b52] dark:focus:border-[#56a0ff]",
            isLoading || disabled ? "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-[#b91c1c] dark:text-[#fda4af]"
            role="alert"
          >
            {emailError}
          </p>
        )}
      </div>

      <div>
        <label
          htmlFor="login-password"
          className="mb-2 block text-[0.72rem] font-semibold uppercase tracking-[0.08em] text-[#2f3b52] dark:text-[#c5d0e6]"
        >
          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 || disabled}
          autoComplete="current-password"
          className={[
            "w-full rounded-lg border px-3.5 py-2.5 text-sm",
            "bg-[#f8faff]/90 text-[#0f141d] placeholder:text-[#5a6a87]",
            "transition-colors focus:outline-none focus:ring-2 focus:ring-[#56a0ff]/25",
            "dark:bg-[#0f141d]/80 dark:text-[#eef3ff] dark:placeholder:text-[#8f9db7]",
            passwordError
              ? "border-[#f06a6f] focus:border-[#e5484d]"
              : "border-[#b8c4de] focus:border-[#2f80ff] dark:border-[#2f3b52] dark:focus:border-[#56a0ff]",
            isLoading || disabled ? "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-[#b91c1c] dark:text-[#fda4af]"
            role="alert"
          >
            {passwordError}
          </p>
        )}
      </div>

      <button
        type="submit"
        disabled={isLoading || disabled}
        className={[
          "w-full inline-flex items-center justify-center gap-2 rounded-lg px-4 py-3 text-sm font-semibold text-white",
          "bg-[linear-gradient(135deg,#2f80ff,#8b5cf6)]",
          "transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-[#56a0ff]/60",
          "hover:-translate-y-0.5 hover:shadow-[0_10px_30px_rgba(47,128,255,0.38)]",
          isLoading || disabled ? "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>
  );
}
