"use client";

import { useState } from "react";
import Link from "next/link";
import { CheckCircle2 } from "lucide-react";
import { z } from "zod";
import { formsApi } from "@/lib/api/forms";
import { ApiException } from "@/lib/api/client";
import { useToken } from "@/lib/auth/useToken";
import {
  apiFieldErrors,
  emailField,
  fieldErrors,
  gstinField,
  mobileField,
  normalizeMobile,
  pincodeField,
  quantityField,
} from "@/lib/validation";
import FieldError from "@/components/ui/FieldError";

type FieldName =
  | "name"
  | "company_name"
  | "phone"
  | "email"
  | "gst_number"
  | "pincode"
  | "delivery_location"
  | "brand"
  | "product"
  | "quantity"
  | "requirement";

type Field = {
  name: FieldName;
  label: string;
  type?: string;
  required?: boolean;
  placeholder?: string;
  inputMode?: "numeric" | "decimal" | "tel" | "email";
  /** Strip what the field can never contain, as the user types. */
  clean?: (v: string) => string;
  wide?: boolean;
};

const FIELDS: Field[] = [
  { name: "name", label: "Your Name", required: true, placeholder: "Enter your full name" },
  { name: "company_name", label: "Company Name", placeholder: "Enter your company name" },
  { name: "phone", label: "Mobile", type: "tel", required: true, inputMode: "numeric", placeholder: "10-digit mobile number", clean: (v) => v.replace(/\D/g, "").slice(0, 10) },
  { name: "email", label: "Email", type: "email", placeholder: "Enter your work email" },
  { name: "gst_number", label: "GST Number", placeholder: "15-character GSTIN (if available)", clean: (v) => v.toUpperCase().replace(/[^0-9A-Z]/g, "").slice(0, 15) },
  { name: "pincode", label: "Delivery Pincode", required: true, inputMode: "numeric", placeholder: "6-digit pincode", clean: (v) => v.replace(/\D/g, "").slice(0, 6) },
  { name: "delivery_location", label: "Delivery City", placeholder: "e.g., Jaipur, Rajasthan" },
  { name: "brand", label: "Preferred Brand", placeholder: "e.g., Tata, JSW" },
  { name: "product", label: "Product / Commodity", required: true, placeholder: "e.g., TMT Bars" },
  { name: "quantity", label: "Quantity (MT)", required: true, inputMode: "decimal", placeholder: "e.g., 100", clean: (v) => v.replace(/[^\d.]/g, "") },
  { name: "requirement", label: "Specification", placeholder: "e.g., Fe500D, 12 mm and 16 mm", wide: true },
];

/** Same rules the `/enquiry` API applies (Phase 1A). */
const schema = z.object({
  name: z.string().trim().min(1, "Enter your name"),
  company_name: z.string().optional(),
  phone: mobileField(),
  email: emailField(false),
  gst_number: gstinField(false),
  pincode: pincodeField(),
  delivery_location: z.string().optional(),
  brand: z.string().optional(),
  product: z.string().trim().min(1, "Enter the product you need"),
  quantity: quantityField(),
  requirement: z.string().optional(),
});

/** API field → form field, for 422s. */
const API_FIELD: Partial<Record<string, FieldName>> = {
  contact_number: "phone",
  gst_number: "gst_number",
  pincode: "pincode",
  quantity: "quantity",
  email: "email",
  name: "name",
  product: "product",
};

/**
 * "Something else" on Post Requirement (4.5): a requirement for a product the
 * catalog does not carry, in the buyer's own words. Lands in admin under
 * General Enquiry, linked to the signed-in account.
 *
 * It used to post to the RFQ endpoint, which requires a catalog product id
 * this form never has, so every submission failed with a 422.
 */
export default function CustomRequirementForm() {
  const { token } = useToken();
  const [values, setValues] = useState<Partial<Record<FieldName, string>>>({});
  const [message, setMessage] = useState("");
  const [submitting, setSubmitting] = useState(false);
  const [errors, setErrors] = useState<Partial<Record<FieldName, string>>>({});
  const [err, setErr] = useState<string | null>(null);
  const [reference, setReference] = useState<string | null>(null);

  function update(field: Field, raw: string) {
    const v = field.clean ? field.clean(raw) : raw;
    setValues((p) => ({ ...p, [field.name]: v }));
    setErrors((e) => (e[field.name] ? { ...e, [field.name]: undefined } : e));
  }

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    setErr(null);
    const clientErrors = fieldErrors(schema, values) as Partial<Record<FieldName, string>>;
    setErrors(clientErrors);
    if (Object.keys(clientErrors).length > 0) return;

    setSubmitting(true);
    try {
      const res = await formsApi.enquiry(
        {
          name: values.name!.trim(),
          company_name: values.company_name || undefined,
          contact_number: normalizeMobile(values.phone ?? ""),
          email: values.email?.trim() || undefined,
          gst_number: values.gst_number || undefined,
          pincode: values.pincode,
          product: [values.product, values.brand ? `(${values.brand})` : ""].filter(Boolean).join(" "),
          quantity: values.quantity,
          quantity_unit: "MT",
          message: [values.requirement, values.delivery_location ? `Deliver to: ${values.delivery_location}` : "", message]
            .filter(Boolean)
            .join("\n") || undefined,
        },
        token
      );
      setReference(res.data?.reference ?? "submitted");
    } catch (e) {
      if (e instanceof ApiException && e.status === 422 && e.errors) {
        const mapped: Partial<Record<FieldName, string>> = {};
        for (const [key, msg] of Object.entries(apiFieldErrors(e.errors))) {
          const field = API_FIELD[key];
          if (field && msg) mapped[field] = msg;
        }
        setErrors(mapped);
        if (Object.keys(mapped).length === 0) setErr(e.message);
      } else {
        setErr(e instanceof Error ? e.message : "Submission failed");
      }
    } finally {
      setSubmitting(false);
    }
  }

  if (reference) {
    return (
      <div className="rounded-xl bg-white p-8 text-center shadow-sm ring-1 ring-gray-100">
        <CheckCircle2 className="mx-auto mb-3 h-12 w-12 text-emerald-600" />
        <h2 className="text-xl font-bold text-gray-900">Requirement submitted</h2>
        <p className="mt-1 text-sm text-gray-600">
          Reference <span className="font-mono font-semibold">{reference}</span>. Our team will call you with quotes.
        </p>
        <p className="mt-4 text-sm text-gray-600">
          Need a catalog product with live seller bids?{" "}
          <Link href="/rfq/new" className="font-semibold text-[#CC1414] hover:underline">
            Get live quotes
          </Link>
        </p>
      </div>
    );
  }

  return (
    <div className="space-y-4">
      <p className="text-sm text-gray-600">
        Describe what you need. Our team will come back with quotes from verified suppliers.
      </p>

      <form onSubmit={handleSubmit} noValidate className="space-y-4">
        <div className="grid grid-cols-1 gap-4 rounded-xl bg-white p-5 shadow-sm ring-1 ring-gray-100 sm:grid-cols-2">
          {FIELDS.map((f) => (
            <div key={f.name} className={f.wide ? "sm:col-span-2" : ""}>
              <label htmlFor={`enq-${f.name}`} className="mb-1 block text-sm font-medium text-gray-700">
                {f.label}
                {f.required && <span className="text-[#CC1414]"> *</span>}
              </label>
              <input
                id={`enq-${f.name}`}
                type={f.type ?? "text"}
                inputMode={f.inputMode}
                value={values[f.name] ?? ""}
                onChange={(e) => update(f, e.target.value)}
                placeholder={f.placeholder}
                aria-invalid={!!errors[f.name]}
                aria-describedby={`enq-${f.name}-err`}
                className={`w-full rounded-lg border px-3 py-2 text-sm focus:border-[#CC1414] focus:outline-none ${
                  errors[f.name] ? "border-[#CC1414]" : "border-gray-200"
                }`}
              />
              <FieldError id={`enq-${f.name}-err`} message={errors[f.name]} />
            </div>
          ))}
          <div className="sm:col-span-2">
            <label htmlFor="enq-message" className="mb-1 block text-sm font-medium text-gray-700">Additional Message</label>
            <textarea
              id="enq-message"
              value={message}
              onChange={(e) => setMessage(e.target.value)}
              rows={4}
              placeholder="Share delivery timeline, payment preference, or other details"
              className="w-full rounded-lg border border-gray-200 px-3 py-2 text-sm focus:border-[#CC1414] focus:outline-none"
            />
          </div>
        </div>

        {err && <div className="rounded-lg bg-red-50 p-3 text-sm text-red-700 ring-1 ring-red-100">{err}</div>}

        <button
          type="submit"
          disabled={submitting}
          className="rounded-lg bg-[#CC1414] px-6 py-2.5 text-sm font-medium text-white hover:bg-[#a30f0f] disabled:opacity-50"
        >
          {submitting ? "Submitting…" : "Submit requirement"}
        </button>
      </form>
    </div>
  );
}
