"use client";

import { useId, useRef, useState, type FormEvent } from "react";
import { useSearchParams } from "next/navigation";
import Link from "next/link";
import { Button } from "@/components/ui/button";
import {
  emailError,
  normalizeEmail,
  validationA11yProps,
} from "./model";
import { postAuthRequest } from "./auth-client";

export function RecoveryForm({ apiEnabled }: { apiEnabled: boolean }) {
  const params = useSearchParams();
  const pending = useRef(false);
  const emailId = useId();
  const [email, setEmail] = useState(params.get("email") ?? "");
  const [validationError, setValidationError] = useState("");
  const [requestError, setRequestError] = useState("");
  const [submitted, setSubmitted] = useState(false);
  const [busy, setBusy] = useState(false);

  async function submit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    if (pending.current || !apiEnabled) return;
    setValidationError("");
    setRequestError("");
    setSubmitted(false);
    const nextValidationError = emailError(email);
    if (nextValidationError) {
      setValidationError(nextValidationError);
      return;
    }
    pending.current = true;
    setBusy(true);
    const result = await postAuthRequest("reset", {
      email: normalizeEmail(email),
    });
    pending.current = false;
    setBusy(false);
    if (!result.ok) {
      setRequestError(result.error);
      return;
    }
    setSubmitted(true);
  }

  if (!apiEnabled) {
    return (
      <div className="space-y-4">
        <p role="alert" className="rounded-lg border border-destructive/30 bg-card p-3 text-sm leading-6">
          Password recovery is unavailable because the authentication service is not configured.
        </p>
        <Link
          href="/signin"
          className="text-sm text-auth-action hover:underline"
          prefetch={false}
        >
          Back to sign in
        </Link>
      </div>
    );
  }

  return (
    <div className="space-y-5">
      {submitted ? (
        <>
          <p role="status" className="rounded-lg border bg-muted/40 p-4 text-sm leading-6">
            If the account is eligible, password reset instructions will be
            sent. Check your inbox and follow the link to choose a new
            password.
          </p>
          <Button
            variant="outline"
            className="w-full"
            onClick={() => setSubmitted(false)}
          >
            Try another email
          </Button>
        </>
      ) : (
        <form onSubmit={submit} noValidate className="space-y-5">
          <div>
            <label htmlFor={emailId} className="field-label">
              Email <span className="text-destructive">*</span>
            </label>
            <input
              id={emailId}
              name="email"
              className="form-input"
              type="email"
              autoComplete="email"
              value={email}
              onChange={(event) => {
                setEmail(event.target.value);
                setValidationError("");
                setRequestError("");
              }}
              placeholder="info@gmail.com"
              {...validationA11yProps(validationError, `${emailId}-error`)}
              required
            />
            {validationError && (
              <p
                id={`${emailId}-error`}
                role="alert"
                className="mt-1 text-sm text-destructive"
              >
                {validationError}
              </p>
            )}
          </div>
          {requestError && (
            <p role="alert" className="text-sm text-destructive">
              {requestError}
            </p>
          )}
          <Button variant="auth" className="w-full" disabled={busy}>
            {busy ? "Sending request…" : "Send reset instructions"}
          </Button>
        </form>
      )}
      <Link
        href={
          "/signin?" + new URLSearchParams({ email: normalizeEmail(email) })
        }
        className="text-sm text-auth-action hover:underline"
        prefetch={false}
      >
        Back to sign in
      </Link>
    </div>
  );
}
