"use client";

import { useState } from "react";
import { services } from "@/lib/content/services";

type FieldKey = "name" | "email" | "company" | "message";

const validators: Record<FieldKey, { test: (v: string) => boolean; msg: string }> = {
  name: { test: (v) => v.trim().length >= 2, msg: "Please enter your name." },
  email: {
    test: (v) => /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(v.trim()),
    msg: "Please enter a valid work email.",
  },
  company: { test: (v) => v.trim().length >= 2, msg: "Please enter your company name." },
  message: {
    test: (v) => v.trim().length >= 20,
    msg: "Tell us a little more — at least 20 characters.",
  },
};

export default function ContactForm({
  initialTopic,
  initialMessage,
}: {
  initialTopic?: string;
  initialMessage?: string;
}) {
  const [values, setValues] = useState({
    name: "",
    email: "",
    company: "",
    phone: "",
    service: initialTopic ?? "",
    budget: "",
    message: initialMessage ?? "",
  });
  const [errors, setErrors] = useState<Partial<Record<FieldKey, string>>>({});
  const [state, setState] = useState<"idle" | "sending" | "sent" | "failed">("idle");

  const set = (k: keyof typeof values) => (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>) => {
    setValues((v) => ({ ...v, [k]: e.target.value }));
    if (k in errors) {
      setErrors((prev) => {
        const next = { ...prev };
        delete next[k as FieldKey];
        return next;
      });
    }
  };

  const validate = (): boolean => {
    const next: Partial<Record<FieldKey, string>> = {};
    (Object.keys(validators) as FieldKey[]).forEach((k) => {
      if (!validators[k].test(values[k])) next[k] = validators[k].msg;
    });
    setErrors(next);
    if (Object.keys(next).length) {
      const first = Object.keys(next)[0];
      document.getElementById(`f-${first}`)?.focus();
      return false;
    }
    return true;
  };

  const submit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!validate()) return;
    setState("sending");
    try {
      const res = await fetch("/api/inquiries", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(values),
      });
      if (!res.ok) throw new Error(String(res.status));
      setState("sent");
    } catch {
      setState("failed");
    }
  };

  if (state === "sent") {
    return (
      <div className="rounded-2xl border border-black/10 bg-white p-10 text-center" role="status">
        <span className="mx-auto grid h-16 w-16 place-items-center rounded-full bg-azure/10 text-azure-deep">
          <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" aria-hidden>
            <path d="M4 12.5 l5 5 L20 6.5" />
          </svg>
        </span>
        <h3 className="mt-5 text-2xl font-semibold text-lhi">Inquiry received.</h3>
        <p className="mt-2.5 text-[0.95rem] text-lmid">
          It&apos;s in our queue — a senior engineer will reply within one business day.
        </p>
        <p className="ar mt-4 text-lg text-azure-deep" lang="ar">
          شكراً لتواصلكم
        </p>
      </div>
    );
  }

  const err = (k: FieldKey) =>
    errors[k] ? (
      <span id={`err-${k}`} className="text-[0.8rem] text-[#A8431F]" role="alert">
        {errors[k]}
      </span>
    ) : null;

  const invalid = (k: FieldKey) => (errors[k] ? true : undefined);
  const describedBy = (k: FieldKey) => (errors[k] ? `err-${k}` : undefined);

  return (
    <form
      onSubmit={submit}
      noValidate
      className="rounded-2xl border border-black/10 bg-white p-7 shadow-[0_30px_60px_-40px_rgba(11,27,51,0.25)] md:p-10"
    >
      <div className="grid gap-5 sm:grid-cols-2">
        <div className="grid gap-1.5">
          <label htmlFor="f-name" className="field-label">
            Full name <span className="text-azure">*</span>
          </label>
          <input id="f-name" className="field-input" autoComplete="name" value={values.name} onChange={set("name")} aria-invalid={invalid("name")} aria-describedby={describedBy("name")} />
          {err("name")}
        </div>
        <div className="grid gap-1.5">
          <label htmlFor="f-email" className="field-label">
            Work email <span className="text-azure">*</span>
          </label>
          <input id="f-email" type="email" className="field-input" autoComplete="email" value={values.email} onChange={set("email")} aria-invalid={invalid("email")} aria-describedby={describedBy("email")} />
          {err("email")}
        </div>
        <div className="grid gap-1.5">
          <label htmlFor="f-company" className="field-label">
            Company <span className="text-azure">*</span>
          </label>
          <input id="f-company" className="field-input" autoComplete="organization" value={values.company} onChange={set("company")} aria-invalid={invalid("company")} aria-describedby={describedBy("company")} />
          {err("company")}
        </div>
        <div className="grid gap-1.5">
          <label htmlFor="f-phone" className="field-label">
            Phone
          </label>
          <input id="f-phone" type="tel" className="field-input" autoComplete="tel" placeholder="+966 5X XXX XXXX" value={values.phone} onChange={set("phone")} />
        </div>
        <div className="grid gap-1.5">
          <label htmlFor="f-service" className="field-label">
            Service interest
          </label>
          <select id="f-service" className="field-input" value={values.service} onChange={set("service")}>
            <option value="">Select a service…</option>
            {services.map((s) => (
              <option key={s.slug}>{s.name}</option>
            ))}
            <option>Hosting & domains</option>
            <option>A readymade product</option>
            <option>Not sure yet</option>
          </select>
        </div>
        <div className="grid gap-1.5">
          <label htmlFor="f-budget" className="field-label">
            Indicative budget
          </label>
          <select id="f-budget" className="field-input" value={values.budget} onChange={set("budget")}>
            <option value="">Select a range…</option>
            <option>Under SAR 100k</option>
            <option>SAR 100k – 500k</option>
            <option>SAR 500k – 2M</option>
            <option>SAR 2M+</option>
          </select>
        </div>
      </div>
      <div className="mt-5 grid gap-1.5">
        <label htmlFor="f-message" className="field-label">
          Project brief <span className="text-azure">*</span>
        </label>
        <textarea
          id="f-message"
          rows={5}
          className="field-input resize-y"
          placeholder="What are you building, and what does success look like?"
          value={values.message}
          onChange={set("message")}
          aria-invalid={invalid("message")}
          aria-describedby={describedBy("message")}
        />
        {err("message")}
      </div>

      {state === "failed" && (
        <p className="mt-4 rounded-lg border border-[#D96B4A]/40 bg-[#D96B4A]/10 px-4 py-3 text-[0.9rem] text-[#8A3A20]" role="alert">
          The inquiry could not be sent — please retry, or write to hello@vira.sa directly.
        </p>
      )}

      <button type="submit" disabled={state === "sending"} className="btn btn-primary mt-6 w-full disabled:opacity-60">
        {state === "sending" ? "Sending…" : "Send inquiry"}{" "}
        <span className="arrow" aria-hidden>
          →
        </span>
      </button>
      <p className="mt-4 text-center text-[0.8rem] leading-relaxed text-llo">
        Your details are processed under the Saudi Personal Data Protection Law (PDPL) as described
        in our{" "}
        <a href="/privacy" className="underline decoration-azure-deep/40 underline-offset-2 hover:text-azure-deep">
          privacy notice
        </a>
        .
      </p>
    </form>
  );
}
