import { useState, type FormEvent } from "react";
import { useNavigate, useSearchParams, Navigate } from "react-router-dom";
import { useAuth } from "@/auth/useAuth";

/**
 * Sign-in screen. Mounted by the `/login` route in `App.tsx`, which
 * sits outside `<RequireAuth>` so unauthenticated operators can reach
 * it. The page is also reachable via the auto-redirect on a 401 from
 * `authedFetch` — that path appends `?next=<current>` so the operator
 * lands back on the page they were trying to view.
 *
 * Error mapping is driven by the backend's `error` code on the
 * `ApiError` thrown from `authApi.login`. The codes are defined in
 * `backend/src/cyclone/auth/routes.py::login`.
 */
export function Login() {
  const { user, login } = useAuth();
  const [params] = useSearchParams();
  const next = params.get("next") ?? "/";
  const navigate = useNavigate();
  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");
  const [error, setError] = useState<string | null>(null);
  const [submitting, setSubmitting] = useState(false);

  // Already authenticated — bounce to the original destination (or
  // dashboard) so we don't show a sign-in form to a logged-in user.
  if (user) return <Navigate to={next} replace />;

  async function onSubmit(e: FormEvent) {
    e.preventDefault();
    setError(null);
    setSubmitting(true);
    try {
      await login(username, password);
      navigate(next, { replace: true });
    } catch (err) {
      const code = (err as { code?: string })?.code ?? "error";
      if (code === "invalid_credentials") {
        setError("Username or password is incorrect.");
      } else if (code === "account_disabled") {
        setError("Account is disabled. Contact your administrator.");
      } else if (code === "rate_limited") {
        setError("Too many attempts. Try again shortly.");
      } else {
        setError("Sign in failed. Try again.");
      }
    } finally {
      setSubmitting(false);
    }
  }

  return (
    <div className="min-h-screen flex items-center justify-center bg-background text-foreground p-6">
      <form
        onSubmit={onSubmit}
        className="w-full max-w-sm p-8 rounded-lg border border-border bg-card shadow-lg"
      >
        <h1 className="text-2xl font-semibold mb-1 tracking-tight">Cyclone</h1>
        <p className="text-sm text-muted-foreground mb-6">
          Sign in to continue.
        </p>
        <label className="block mb-4">
          <span className="text-sm font-medium">Username</span>
          <input
            type="text"
            value={username}
            onChange={(e) => setUsername(e.target.value)}
            required
            autoFocus
            autoComplete="username"
            className="mt-1 w-full px-3 py-2 rounded bg-background border border-border text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
          />
        </label>
        <label className="block mb-5">
          <span className="text-sm font-medium">Password</span>
          <input
            type="password"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
            required
            autoComplete="current-password"
            className="mt-1 w-full py-2 px-3 rounded bg-background border border-border text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
          />
        </label>
        {error ? (
          <div
            className="mb-4 text-sm text-red-400 bg-red-400/10 border border-red-400/30 rounded px-3 py-2"
            role="alert"
          >
            {error}
          </div>
        ) : null}
        <button
          type="submit"
          disabled={submitting}
          className="w-full py-2 rounded bg-primary text-primary-foreground font-medium disabled:opacity-50 hover:bg-primary/90 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
        >
          {submitting ? "Signing in…" : "Sign in"}
        </button>
      </form>
    </div>
  );
}
