const { useEffect, useMemo, useRef, useState } = React;

const Logo = () => (
  <img className="ctech-logo" src="logo.png" alt="CTech Manufacturing" />
);

const Icon = ({ name, size = 18, color = "currentColor", stroke = 1.7 }) => {
  const s = size;
  switch (name) {
    case "pin":
      return <svg width={s} height={s} viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth={stroke} strokeLinecap="round" strokeLinejoin="round"><path d="M12 21s-7-7.58-7-12a7 7 0 0 1 14 0c0 4.42-7 12-7 12Z" /><circle cx="12" cy="9" r="2.5" /></svg>;
    case "phone":
      return <svg width={s} height={s} viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth={stroke} strokeLinecap="round" strokeLinejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.37 1.9.72 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.91.35 1.85.59 2.81.72A2 2 0 0 1 22 16.92Z" /></svg>;
    case "mail":
      return <svg width={s} height={s} viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth={stroke} strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="5" width="18" height="14" rx="1" /><path d="m3 7 9 6 9-6" /></svg>;
    case "search":
      return <svg width={s} height={s} viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth={stroke} strokeLinecap="round" strokeLinejoin="round"><circle cx="11" cy="11" r="7" /><path d="m21 21-4.3-4.3" /></svg>;
    case "upload":
      return <svg width={s} height={s} viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth={stroke} strokeLinecap="round" strokeLinejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" /><path d="m17 8-5-5-5 5" /><path d="M12 3v12" /></svg>;
    case "image":
      return <svg width={s} height={s} viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth={stroke} strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="3" width="18" height="18" rx="1" /><circle cx="9" cy="9" r="2" /><path d="m21 15-5-5L5 21" /></svg>;
    case "x":
      return <svg width={s} height={s} viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth={stroke} strokeLinecap="round" strokeLinejoin="round"><path d="M18 6 6 18M6 6l12 12" /></svg>;
    case "check":
      return <svg width={s} height={s} viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth={stroke} strokeLinecap="round" strokeLinejoin="round"><path d="M20 6 9 17l-5-5" /></svg>;
    case "arrow-right":
      return <svg width={s} height={s} viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth={stroke} strokeLinecap="round" strokeLinejoin="round"><path d="M5 12h14" /><path d="m12 5 7 7-7 7" /></svg>;
    case "chev":
      return <svg width={s} height={s} viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth={stroke} strokeLinecap="round" strokeLinejoin="round"><path d="m6 9 6 6 6-6" /></svg>;
    default:
      return null;
  }
};

const PN_PHOTOS = [
  {
    src: 'images/cart-1.jpg',
    caption: 'Stamped under the drawer rail',
    body: 'On some units, the number is red-ink stamped on the aluminum edge beneath one of the drawer slides. Pull the drawer to full extension or remove it to check.',
  },
  {
    src: 'images/cart-2.jpg',
    caption: 'Under the drawer mat',
    body: 'Open a drawer and lift up the black non-slip liner. If present, the project number is on a white QR sticker on the drawer floor.',
  },
  {
    src: 'images/cabinet-1.jpg',
    caption: 'Inside, on the vertical posts',
    body: 'A small white sticker may be on one of the slotted aluminum uprights — sometimes near the top of a front post, sometimes mid-height on a back post.',
  },
  {
    src: 'images/cabinet-2.jpg',
    caption: 'Lower frame, near the hinge',
    body: 'With the door open, check the bottom inside corner near the hinge. On some units the number is printed on the aluminum frame member just above the floor.',
  },
  {
    src: 'images/cabinet-3.jpg',
    caption: 'Backsplash — rear view',
    body: 'View from behind the base cabinets. The sticker is affixed to the backsplash panel at the top of the unit.',
  },
  {
    src: 'images/cabinet-4.jpg',
    caption: 'Inside the drawers',
    body: 'The laser-etched number can appear in any drawer, not just the first one. Check the floor of each drawer for a white QR sticker or etching.',
  },
  {
    src: 'images/drawer.jpg',
    caption: 'Stamped on the rail edge',
    body: 'Look along the front aluminum edge just below the drawer slide. The number is red-ink stamped — angle the unit toward the light to read it.',
  },
  {
    src: 'images/drawer-housing.jpg',
    caption: 'Top-center of the back panel',
    body: 'Flip the unit so you can see the back. A white printed label is fastened near the top center, between the upper mounting holes.',
  },
  {
    src: 'images/shelf.jpg',
    caption: 'Red stamp, center of the shelf',
    body: 'Slide the shelf out. The number is red-ink stamped directly on the aluminum surface, typically near the center.',
  },
  {
    src: 'images/tdu.jpg',
    caption: 'Back wall above the drawer slides',
    body: 'The top drawers must be removed to reveal the project number. Once removed, look for a small white QR sticker on the inner back wall, just above the top row of drawer slides.',
  },
];

const PNModal = ({ open, onClose }) => {
  const [lightbox, setLightbox] = useState(null);

  useEffect(() => {
    if (!open) return;
    const k = e => {
      if (e.key !== 'Escape') return;
      if (lightbox) setLightbox(null);
      else onClose();
    };
    window.addEventListener('keydown', k);
    document.body.style.overflow = 'hidden';
    return () => { window.removeEventListener('keydown', k); document.body.style.overflow = ''; };
  }, [open, onClose, lightbox]);

  if (!open) return null;

  return (
    <div className="modal-scrim" onClick={onClose}>
      <div className="modal pn-modal" onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <h2>Find your <span className="pn-yellow">project number</span></h2>
          <button className="modal-close" onClick={onClose} aria-label="Close">
            <Icon name="x" size={20} />
          </button>
        </div>
        <div className="pn-body">
          <div className="pn-intro">
            <p>Every CTech build carries a project number — printed, stickered, or ink-stamped somewhere on the unit. Scroll through the examples below to see where it might be on yours. Click any photo to zoom in.</p>
          </div>
          <div className="pn-photos">
            {PN_PHOTOS.map((p, i) => (
              <figure key={i} className="pn-photo">
                <button type="button" className="pn-photo-img" onClick={() => setLightbox(p)}>
                  <img src={p.src} alt={p.caption} loading="lazy" />
                </button>
                <figcaption>
                  <h4>{p.caption}</h4>
                  <p>{p.body}</p>
                </figcaption>
              </figure>
            ))}
          </div>
          <div className="pn-tip">
            <strong>Can't find it?</strong> Call us at <a href="tel:+17153558842">715.355.8842</a> or email <a href="mailto:hello@ctechmanufacturing.com">hello@ctechmanufacturing.com</a> with photos of the unit and we'll help you find it.
          </div>
        </div>
      </div>

      {lightbox && (
        <div className="lightbox" onClick={() => setLightbox(null)}>
          <img src={lightbox.src} alt={lightbox.caption} />
          <div className="lightbox-cap">{lightbox.caption}</div>
          <button className="modal-close" style={{position:'absolute',top:16,right:16}} onClick={() => setLightbox(null)} aria-label="Close">
            <Icon name="x" size={22} />
          </button>
        </div>
      )}
    </div>
  );
};

function formatPhone(raw) {
  const digits = raw.replace(/\D/g, "").slice(0, 10);
  if (digits.length <= 3) return digits;
  if (digits.length <= 6) return `${digits.slice(0, 3)}-${digits.slice(3)}`;
  return `${digits.slice(0, 3)}-${digits.slice(3, 6)}-${digits.slice(6)}`;
}

function formatZip(raw) {
  const digits = raw.replace(/\D/g, "").slice(0, 9);
  if (digits.length <= 5) return digits;
  return `${digits.slice(0, 5)}-${digits.slice(5)}`;
}

function PhotoUploader({ files, setFiles }) {
  const [drag, setDrag] = useState(false);
  const inputRef = useRef(null);

  const addFiles = (list) => {
    const accepted = Array.from(list || []).filter((file) => file.type.startsWith("image/"));
    const mapped = accepted.map((file) => ({
      id: `${file.name}-${file.size}-${file.lastModified}-${Math.random().toString(36).slice(2)}`,
      name: file.name,
      size: file.size,
      url: URL.createObjectURL(file),
      raw: file,
    }));
    setFiles((previous) => [...previous, ...mapped].slice(0, 8));
  };

  const remove = (id) => {
    setFiles((previous) => {
      const match = previous.find((file) => file.id === id);
      if (match) URL.revokeObjectURL(match.url);
      return previous.filter((file) => file.id !== id);
    });
  };

  const formatSize = (bytes) => (
    bytes < 1024 * 1024
      ? `${(bytes / 1024).toFixed(0)} KB`
      : `${(bytes / 1048576).toFixed(1)} MB`
  );

  return (
    <div
      className={`uploader ${drag ? "drag" : ""}`}
      onDragOver={(event) => { event.preventDefault(); setDrag(true); }}
      onDragLeave={() => setDrag(false)}
      onDrop={(event) => { event.preventDefault(); setDrag(false); addFiles(event.dataTransfer?.files); }}
    >
      <div className="uploader-empty">
        <div className="uploader-icon">
          <Icon name="image" size={26} stroke={1.5} />
        </div>
        <div className="uploader-copy">
          <h4>Add photos of the failure</h4>
          <p>Drag &amp; drop or click to browse. Up to 8 images · JPG, PNG, HEIC · 10 MB each.</p>
        </div>
        <button type="button" className="uploader-cta" onClick={() => inputRef.current?.click()}>
          <Icon name="upload" size={14} /> Browse files
        </button>
        <input
          ref={inputRef}
          type="file"
          accept="image/*"
          multiple
          style={{ display: "none" }}
          onChange={(event) => addFiles(event.target.files)}
        />
      </div>
      {files.length > 0 && (
        <div className="thumbs">
          {files.map((file) => (
            <div key={file.id} className="thumb">
              <img src={file.url} alt={file.name} />
              <button type="button" className="x" onClick={() => remove(file.id)} aria-label="Remove">
                <Icon name="x" size={14} />
              </button>
              <div className="meta">
                <span style={{ maxWidth: "70%", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{file.name}</span>
                <span>{formatSize(file.size)}</span>
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

const initialForm = {
  firstName: "",
  lastName: "",
  phone: "",
  email: "",
  street: "",
  street2: "",
  city: "",
  state: "",
  zip: "",
  country: "US",
  projectNumber: "",
  productCategory: "",
  failureDescription: "",
};

const STATE_OPTS = ["AL", "AK", "AZ", "AR", "CA", "CO", "CT", "DE", "FL", "GA", "HI", "ID", "IL", "IN", "IA", "KS", "KY", "LA", "ME", "MD", "MA", "MI", "MN", "MS", "MO", "MT", "NE", "NV", "NH", "NJ", "NM", "NY", "NC", "ND", "OH", "OK", "OR", "PA", "RI", "SC", "SD", "TN", "TX", "UT", "VT", "VA", "WA", "WV", "WI", "WY"];

const STATE_NAME_TO_ABBR = {
  "alabama": "AL", "alaska": "AK", "arizona": "AZ", "arkansas": "AR",
  "california": "CA", "colorado": "CO", "connecticut": "CT", "delaware": "DE",
  "florida": "FL", "georgia": "GA", "hawaii": "HI", "idaho": "ID",
  "illinois": "IL", "indiana": "IN", "iowa": "IA", "kansas": "KS",
  "kentucky": "KY", "louisiana": "LA", "maine": "ME", "maryland": "MD",
  "massachusetts": "MA", "michigan": "MI", "minnesota": "MN", "mississippi": "MS",
  "missouri": "MO", "montana": "MT", "nebraska": "NE", "nevada": "NV",
  "new hampshire": "NH", "new jersey": "NJ", "new mexico": "NM", "new york": "NY",
  "north carolina": "NC", "north dakota": "ND", "ohio": "OH", "oklahoma": "OK",
  "oregon": "OR", "pennsylvania": "PA", "rhode island": "RI", "south carolina": "SC",
  "south dakota": "SD", "tennessee": "TN", "texas": "TX", "utah": "UT",
  "vermont": "VT", "virginia": "VA", "washington": "WA", "west virginia": "WV",
  "wisconsin": "WI", "wyoming": "WY", "district of columbia": "DC",
};

function WarrantyForm({ onSubmitted }) {
  const [form, setForm] = useState(initialForm);
  const [files, setFiles] = useState([]);
  const [touched, setTouched] = useState({});
  const [submitting, setSubmitting] = useState(false);
  const [submitError, setSubmitError] = useState(null);
  const [pnModal, setPnModal] = useState(false);
  const [addrSuggestions, setAddrSuggestions] = useState([]);
  const [showAddrDrop, setShowAddrDrop] = useState(false);
  const addrDebounce = useRef(null);

  const setField = (key) => (event) => setForm((state) => ({ ...state, [key]: event.target.value }));
  const markTouched = (key) => () => setTouched((state) => ({ ...state, [key]: true }));

  const fetchAddrSuggestions = async (query) => {
    if (query.length < 3) { setAddrSuggestions([]); setShowAddrDrop(false); return; }
    try {
      const res = await fetch(
        `https://nominatim.openstreetmap.org/search?q=${encodeURIComponent(query)}&format=json&addressdetails=1&countrycodes=us&limit=6`,
        { headers: { "Accept-Language": "en-US,en" } },
      );
      const data = await res.json();
      const suggestions = data
        .filter((item) => item.address && (item.address.house_number || item.address.road))
        .map((item) => {
          const a = item.address;
          return {
            street: [a.house_number, a.road].filter(Boolean).join(" "),
            city: a.city || a.town || a.village || a.hamlet || a.county || "",
            state: STATE_NAME_TO_ABBR[(a.state || "").toLowerCase()] || "",
            zip: (a.postcode || "").slice(0, 5),
          };
        })
        .filter((s) => s.street);
      setAddrSuggestions(suggestions);
      setShowAddrDrop(suggestions.length > 0);
    } catch {
      // Nominatim unavailable — fail silently
    }
  };

  const onStreetChange = (event) => {
    const val = event.target.value;
    setForm((state) => ({ ...state, street: val }));
    if (addrDebounce.current) clearTimeout(addrDebounce.current);
    addrDebounce.current = setTimeout(() => fetchAddrSuggestions(val), 200);
  };

  const pickAddress = (suggestion) => {
    setForm((state) => ({
      ...state,
      street: suggestion.street,
      city: suggestion.city,
      state: suggestion.state,
      zip: suggestion.zip,
    }));
    setShowAddrDrop(false);
    setAddrSuggestions([]);
  };

  const errors = useMemo(() => {
    const nextErrors = {};
    if (!form.firstName.trim()) nextErrors.firstName = "Required";
    if (!form.lastName.trim()) nextErrors.lastName = "Required";
    if (!form.phone.trim()) nextErrors.phone = "Required";
    else if (form.phone.replace(/\D/g, "").length !== 10) nextErrors.phone = "Enter a 10-digit phone number";
    if (!form.email.trim()) nextErrors.email = "Required";
    else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email)) nextErrors.email = "Enter a valid email";
    if (!form.street.trim()) nextErrors.street = "Required";
    if (!form.city.trim()) nextErrors.city = "Required";
    if (!form.state) nextErrors.state = "Required";
    if (!form.zip.trim()) nextErrors.zip = "Required";
    else if (!/^\d{5}(-\d{4})?$/.test(form.zip)) nextErrors.zip = "Use ZIP or ZIP+4";
    if (!form.projectNumber.trim()) nextErrors.projectNumber = "Required";
    else if (!/^\d{4,6}$/.test(form.projectNumber.trim())) nextErrors.projectNumber = "Enter a 4–6 digit project number";
    if (!form.productCategory) nextErrors.productCategory = "Required";
    if (!form.failureDescription.trim()) nextErrors.failureDescription = "Required";
    else if (form.failureDescription.trim().length < 20) nextErrors.failureDescription = "Please give us more detail (20+ characters)";
    return nextErrors;
  }, [form]);

  const showError = (key) => touched[key] && errors[key];

  const onSubmit = async (event) => {
    event.preventDefault();

    setTouched(Object.fromEntries(Object.keys(initialForm).map((key) => [key, true])));
    if (Object.keys(errors).length > 0) {
      const first = Object.keys(errors)[0];
      document.querySelector(`[data-field="${first}"]`)?.scrollIntoView({ block: "center", behavior: "smooth" });
      return;
    }

    const reference = `WR-${Math.floor(100000 + Math.random() * 900000)}`;
    const formData = new FormData();
    formData.append("reference", reference);
    formData.append("submittedAt", new Date().toISOString());
    Object.entries(form).forEach(([key, value]) => formData.append(key, value ?? ""));
    formData.append("photoCount", String(files.length));
    files.forEach((file) => formData.append("photos", file.raw, file.name));

    setSubmitting(true);
    setSubmitError(null);

    try {
      const response = await fetch("/api/submit", {
        method: "POST",
        body: formData,
      });

      if (!response.ok) {
        let message = `Warranty server responded ${response.status}`;
        try {
          const data = await response.json();
          message = data.message || data.error || message;
        } catch (error) {
          // Keep the generic message when the response is not JSON.
        }
        throw new Error(message);
      }

      onSubmitted({ ref: reference, firstName: form.firstName, files: files.length });
    } catch (error) {
      console.error("Submit failed:", error);
      setSubmitError("We could not reach the warranty server. Please try again, or call +1 (715) 230-3967.");
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <form className="card" onSubmit={onSubmit} noValidate autoComplete="on">
      <PNModal open={pnModal} onClose={() => setPnModal(false)} />

      <div className="form-grid">
        <div className="field" data-field="firstName">
          <label className="label">First name <span className="req">*</span></label>
          <input className={`input ${showError("firstName") ? "invalid" : ""}`} name="firstName" autoComplete="given-name" placeholder="First name" value={form.firstName} onChange={setField("firstName")} onBlur={markTouched("firstName")} />
          {showError("firstName") && <div className="error-line">{errors.firstName}</div>}
        </div>
        <div className="field" data-field="lastName">
          <label className="label">Last name <span className="req">*</span></label>
          <input className={`input ${showError("lastName") ? "invalid" : ""}`} name="lastName" autoComplete="family-name" placeholder="Last name" value={form.lastName} onChange={setField("lastName")} onBlur={markTouched("lastName")} />
          {showError("lastName") && <div className="error-line">{errors.lastName}</div>}
        </div>

        <div className="field" data-field="phone">
          <label className="label">Phone <span className="req">*</span></label>
          <input className={`input ${showError("phone") ? "invalid" : ""}`} type="tel" name="phone" autoComplete="tel-national" inputMode="numeric" maxLength={12} placeholder="555-555-0142" value={form.phone} onChange={(event) => setForm((state) => ({ ...state, phone: formatPhone(event.target.value) }))} onBlur={markTouched("phone")} />
          {showError("phone") && <div className="error-line">{errors.phone}</div>}
        </div>
        <div className="field" data-field="email">
          <label className="label">Email <span className="req">*</span></label>
          <input className={`input ${showError("email") ? "invalid" : ""}`} type="email" name="email" autoComplete="email" placeholder="you@example.com" value={form.email} onChange={setField("email")} onBlur={markTouched("email")} />
          {showError("email") && <div className="error-line">{errors.email}</div>}
        </div>

        <div className="field full" data-field="street">
          <label className="label">Street address <span className="req">*</span></label>
          <div className="addr-street-wrap">
            <input
              className={`input ${showError("street") ? "invalid" : ""}`}
              name="street"
              autoComplete="off"
              placeholder="123 Pit Road"
              value={form.street}
              onChange={onStreetChange}
              onBlur={() => { markTouched("street")(); setTimeout(() => setShowAddrDrop(false), 180); }}
              onFocus={() => addrSuggestions.length > 0 && setShowAddrDrop(true)}
            />
            {showAddrDrop && (
              <div className="addr-suggestions">
                {addrSuggestions.map((s, i) => (
                  <div key={i} className="addr-suggestion" onMouseDown={() => pickAddress(s)}>
                    <div className="addr-suggestion-main">{s.street}</div>
                    <div className="addr-suggestion-sub">{[s.city, s.state, s.zip].filter(Boolean).join(", ")}</div>
                  </div>
                ))}
              </div>
            )}
          </div>
          {showError("street") && <div className="error-line">{errors.street}</div>}
        </div>
        <div className="field full">
          <label className="label">Apt, suite, or unit <span style={{ color: "var(--muted)", fontWeight: 500 }}>(optional)</span></label>
          <input className="input" name="street2" autoComplete="address-line2" placeholder="Suite 200" value={form.street2} onChange={setField("street2")} />
        </div>
        <div className="field full">
          <div className="addr-grid">
            <div className="field" data-field="city" style={{ gap: 6 }}>
              <label className="label">City <span className="req">*</span></label>
              <input className={`input ${showError("city") ? "invalid" : ""}`} name="city" autoComplete="address-level2" placeholder="Weston" value={form.city} onChange={setField("city")} onBlur={markTouched("city")} />
              {showError("city") && <div className="error-line">{errors.city}</div>}
            </div>
            <div className="field" data-field="state" style={{ gap: 6 }}>
              <label className="label">State <span className="req">*</span></label>
              <select className={`select ${showError("state") ? "invalid" : ""}`} name="state" autoComplete="address-level1" value={form.state} onChange={setField("state")} onBlur={markTouched("state")}>
                <option value="">Select…</option>
                {STATE_OPTS.map((stateOption) => <option key={stateOption} value={stateOption}>{stateOption}</option>)}
              </select>
              {showError("state") && <div className="error-line">{errors.state}</div>}
            </div>
            <div className="field" data-field="zip" style={{ gap: 6 }}>
              <label className="label">ZIP <span className="req">*</span></label>
              <input className={`input ${showError("zip") ? "invalid" : ""}`} name="zip" autoComplete="postal-code" inputMode="numeric" maxLength={10} placeholder="54476" value={form.zip} onChange={(event) => setForm((state) => ({ ...state, zip: formatZip(event.target.value) }))} onBlur={markTouched("zip")} />
              {showError("zip") && <div className="error-line">{errors.zip}</div>}
            </div>
            <div className="field" style={{ gap: 6 }}>
              <label className="label">Country</label>
              <select className="select" name="country" autoComplete="country" value={form.country} onChange={setField("country")}>
                <option value="US">United States</option>
                <option value="CA">Canada</option>
              </select>
            </div>
          </div>
        </div>

        <div className="field" data-field="projectNumber">
          <label className="label">Project number <span className="req">*</span></label>
          <div className="pn-row">
            <input className={`input ${showError("projectNumber") ? "invalid" : ""}`} placeholder="e.g. 341872" value={form.projectNumber} onChange={setField("projectNumber")} onBlur={markTouched("projectNumber")} />
            <button type="button" className="pn-info-btn" onClick={() => setPnModal(true)}>
              <span className="pn-i-circle">i</span> Where do I find this?
            </button>
          </div>
          {showError("projectNumber")
            ? <div className="error-line">{errors.projectNumber}</div>
            : <div className="help">Stamped on every CTech build. Could be 4–6 digits.</div>}
        </div>
        <div className="field" data-field="productCategory">
          <label className="label">Product category <span className="req">*</span></label>
          <select className={`select ${showError("productCategory") ? "invalid" : ""}`} value={form.productCategory} onChange={setField("productCategory")} onBlur={markTouched("productCategory")}>
            <option value="">Select category…</option>
            <option>Cart</option>
            <option>Cabinet</option>
            <option>Drawer unit</option>
            <option>Accessory</option>
            <option>Caster / Part</option>
            <option>Not sure</option>
          </select>
          {showError("productCategory") && <div className="error-line">{errors.productCategory}</div>}
        </div>

        <div className="field full" data-field="failureDescription">
          <label className="label">Describe the failure <span className="req">*</span></label>
          <textarea className={`textarea ${showError("failureDescription") ? "invalid" : ""}`} placeholder="Describe the issue, when it started, and any steps already taken." value={form.failureDescription} onChange={setField("failureDescription")} onBlur={markTouched("failureDescription")} rows={6} />
          {showError("failureDescription")
            ? <div className="error-line">{errors.failureDescription}</div>
            : <div className="help" style={{ display: "flex", justifyContent: "space-between" }}>
                <span>The more detail, the faster we can dispatch a fix.</span>
                <span>{form.failureDescription.length} chars</span>
              </div>}
        </div>

        <div className="field full">
          <label className="label">Photos of the failure</label>
          <PhotoUploader files={files} setFiles={setFiles} />
        </div>
      </div>

      <div className="form-foot">
        {submitError && <div className="error-line" style={{ marginBottom: 12, fontSize: 13 }}>{submitError}</div>}
        <button className="btn-submit" type="submit" disabled={submitting}>
          {submitting ? "SENDING..." : "SUBMIT"}
        </button>
      </div>
    </form>
  );
}

const SuccessView = ({ result, onReset }) => (
  <div className="success">
    <div className="check"><Icon name="check" size={36} stroke={3} /></div>
    <div className="crumb" style={{ margin: 0 }}>WARRANTY REQUEST RECEIVED</div>
    <h2>Thanks, {result.firstName}.</h2>
    <p>Your request is in the queue. A CTech warranty tech will reach out to the email and phone number you provided within one business day. Keep this reference number for your records:</p>
    <div className="ref">REF · {result.ref}</div>
    <div style={{ display: "flex", gap: 12, marginTop: 18, flexWrap: "wrap", justifyContent: "center" }}>
      <button onClick={onReset} className="btn-submit" style={{ background: "#0b0b0b" }}>
        SUBMIT ANOTHER <Icon name="arrow-right" size={14} />
      </button>
    </div>
  </div>
);

function App() {
  const [done, setDone] = useState(null);

  return (
    <>
      <div className="logo-bar">
        <a href="#" aria-label="CTech Manufacturing"><Logo /></a>
      </div>
      <main className="page">
        <h1 className="italic-display page-title">WARRANTY REQUEST</h1>
        {done ? <SuccessView result={done} onReset={() => setDone(null)} /> : <WarrantyForm onSubmitted={setDone} />}
      </main>
    </>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
