"use client";

import { useState } from "react";
import Link from "next/link";
import { useSearchParams } from "next/navigation";
import { AnimatePresence, motion, useReducedMotion } from "motion/react";
import { contact } from "@/content/company";
import { getPath } from "@/content/paths";
import { SectionHeading } from "@/components/ui/SectionHeading";

type Status = "idle" | "sending" | "sent" | "error";

const DIVISIONS = [
  { value: "knitwear", label: "Knitwear" },
  { value: "denim", label: "Denim and woven" },
  { value: "workwear", label: "Workwear and uniforms" },
  { value: "yarn", label: "Yarn" },
  { value: "other", label: "Something else" },
];

/**
 * Enquiry form.
 *
 * Fields underline in thread gold as they take focus. The submit button carries
 * its own state so the visitor never wonders whether the thing sent, and if the
 * endpoint fails the message is handed back as a prefilled mailto rather than
 * being lost.
 */
export function InquiryForm() {
  const [status, setStatus] = useState<Status>("idle");
  const [errors, setErrors] = useState<Record<string, string>>({});
  const [mailto, setMailto] = useState<string>("");
  const reduced = useReducedMotion();

  // An unrecognised or missing intent resolves to null, which falls back to the
  // general form. Somebody following a stale link must never hit a dead end.
  const params = useSearchParams();
  const path = getPath(params.get("intent"));

  async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setStatus("sending");
    setErrors({});

    const data = Object.fromEntries(new FormData(event.currentTarget));

    // Built up front, so a failed request still leaves the visitor a way through.
    setMailto(buildMailto(data));

    try {
      const response = await fetch("/api/inquiry", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(data),
      });

      if (response.ok) {
        setStatus("sent");
        return;
      }

      const payload = (await response.json().catch(() => ({}))) as {
        errors?: Record<string, string>;
      };

      if (payload.errors) {
        setErrors(payload.errors);
        setStatus("idle");
        return;
      }

      setStatus("error");
    } catch {
      setStatus("error");
    }
  }

  if (status === "sent") {
    return (
      <motion.div
        initial={{ opacity: 0, y: 16 }}
        animate={{ opacity: 1, y: 0 }}
        transition={{ duration: reduced ? 0 : 0.6, ease: [0.16, 1, 0.3, 1] }}
        className="border border-[var(--thread)]/40 bg-[var(--thread)]/5 p-10"
        role="status"
      >
        <p className="eyebrow">Received</p>
        <h3 className="display-md mt-4 text-[1.75rem] text-[var(--cotton)]">
          Thank you. We will come back to you.
        </h3>
        <p className="mt-4 max-w-lg text-sm leading-relaxed text-[var(--melange)]">
          Enquiries are answered from Multan during Pakistan business hours. If
          it is urgent, {contact.phonePk} reaches the office directly.
        </p>
      </motion.div>
    );
  }

  return (
    <>
      <SectionHeading
        eyebrow={path ? "Enquiry" : "General enquiry"}
        title={path ? path.formTitle : "Start here."}
        lede={
          path
            ? path.formIntro
            : "The more you can tell us about the fabric, the quantity and the delivery window, the more useful our first reply will be."
        }
      />

      {path ? (
        <p className="mt-6 text-sm text-[var(--melange)]">
          Not the right route?{" "}
          <Link
            href="/contact"
            className="text-[var(--cotton)] underline decoration-[var(--thread)] underline-offset-4"
          >
            Send a general enquiry instead
          </Link>
          .
        </p>
      ) : null}

      <form onSubmit={handleSubmit} noValidate className="mt-12 space-y-8">
        {/* Honeypot. Off screen rather than hidden, so bots that check computed
          styles still fill it. */}
      <div className="absolute left-[-9999px]" aria-hidden="true">
        <label htmlFor="website">Leave this field empty</label>
        <input id="website" name="website" type="text" tabIndex={-1} autoComplete="off" />
      </div>

      <div className="grid gap-8 sm:grid-cols-2">
        <Field
          name="name"
          label="Your name"
          required
          autoComplete="name"
          error={errors.name}
        />
        <Field
          name="company"
          label="Company"
          autoComplete="organization"
          error={errors.company}
        />
        <Field
          name="email"
          label="Email"
          type="email"
          required
          autoComplete="email"
          error={errors.email}
        />
        <Field
          name="country"
          label="Country"
          autoComplete="country-name"
          error={errors.country}
        />
      </div>

      {/* The path specific questions. A yarn trader is never asked about
          plackets, and an agent is never asked for an order quantity. With no
          recognised intent this falls back to the general pair below. */}
      {path ? (
        <div key={path.id} className="grid gap-8 sm:grid-cols-2">
          {path.fields.map((field) =>
            field.options ? (
              <Select
                key={field.name}
                name={field.name}
                label={field.label}
                options={field.options.map((o) => ({ value: o, label: o }))}
              />
            ) : (
              <Field
                key={field.name}
                name={field.name}
                label={field.label}
                placeholder={field.placeholder}
                error={errors[field.name]}
              />
            ),
          )}
        </div>
      ) : (
        <div className="grid gap-8 sm:grid-cols-2">
          <Select
            name="division"
            label="What are you sourcing?"
            options={DIVISIONS}
          />
          <Field
            name="quantity"
            label="Indicative quantity"
            placeholder="e.g. 20,000 pcs per style"
            error={errors.quantity}
          />
        </div>
      )}

      <input type="hidden" name="intent" value={path?.id ?? "general"} />

      <Field
        name="message"
        label={path ? "Anything else we should know?" : "What are you making?"}
        as="textarea"
        rows={5}
        required
        placeholder={
          path
            ? "As much or as little as you have. If there is a deadline, say so."
            : "Fabric, weight, colourways, target price, delivery window. As much or as little as you have."
        }
        error={errors.message}
      />

      <div className="flex flex-wrap items-center gap-5">
        <button
          type="submit"
          disabled={status === "sending"}
          className="group relative inline-flex items-center gap-3 overflow-hidden rounded-full bg-[var(--thread)] px-7 py-3.5 text-sm text-[var(--ink)] transition-opacity disabled:opacity-60"
        >
          <span className="relative z-10">
            {status === "sending" ? "Sending" : "Send enquiry"}
          </span>
          <span
            aria-hidden="true"
            className="relative z-10 transition-transform duration-500 ease-[cubic-bezier(0.16,1,0.3,1)] group-hover:translate-x-1"
          >
            {status === "sending" ? (
              <span className="inline-block animate-[shuttle_1.1s_ease-in-out_infinite]">
                &rarr;
              </span>
            ) : (
              <>&rarr;</>
            )}
          </span>
        </button>

        <p className="text-xs text-[var(--melange)]">
          Or write to{" "}
          <a
            href={`mailto:${contact.email}`}
            className="text-[var(--cotton)] underline decoration-[var(--thread)] underline-offset-4"
          >
            {contact.email}
          </a>
        </p>
      </div>

      <AnimatePresence>
        {status === "error" ? (
          <motion.div
            initial={{ opacity: 0, y: -8 }}
            animate={{ opacity: 1, y: 0 }}
            exit={{ opacity: 0 }}
            role="alert"
            className="border border-[var(--thread)]/40 bg-[var(--thread)]/5 p-5 text-sm text-[var(--cotton)]"
          >
            The form could not reach us just now.{" "}
            <a
              href={mailto}
              className="underline decoration-[var(--thread)] underline-offset-4"
            >
              Send the same message by email instead
            </a>
            , nothing you typed is lost.
          </motion.div>
        ) : null}
        </AnimatePresence>
      </form>
    </>
  );
}

function Field({
  name,
  label,
  type = "text",
  as = "input",
  rows,
  required,
  placeholder,
  autoComplete,
  error,
}: {
  name: string;
  label: string;
  type?: string;
  as?: "input" | "textarea";
  rows?: number;
  required?: boolean;
  placeholder?: string;
  autoComplete?: string;
  error?: string;
}) {
  const shared =
    "peer w-full border-b border-[var(--rule)] bg-transparent pb-3 pt-2 text-[var(--cotton)] placeholder:text-[var(--melange)]/60 focus:outline-none";

  return (
    <div className="relative">
      <label
        htmlFor={name}
        className="font-mono text-[10px] uppercase tracking-[0.2em] text-[var(--melange)]"
      >
        {label}
        {required ? <span className="text-[var(--thread)]"> *</span> : null}
      </label>

      {as === "textarea" ? (
        <textarea
          id={name}
          name={name}
          rows={rows}
          required={required}
          placeholder={placeholder}
          aria-invalid={error ? true : undefined}
          aria-describedby={error ? `${name}-error` : undefined}
          className={`${shared} mt-3 resize-y`}
        />
      ) : (
        <input
          id={name}
          name={name}
          type={type}
          required={required}
          placeholder={placeholder}
          autoComplete={autoComplete}
          aria-invalid={error ? true : undefined}
          aria-describedby={error ? `${name}-error` : undefined}
          className={`${shared} mt-3`}
        />
      )}

      {/* The thread that runs along the field as it takes focus. */}
      <span
        aria-hidden="true"
        className="absolute inset-x-0 bottom-0 block h-px origin-left scale-x-0 bg-[var(--thread)] transition-transform duration-500 ease-[cubic-bezier(0.16,1,0.3,1)] peer-focus:scale-x-100"
      />

      {error ? (
        <p id={`${name}-error`} className="mt-2 text-xs text-[var(--thread)]">
          {error}
        </p>
      ) : null}
    </div>
  );
}

function Select({
  name,
  label,
  options,
}: {
  name: string;
  label: string;
  options: Array<{ value: string; label: string }>;
}) {
  return (
    <div className="relative">
      <label
        htmlFor={name}
        className="font-mono text-[10px] uppercase tracking-[0.2em] text-[var(--melange)]"
      >
        {label}
      </label>
      <select
        id={name}
        name={name}
        defaultValue=""
        className="peer mt-3 w-full appearance-none border-b border-[var(--rule)] bg-transparent pb-3 pt-2 text-[var(--cotton)] focus:outline-none"
      >
        <option value="" className="bg-[var(--ink)]">
          Select a division
        </option>
        {options.map((option) => (
          <option key={option.value} value={option.value} className="bg-[var(--ink)]">
            {option.label}
          </option>
        ))}
      </select>
      <span
        aria-hidden="true"
        className="absolute inset-x-0 bottom-0 block h-px origin-left scale-x-0 bg-[var(--thread)] transition-transform duration-500 ease-[cubic-bezier(0.16,1,0.3,1)] peer-focus:scale-x-100"
      />
    </div>
  );
}

function buildMailto(data: Record<string, FormDataEntryValue>): string {
  const lines = [
    `Name: ${data.name ?? ""}`,
    `Company: ${data.company ?? ""}`,
    `Country: ${data.country ?? ""}`,
    `Division: ${data.division ?? ""}`,
    `Quantity: ${data.quantity ?? ""}`,
    "",
    String(data.message ?? ""),
  ].join("\n");

  const subject = `Website enquiry: ${data.company || data.name || "new enquiry"}`;

  return `mailto:${contact.email}?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(lines)}`;
}
