/* ============================================================
   BookingForm — multi-step, validated, Formspree-ready
   exported to window.BookingForm
   ============================================================ */
const BookingForm = (() => {
  const { useState, useEffect, useRef } = React;
  const I = window.Icons;
  const STEPS = [
    { n: 1, label: "What you need" },
    { n: 2, label: "Your device" },
    { n: 3, label: "Your details" },
  ];

  const emptyData = {
    service: "", urgency: "week", device: "", description: "",
    photoName: "", name: "", email: "", phone: "", suburb: "", contact: "phone",
    addon: false, bundle: "",
  };

  function Field({ label, hint, error, children, required }) {
    return (
      <label className="fld">
        <span className="fld-l">{label}{required && <i> *</i>}{hint && <em>{hint}</em>}</span>
        {children}
        {error && <span className="fld-err">{error}</span>}
      </label>
    );
  }

  function BookingForm({ prefill }) {
    const C = window.CONFIG, SERVICES = window.SERVICES, DEVICES = window.DEVICE_TYPES, URG = window.URGENCY;
    const SVC_LIST = [...SERVICES, window.OTHER_SERVICE];
    const ADDON = window.ADDON;
    const [step, setStep] = useState(1);
    const [data, setData] = useState(emptyData);
    const [errors, setErrors] = useState({});
    const [status, setStatus] = useState("idle"); // idle | sending | success | error
    const [photoFile, setPhotoFile] = useState(null);
    const [photoURL, setPhotoURL] = useState("");
    const topRef = useRef(null);

    const set = (k, v) => setData(d => ({ ...d, [k]: v }));

    // prefill from hero / service cards
    useEffect(() => {
      if (!prefill) return;
      setData(d => ({ ...d,
        ...(prefill.service ? { service: prefill.service } : {}),
        ...(prefill.suburb ? { suburb: prefill.suburb } : {}),
        ...(prefill.addon !== undefined ? { addon: prefill.addon } : {}),
        ...(prefill.bundle !== undefined ? { bundle: prefill.bundle } : {}),
      }));
    }, [prefill]);

    const scrollTop = () => {
      const el = topRef.current; if (!el) return;
      const r = el.getBoundingClientRect();
      if (r.top < 80) window.scrollTo({ top: window.scrollY + r.top - 96, behavior: "smooth" });
    };

    function validate(s) {
      const e = {};
      if (s === 1) { if (!data.service) e.service = "Pick what you need help with"; }
      if (s === 2) {
        if (!data.device) e.device = "Let us know the device";
        if (!data.description || data.description.trim().length < 12) e.description = "A sentence or two helps us prepare";
      }
      if (s === 3) {
        if (!data.name.trim()) e.name = "Your name, please";
        if (!data.suburb.trim()) e.suburb = "We need this to plan pickup";
        const emailOk = /^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(data.email);
        const phoneOk = data.phone.replace(/\D/g, "").length >= 8;
        if (data.contact === "email" && !emailOk) e.email = "Enter a valid email";
        if (data.contact === "phone" && !phoneOk) e.phone = "Enter a valid phone number";
        if (data.contact !== "email" && !emailOk && !phoneOk) { e.phone = "Add a phone or email so we can reply"; }
      }
      return e;
    }

    function next() {
      const e = validate(step);
      setErrors(e);
      if (Object.keys(e).length) return;
      setStep(s => Math.min(3, s + 1));
      scrollTop();
    }
    function back() { setStep(s => Math.max(1, s - 1)); scrollTop(); }

    function onPhoto(file) {
      if (!file) { setPhotoFile(null); setPhotoURL(""); set("photoName", ""); return; }
      setPhotoFile(file); set("photoName", file.name);
      const r = new FileReader(); r.onload = () => setPhotoURL(r.result); r.readAsDataURL(file);
    }

    async function submit() {
      const e = validate(3); setErrors(e);
      if (Object.keys(e).length) return;
      setStatus("sending");
      const svc = SVC_LIST.find(s => s.id === data.service);
      const payload = {
        _subject: `New ${C.business} ticket — ${svc ? svc.title : "enquiry"} (${data.urgency})`,
        service: svc ? svc.title : data.service,
        urgency: (URG.find(u => u.id === data.urgency) || {}).label,
        device: data.device,
        preventionAddon: data.addon ? `Yes (+$${ADDON.price})` : "No",
        bundle: data.bundle || "—",
        description: data.description,
        name: data.name, email: data.email, phone: data.phone,
        suburb: data.suburb, preferredContact: data.contact,
        submittedAt: new Date().toLocaleString("en-AU"),
      };
      try {
        const endpoint = C.apiEndpoint || "/api/submit";
        let res;
        if (photoFile) {
          // Photo uploads aren't wired through to D1/R2 yet — the API drops
          // file blobs server-side. Sending FormData here is forward-compat
          // for when the photo path lands.
          const fd = new FormData();
          Object.entries(payload).forEach(([k, v]) => fd.append(k, v ?? ""));
          fd.append("photo", photoFile);
          res = await fetch(endpoint, { method: "POST", body: fd, headers: { Accept: "application/json" } });
        } else {
          res = await fetch(endpoint, {
            method: "POST",
            body: JSON.stringify(payload),
            headers: { "Content-Type": "application/json", Accept: "application/json" },
          });
        }
        if (!res.ok) throw new Error("bad");
        setStatus("success"); scrollTop();
      } catch (err) { setStatus("error"); }
    }

    function reset() { setData(emptyData); setPhotoFile(null); setPhotoURL(""); setErrors({}); setStep(1); setStatus("idle"); scrollTop(); }

    /* ---------- SUCCESS ---------- */
    if (status === "success") {
      const svc = SVC_LIST.find(s => s.id === data.service);
      return (
        <div className="bf" ref={topRef}>
          <div className="bf-success">
            <div className="bf-success-ic"><I.CheckCircle w={34} sw={1.6} /></div>
            <h3>You're booked in, {data.name.split(" ")[0]}.</h3>
            <p>We've got your request for <strong>{svc ? svc.title : "help"}</strong> in <strong>{data.suburb}</strong>. We'll be in touch by {data.contact === "email" ? "email" : "phone"} within <strong>1 business day</strong> with honest next steps and a clear quote.</p>
            <div className="bf-next">
              <div><span className="bf-next-n">1</span> We read your request &amp; reply within a day</div>
              <div><span className="bf-next-n">2</span> We confirm a time — we can come to you</div>
              <div><span className="bf-next-n">3</span> Fixed &amp; protected. No fix? No charge.</div>
            </div>
            <div className="bf-success-cta">
              <button className="btn btn-primary" onClick={reset}>Send another request</button>
            </div>
          </div>
        </div>
      );
    }

    return (
      <div className="bf" ref={topRef}>
        {/* progress */}
        <div className="bf-prog">
          {STEPS.map((s, i) => (
            <React.Fragment key={s.n}>
              <button className={"bf-step" + (step === s.n ? " on" : "") + (step > s.n ? " done" : "")}
                      onClick={() => step > s.n && setStep(s.n)} disabled={step <= s.n}>
                <span className="bf-step-d">{step > s.n ? <I.Check w={14} sw={2.4} /> : s.n}</span>
                <span className="bf-step-l">{s.label}</span>
              </button>
              {i < STEPS.length - 1 && <span className={"bf-bar" + (step > s.n ? " done" : "")} />}
            </React.Fragment>
          ))}
        </div>

        {/* STEP 1 */}
        {step === 1 && (
          <div className="bf-body">
            {data.bundle && <div className="bf-bundle"><I.Tag w={15} /> <strong>{data.bundle}</strong> applied — prevention is included</div>}
            <h3 className="bf-q">What can we help with?</h3>
            <div className="bf-svc">
              {SVC_LIST.map(s => {
                const Ic = I[s.icon];
                const on = data.service === s.id;
                return (
                  <button key={s.id} className={"bf-svc-card" + (on ? " on" : "")} onClick={() => { set("service", s.id); setErrors(e => ({ ...e, service: "" })); }}>
                    <span className="bf-svc-ic"><Ic w={22} /></span>
                    <span className="bf-svc-t">{s.title}</span>
                    {s.price && <span className="bf-svc-p">{s.price}</span>}
                    {on && <span className="bf-svc-chk"><I.Check w={13} sw={3} /></span>}
                  </button>
                );
              })}
            </div>
            {errors.service && <span className="fld-err mt">{errors.service}</span>}

            <h3 className="bf-q mt28">How soon do you need us?</h3>
            <div className="bf-urg">
              {URG.map(u => (
                <button key={u.id} className={"bf-urg-b" + (data.urgency === u.id ? " on" : "")} onClick={() => set("urgency", u.id)}>
                  <strong>{u.label}</strong><span>{u.sub}</span>
                </button>
              ))}
            </div>

            {data.service !== "prevent" && (
              <button className={"bf-addon" + (data.addon ? " on" : "")} onClick={() => set("addon", !data.addon)}>
                <span className="bf-addon-box">{data.addon && <I.Check w={14} sw={3} />}</span>
                <span className="bf-addon-txt">
                  <strong>{ADDON.label} <em>save ${ADDON.save}</em></strong>
                  <span>{ADDON.sub}</span>
                </span>
                <span className="bf-addon-price">+${ADDON.price}</span>
              </button>
            )}
          </div>
        )}

        {/* STEP 2 */}
        {step === 2 && (
          <div className="bf-body">
            <h3 className="bf-q">Tell us about your device</h3>
            <Field label="What device is it?" required error={errors.device}>
              <div className="bf-dev">
                {DEVICES.map(d => (
                  <button key={d} className={"bf-dev-b" + (data.device === d ? " on" : "")} onClick={() => { set("device", d); setErrors(e => ({ ...e, device: "" })); }}>{d}</button>
                ))}
              </div>
            </Field>
            <Field label="What's going on?" hint="the more detail, the better" required error={errors.description}>
              <textarea className="inp" rows={4} value={data.description}
                placeholder="e.g. My laptop has been really slow for a few weeks and a pop-up keeps saying I have a virus…"
                onChange={e => { set("description", e.target.value); if (errors.description) setErrors(x => ({ ...x, description: "" })); }} />
            </Field>
            <Field label="Add a photo" hint="optional — a snap of the screen or device helps">
              {!photoURL ? (
                <label className="bf-photo">
                  <I.Camera w={22} />
                  <span>Tap to add a photo</span>
                  <input type="file" accept="image/*" hidden onChange={e => onPhoto(e.target.files[0])} />
                </label>
              ) : (
                <div className="bf-photo-prev">
                  <img src={photoURL} alt="upload" />
                  <div><strong>{data.photoName}</strong><button onClick={() => onPhoto(null)}>Remove</button></div>
                </div>
              )}
            </Field>
          </div>
        )}

        {/* STEP 3 */}
        {step === 3 && (
          <div className="bf-body">
            <h3 className="bf-q">How do we reach you?</h3>
            <div className="bf-grid2">
              <Field label="Name" required error={errors.name}>
                <input className="inp" value={data.name} placeholder="Jane Smith"
                  onChange={e => { set("name", e.target.value); if (errors.name) setErrors(x => ({ ...x, name: "" })); }} />
              </Field>
              <Field label="Suburb" hint="for pickup" required error={errors.suburb}>
                <input className="inp" value={data.suburb} placeholder="e.g. Terrigal"
                  onChange={e => { set("suburb", e.target.value); if (errors.suburb) setErrors(x => ({ ...x, suburb: "" })); }} />
              </Field>
              <Field label="Phone" error={errors.phone}>
                <input className="inp" value={data.phone} placeholder="0400 000 000" inputMode="tel"
                  onChange={e => { set("phone", e.target.value); if (errors.phone) setErrors(x => ({ ...x, phone: "" })); }} />
              </Field>
              <Field label="Email" error={errors.email}>
                <input className="inp" value={data.email} placeholder="you@email.com" inputMode="email"
                  onChange={e => { set("email", e.target.value); if (errors.email) setErrors(x => ({ ...x, email: "" })); }} />
              </Field>
            </div>
            <Field label="Best way to reach you">
              <div className="bf-contact">
                {[{ id: "phone", l: "Call me", ic: "Phone" }, { id: "text", l: "Text me", ic: "Chat" }, { id: "email", l: "Email me", ic: "Mail" }].map(o => {
                  const Ic = I[o.ic];
                  return <button key={o.id} className={"bf-contact-b" + (data.contact === o.id ? " on" : "")} onClick={() => set("contact", o.id)}><Ic w={17} />{o.l}</button>;
                })}
              </div>
            </Field>
            <div className="bf-reassure"><I.Shield w={16} /> No spam, ever. We only use this to help with your request.</div>
            {status === "error" && <div className="bf-errbox">Something went wrong sending that. Please try again in a moment.</div>}
          </div>
        )}

        {/* footer nav */}
        <div className="bf-foot">
          {step > 1 ? <button className="btn btn-ghost" onClick={back}><I.ChevronL w={17} /> Back</button> : <span />}
          {step < 3
            ? <button className="btn btn-primary" onClick={next}>Continue <I.ChevronR w={17} /></button>
            : <button className="btn btn-primary" onClick={submit} disabled={status === "sending"}>
                {status === "sending" ? "Sending…" : <>Send my request <I.Arrow w={18} /></>}
              </button>}
        </div>
      </div>
    );
  }
  return BookingForm;
})();
window.BookingForm = BookingForm;
