"use client";
import { useCallback, useRef, useState } from "react";
import { Toaster, toast } from "sonner";
import { contactResponseSchema, interests } from "@/lib/contact-schema";
import {
  quickApplyFieldNames,
  quickApplySchema,
} from "@/lib/quick-apply-schema";
import { Turnstile } from "./turnstile";
import { CHECK_FIELDS, useFieldValidation } from "./use-field-validation";
type Field = {
  name: string;
  label: string;
  placeholder: string;
  type: "text" | "tel" | "email" | "select";
  autoComplete: string;
  inputMode?: "decimal";
  max: number;
};
const fields: readonly Field[] = [
  {
    name: "name",
    label: "Full Name",
    placeholder: "Full Name *",
    type: "text",
    autoComplete: "name",
    max: 100,
  },
  {
    name: "phone",
    label: "Contact Number",
    placeholder: "Contact Number *",
    type: "tel",
    autoComplete: "tel",
    max: 30,
  },
  {
    name: "email",
    label: "Email",
    placeholder: "Email *",
    type: "email",
    autoComplete: "email",
    max: 254,
  },
  {
    name: "interest",
    label: "Purpose of Loan",
    placeholder: "Purpose of Loan *",
    type: "select",
    autoComplete: "off",
    max: 0,
  },
  {
    name: "monthlyIncome",
    label: "Monthly Income",
    placeholder: "Enter Your Monthly Income *",
    type: "text",
    autoComplete: "off",
    inputMode: "decimal",
    max: 24,
  },
  {
    name: "loanAmount",
    label: "Desired Loan Amount",
    placeholder: "Enter Your Desired Loan Amount *",
    type: "text",
    autoComplete: "off",
    inputMode: "decimal",
    max: 24,
  },
];
const SECURITY_CHECK = "Please complete the security check before sending.";
export function QuickApplyForm({
  mock,
  siteKey,
}: {
  mock: boolean;
  siteKey?: string;
}) {
  const { errors, flush, onChange, onBlur, report, clear, reset } =
    useFieldValidation(quickApplySchema);
  const [status, setStatus] = useState("");
  const [busy, setBusy] = useState(false);
  const [token, setToken] = useState("");
  const [resetKey, setResetKey] = useState(0);
  const pending = useRef(false),
    intent = useRef<{ data: string; id: string } | null>(null);
  if (status === CHECK_FIELDS && !Object.keys(errors).length) setStatus("");
  const onToken = useCallback(
    (value: string) => {
      setToken(value);
      if (value) {
        setStatus((s) => (s === SECURITY_CHECK ? "" : s));
        flush(true);
      }
    },
    [flush],
  );
  async function submit(event: React.SubmitEvent<HTMLFormElement>) {
    event.preventDefault();
    if (pending.current) return;
    const form = event.currentTarget,
      data = Object.fromEntries(new FormData(form));
    const parsed = quickApplySchema.safeParse(data);
    if (!parsed.success) {
      const first = report(parsed.error.issues);
      setStatus(CHECK_FIELDS);
      form.querySelector<HTMLInputElement>(`[name="${first}"]`)?.focus();
      return;
    }
    clear();
    if (siteKey && !token) {
      setStatus(SECURITY_CHECK);
      return;
    }
    const serialized = JSON.stringify(parsed.data);
    if (intent.current?.data !== serialized)
      intent.current = { data: serialized, id: crypto.randomUUID() };
    const entered = Object.fromEntries(
      quickApplyFieldNames.map((name) => [name, String(data[name] ?? "")]),
    );
    pending.current = true;
    setBusy(true);
    setStatus("");
    try {
      const response = await fetch("/api/quick-apply", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        signal: AbortSignal.timeout(25000),
        body: JSON.stringify({
          ...entered,
          website: data.website || "",
          turnstileToken: token || "quick-apply-unchallenged",
          requestId: intent.current.id,
        }),
      });
      const result = contactResponseSchema.parse(await response.json());
      setStatus(result.message);
      if (response.ok && result.ok) {
        form.reset();
        reset();
        intent.current = null;
        toast.success(result.message);
      }
    } catch {
      setStatus(
        "We could not confirm your request was sent. Your details are still here; please retry or call 6336 4144.",
      );
    } finally {
      pending.current = false;
      setBusy(false);
      setToken("");
      setResetKey((n) => n + 1);
    }
  }
  const describe = (name: string) => ({
    "aria-invalid": Boolean(errors[name]),
    "aria-describedby": errors[name] ? `quick-error-${name}` : undefined,
  });
  return (
    <section
      className="quick-apply-form-section"
      aria-labelledby="quick-apply-form-title"
    >
      <div className="inner-container">
        <h2 id="quick-apply-form-title" className="sr-only">
          Quick apply form
        </h2>
        <form
          className="quick-apply-card"
          noValidate
          onSubmit={submit}
          onChange={onChange}
          onBlur={onBlur}
        >
          <fieldset disabled={busy}>
            <legend className="sr-only">Your details</legend>
            {fields.map((field) => (
              <div className="quick-apply-field form-field" key={field.name}>
                <label className="sr-only" htmlFor={`quick-${field.name}`}>
                  {field.label}
                </label>
                {field.type === "select" ? (
                  <select
                    id={`quick-${field.name}`}
                    name={field.name}
                    defaultValue=""
                    required
                    {...describe(field.name)}
                  >
                    <option value="">{field.placeholder}</option>
                    {interests.map((interest) => (
                      <option key={interest}>{interest}</option>
                    ))}
                  </select>
                ) : (
                  <input
                    id={`quick-${field.name}`}
                    name={field.name}
                    type={field.type}
                    inputMode={field.inputMode}
                    autoComplete={field.autoComplete}
                    maxLength={field.max}
                    placeholder={field.placeholder}
                    required
                    {...describe(field.name)}
                  />
                )}
                {errors[field.name] && (
                  <p className="form-error" id={`quick-error-${field.name}`}>
                    {errors[field.name]}
                  </p>
                )}
              </div>
            ))}
            <div className="contact-honeypot" aria-hidden="true">
              <label htmlFor="quick-website">Leave this field empty</label>
              <input
                id="quick-website"
                name="website"
                tabIndex={-1}
                autoComplete="off"
              />
            </div>
            <div className="quick-apply-full">
              <Turnstile
                mock={mock}
                siteKey={siteKey}
                resetKey={resetKey}
                onToken={onToken}
                action="quick-apply"
              />
            </div>
            <button className="site-button quick-apply-full" type="submit">
              {busy ? "SENDING…" : "SUBMIT"}
              <svg
                aria-hidden="true"
                width="18"
                height="18"
                viewBox="0 0 512 512"
                fill="currentColor"
              >
                <path d="M444.52 3.52 28.74 195.42c-47.97 22.39-31.98 92.75 19.19 92.75h175.91v175.91c0 51.17 70.36 67.17 92.75 19.19l191.9-415.78c15.99-35.18-19.2-70.37-55.97-51.99z" />
              </svg>
            </button>
          </fieldset>
          <p className="quick-apply-status" role="status" aria-live="polite">
            {status}
          </p>
        </form>
      </div>
      <Toaster />
    </section>
  );
}
