"use client";

import { useId, useState, type FormEvent } from "react";
import { CheckCircle2, Loader2 } from "lucide-react";
import type { LeadFormBlock } from "@/lib/chat/types";
import { cn } from "@/lib/utils";
import { useChatBlocks } from "../ChatBlockContext";
import {
  BlockCard,
  Field,
  FormClosedNote,
  FormHeader,
  cancelButtonClass,
  describedBy,
  fieldErrorsFrom,
  inputClass,
  primaryButtonClass,
  useFormDismiss,
} from "./shared";

const TEXT_MAX = 2000;
const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

type FieldName = "name" | "contact_number" | "email" | "requirement" | "delivery_location";
type Errors = Partial<Record<FieldName, string>>;

const FIELDS: readonly FieldName[] = ["name", "contact_number", "email", "requirement", "delivery_location"];

const onlyDigits = (value: string) => value.replace(/\D/g, "").slice(-10);

/** Guest callback request → `lead.submit`. */
export default function LeadForm({ block, formKey }: { block: LeadFormBlock; formKey: string }) {
  const { copy, busy, pendingFormKey, isFormSubmitted, sendAction } = useChatBlocks();
  const id = useId();
  const prefill = block.prefill ?? {};

  const [name, setName] = useState(() => prefill.name ?? "");
  const [phone, setPhone] = useState(() => (prefill.contact_number ? onlyDigits(prefill.contact_number) : ""));
  const [email, setEmail] = useState(() => prefill.email ?? "");
  const [requirement, setRequirement] = useState("");
  const [location, setLocation] = useState("");
  const [errors, setErrors] = useState<Errors>({});
  const [formError, setFormError] = useState<string | null>(null);

  const submitted = isFormSubmitted(formKey);
  const submitting = pendingFormKey === formKey;
  const locked = submitted || busy;
  const { dismissed, canClose, close } = useFormDismiss(formKey);

  const f: Record<FieldName, string> = {
    name: `${id}-name`,
    contact_number: `${id}-phone`,
    email: `${id}-email`,
    requirement: `${id}-requirement`,
    delivery_location: `${id}-location`,
  };

  if (dismissed && !submitted) return <FormClosedNote />;

  if (submitted) {
    return (
      <BlockCard>
        <p className="flex items-center gap-1.5 font-semibold text-emerald-700">
          <CheckCircle2 size={14} aria-hidden /> {copy.leadSubmitted}
        </p>
      </BlockCard>
    );
  }

  function validate(): Errors {
    const next: Errors = {};
    if (!name.trim()) next.name = copy.errName;
    if (!/^\d{10}$/.test(phone)) next.contact_number = copy.errPhone;
    if (email.trim() && !EMAIL_RE.test(email.trim())) next.email = copy.errEmail;
    if (!requirement.trim()) next.requirement = copy.errRequirement;
    return next;
  }

  async function onSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    if (locked) return;
    const found = validate();
    setErrors(found);
    setFormError(null);
    if (Object.keys(found).length) return;

    const payload: Record<string, unknown> = {
      name: name.trim(),
      contact_number: phone,
      requirement: requirement.trim().slice(0, TEXT_MAX),
    };
    if (email.trim()) payload.email = email.trim();
    if (location.trim()) payload.delivery_location = location.trim();

    const error = await sendAction({ type: "lead.submit", payload }, { formKey, inlineValidation: true });
    if (error?.kind === "validation") {
      const mapped: Errors = {};
      for (const [field, message] of Object.entries(fieldErrorsFrom(error.errors))) {
        if ((FIELDS as readonly string[]).includes(field)) mapped[field as FieldName] = message;
      }
      setErrors(mapped);
      if (!Object.keys(mapped).length) setFormError(error.message);
    }
  }

  return (
    <BlockCard>
      <FormHeader title={copy.leadFormTitle} onClose={close} canClose={canClose} />
      <form onSubmit={onSubmit} noValidate className="space-y-2.5">
        <fieldset disabled={locked} className="space-y-2.5">
          <Field id={f.name} label={copy.name} required error={errors.name}>
            <input
              id={f.name}
              type="text"
              autoComplete="name"
              maxLength={120}
              value={name}
              onChange={(e) => setName(e.target.value)}
              className={inputClass}
              {...describedBy(f.name, errors.name)}
            />
          </Field>
          <Field id={f.contact_number} label={copy.contactNumber} required error={errors.contact_number}>
            <input
              id={f.contact_number}
              type="tel"
              inputMode="numeric"
              autoComplete="tel-national"
              maxLength={10}
              value={phone}
              onChange={(e) => setPhone(e.target.value.replace(/\D/g, "").slice(0, 10))}
              placeholder="98XXXXXXXX"
              className={inputClass}
              {...describedBy(f.contact_number, errors.contact_number)}
            />
          </Field>
          <Field id={f.email} label={copy.email} optional error={errors.email}>
            <input
              id={f.email}
              type="email"
              inputMode="email"
              autoComplete="email"
              value={email}
              onChange={(e) => setEmail(e.target.value)}
              className={inputClass}
              {...describedBy(f.email, errors.email)}
            />
          </Field>
          <Field id={f.requirement} label={copy.requirement} required error={errors.requirement}>
            <textarea
              id={f.requirement}
              rows={3}
              maxLength={TEXT_MAX}
              value={requirement}
              onChange={(e) => setRequirement(e.target.value)}
              placeholder={copy.requirementPlaceholder}
              className={cn(inputClass, "resize-none")}
              {...describedBy(f.requirement, errors.requirement)}
            />
          </Field>
          <Field id={f.delivery_location} label={copy.deliveryLocation} optional error={errors.delivery_location}>
            <input
              id={f.delivery_location}
              type="text"
              autoComplete="address-level2"
              maxLength={190}
              value={location}
              onChange={(e) => setLocation(e.target.value)}
              placeholder={copy.cityPlaceholder}
              className={inputClass}
              {...describedBy(f.delivery_location, errors.delivery_location)}
            />
          </Field>
        </fieldset>

        {formError ? (
          <p role="alert" className="rounded-md bg-red-50 px-2 py-1.5 text-[11px] text-red-700">
            {formError}
          </p>
        ) : null}

        <div className="grid grid-cols-[auto_1fr] gap-2">
          <button type="button" onClick={close} disabled={!canClose} className={cancelButtonClass}>
            {copy.cancel}
          </button>
          <button type="submit" disabled={locked} className={primaryButtonClass}>
            {submitting ? (
              <>
                <Loader2 size={13} className="animate-spin" aria-hidden /> {copy.submitting}
              </>
            ) : (
              copy.submitLead
            )}
          </button>
        </div>
      </form>
    </BlockCard>
  );
}
