"use client";

import Link from "next/link";
import { useActionState, useEffect, useId, useRef, type ReactNode } from "react";
import { submitLead, type LeadFormState } from "@/app/actions/submit-lead";
import { Alert, ArrowRight, Check } from "@/components/ui/Icons";
import { cn } from "@/lib/cn";
import type { LeadField } from "@/lib/lead";
import { routes } from "@/lib/routes";

const initialState: LeadFormState = { status: "idle" };

const spendOptions = [
  { value: "", label: "Select a range" },
  { value: "none", label: "Not running paid media yet" },
  { value: "under-10k", label: "Under $10k per month" },
  { value: "10k-50k", label: "$10k–$50k per month" },
  { value: "50k-150k", label: "$50k–$150k per month" },
  { value: "150k-plus", label: "$150k+ per month" },
  { value: "not-sure", label: "Not sure" },
];

const inputClass =
  "block w-full rounded-sm border border-line-strong bg-surface px-3.5 text-[1rem] text-ink placeholder:text-muted/80 transition-colors focus:border-ink focus:outline-2 focus:outline-offset-2 focus:outline-signal aria-[invalid=true]:border-ink";

function Field({
  id,
  label,
  hint,
  error,
  optional,
  children,
}: {
  id: string;
  label: string;
  hint?: string;
  error?: string;
  optional?: boolean;
  children: ReactNode;
}) {
  return (
    <div>
      <label htmlFor={id} className="flex items-baseline justify-between gap-3 text-sm font-medium">
        {label}
        {optional ? <span className="text-xs font-normal text-muted">Optional</span> : null}
      </label>
      {hint ? (
        <p id={`${id}-hint`} className="mt-1 text-sm text-muted">
          {hint}
        </p>
      ) : null}
      <div className="mt-2">{children}</div>
      {error ? (
        <p id={`${id}-error`} className="mt-2 flex items-center gap-1.5 text-sm font-medium text-ink">
          <Alert size={14} className="shrink-0 text-signal" />
          {error}
        </p>
      ) : null}
    </div>
  );
}

/**
 * Growth Audit and contact form. The same DOM is server-rendered and hydrated in place, so anything a
 * visitor types before hydration is kept. Diagnostic prefill (?model=&focus=) is applied after mount.
 */
export function LeadForm({ intent }: { intent: "audit" | "contact" }) {
  const [state, formAction, pending] = useActionState(submitLead, initialState);
  const formId = useId();
  const formRef = useRef<HTMLFormElement>(null);
  const startedRef = useRef<HTMLInputElement>(null);
  const focusRef = useRef<HTMLInputElement>(null);
  const statusRef = useRef<HTMLDivElement>(null);

  const errors = state.fieldErrors ?? {};
  const values = state.values ?? {};

  useEffect(() => {
    if (startedRef.current) startedRef.current.value = String(Date.now());
    const params = new URLSearchParams(window.location.search);
    if (focusRef.current) focusRef.current.value = (params.get("focus") ?? "").replace(/[^a-z,]/g, "").slice(0, 80);
    const model = params.get("model");
    const form = formRef.current;
    if (form && model && !form.querySelector("input[name=model]:checked")) {
      const option = form.querySelector<HTMLInputElement>(`input[name=model][value="${model.replace(/[^a-z]/g, "")}"]`);
      if (option) option.checked = true;
    }
  }, []);

  useEffect(() => {
    if (state.status !== "idle") statusRef.current?.focus();
  }, [state]);

  const describedBy = (field: LeadField, hint = false) =>
    [hint ? `${formId}-${field}-hint` : null, errors[field] ? `${formId}-${field}-error` : null].filter(Boolean).join(" ") || undefined;

  if (state.status === "success") {
    return (
      <div ref={statusRef} tabIndex={-1} role="status" className="rounded-lg border border-line bg-surface p-8 focus:outline-none">
        <span className="flex size-10 items-center justify-center rounded-full bg-signal text-white">
          <Check size={18} />
        </span>
        <h2 className="mt-6 text-display-md">{intent === "audit" ? "Request received." : "Message received."}</h2>
        <p className="mt-4 text-ink-soft">
          {intent === "audit"
            ? "Thank you. We'll review what you shared and reply by email with next steps, including any access we'd need for the review."
            : "Thank you. We'll read your message and reply by email."}
        </p>
        <Link href={routes.resources} className="group mt-6 inline-flex items-center gap-2 font-medium">
          <span className="link-underline">Read our growth guides while you wait</span>
          <ArrowRight size={15} className="btn-arrow" />
        </Link>
      </div>
    );
  }

  const fieldId = (field: LeadField) => `${formId}-${field}`;

  return (
    <form ref={formRef} action={formAction} className="space-y-6" aria-describedby={state.status === "error" ? `${formId}-status` : undefined}>
      {state.status === "error" ? (
        <div
          ref={statusRef}
          id={`${formId}-status`}
          tabIndex={-1}
          role="alert"
          className="flex gap-3 rounded-md border border-ink/20 bg-sand px-4 py-3 text-[0.9375rem] focus:outline-none"
        >
          <Alert size={18} className="mt-0.5 shrink-0" />
          <p>{state.message}</p>
        </div>
      ) : null}

      <input type="hidden" name="intent" value={intent} />
      <input ref={focusRef} type="hidden" name="focus" defaultValue={values.focus ?? ""} />
      <input ref={startedRef} type="hidden" name="started_at" defaultValue="" />
      <div aria-hidden="true" className="absolute -left-[9999px] h-px w-px overflow-hidden">
        <label htmlFor={`${formId}-company-role`}>Leave this field empty</label>
        <input id={`${formId}-company-role`} type="text" name="company_role" tabIndex={-1} autoComplete="off" defaultValue="" />
      </div>

      <div className="grid gap-6 sm:grid-cols-2">
        <Field id={fieldId("name")} label="Name" error={errors.name}>
          <input id={fieldId("name")} name="name" type="text" autoComplete="name" required minLength={2} maxLength={120} defaultValue={values.name} aria-invalid={Boolean(errors.name)} aria-describedby={describedBy("name")} className={cn(inputClass, "h-12")} />
        </Field>
        <Field id={fieldId("email")} label="Work email" error={errors.email}>
          <input id={fieldId("email")} name="email" type="email" autoComplete="email" required maxLength={200} defaultValue={values.email} aria-invalid={Boolean(errors.email)} aria-describedby={describedBy("email")} className={cn(inputClass, "h-12")} />
        </Field>
        <Field id={fieldId("company")} label="Company" error={errors.company}>
          <input id={fieldId("company")} name="company" type="text" autoComplete="organization" required maxLength={160} defaultValue={values.company} aria-invalid={Boolean(errors.company)} aria-describedby={describedBy("company")} className={cn(inputClass, "h-12")} />
        </Field>
        {intent === "audit" ? (
          <Field id={fieldId("website")} label="Website" optional error={errors.website}>
            <input id={fieldId("website")} name="website" type="text" inputMode="url" autoComplete="url" placeholder="example.com" maxLength={300} defaultValue={values.website} aria-invalid={Boolean(errors.website)} aria-describedby={describedBy("website")} className={cn(inputClass, "h-12")} />
          </Field>
        ) : null}
      </div>

      {intent === "audit" ? (
        <>
          <fieldset aria-describedby={errors.model ? `${fieldId("model")}-error` : undefined}>
            <legend className="text-sm font-medium">Business model</legend>
            <div className="mt-2 grid grid-cols-3 gap-2">
              {[
                { value: "saas", label: "SaaS" },
                { value: "ecommerce", label: "E-commerce" },
                { value: "other", label: "Other" },
              ].map((option) => (
                <label key={option.value} className="relative">
                  <input
                    type="radio"
                    name="model"
                    value={option.value}
                    required
                    defaultChecked={values.model === option.value}
                    className="peer absolute inset-0 cursor-pointer opacity-0"
                  />
                  <span className="pointer-events-none flex h-12 items-center justify-center rounded-sm border border-line-strong bg-surface text-[0.9375rem] transition-colors peer-checked:border-ink peer-checked:bg-ink peer-checked:text-paper peer-focus-visible:outline peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-signal">
                    {option.label}
                  </span>
                </label>
              ))}
            </div>
            {errors.model ? (
              <p id={`${fieldId("model")}-error`} className="mt-2 flex items-center gap-1.5 text-sm font-medium">
                <Alert size={14} className="text-signal" />
                {errors.model}
              </p>
            ) : null}
          </fieldset>

          <Field id={fieldId("spend")} label="Monthly paid-media spend (USD)" optional error={errors.spend}>
            <select id={fieldId("spend")} name="spend" defaultValue={values.spend ?? ""} aria-describedby={describedBy("spend")} className={cn(inputClass, "h-12 pr-10")}>
              {spendOptions.map((option) => (
                <option key={option.value} value={option.value}>
                  {option.label}
                </option>
              ))}
            </select>
          </Field>
        </>
      ) : null}

      <Field
        id={fieldId("message")}
        label={intent === "audit" ? "What's the biggest growth challenge right now?" : "Message"}
        hint={intent === "audit" ? "A sentence or two is enough. What's stuck, and what have you tried?" : undefined}
        optional={intent === "audit"}
        error={errors.message}
      >
        <textarea
          id={fieldId("message")}
          name="message"
          rows={intent === "audit" ? 4 : 6}
          maxLength={3000}
          required={intent === "contact"}
          defaultValue={values.message}
          aria-invalid={Boolean(errors.message)}
          aria-describedby={describedBy("message", intent === "audit")}
          className={cn(inputClass, "py-3")}
        />
      </Field>

      <div>
        <label className="flex gap-3 text-[0.9375rem]">
          <input
            type="checkbox"
            name="consent"
            value="yes"
            required
            defaultChecked={values.consent === "yes"}
            aria-invalid={Boolean(errors.consent)}
            aria-describedby={errors.consent ? `${fieldId("consent")}-error` : undefined}
            className="mt-1 size-4 shrink-0 accent-[var(--color-signal)]"
          />
          <span className="text-ink-soft">
            I agree that Axidys Limited may use these details to respond to my request, as described in the{" "}
            <Link href={routes.privacy} className="link-underline text-ink">
              privacy policy
            </Link>
            .
          </span>
        </label>
        {errors.consent ? (
          <p id={`${fieldId("consent")}-error`} className="mt-2 flex items-center gap-1.5 text-sm font-medium">
            <Alert size={14} className="text-signal" />
            {errors.consent}
          </p>
        ) : null}
      </div>

      <button
        type="submit"
        disabled={pending}
        className="btn inline-flex h-14 w-full items-center justify-center gap-3 rounded-md bg-signal px-6 font-medium text-white [--btn-fill:var(--color-ink)] disabled:cursor-wait disabled:opacity-70"
      >
        <span className="btn-fill" aria-hidden="true" />
        <span>{pending ? "Sending…" : intent === "audit" ? "Request my Growth Audit" : "Send message"}</span>
        {pending ? null : <ArrowRight size={16} className="btn-arrow" />}
      </button>
      <p className="text-center text-sm text-muted">No exaggerated promises. No generic deck.</p>
    </form>
  );
}
