// ARS — multi-step online booking flow (modal)
const { useState: useStateBk, useMemo: useMemoBk, useEffect: useEffectBk } = React;

const SERVICE_OPTS = [
  { id: "nextday", laborId: "lab_nextday", title: "Next-Day Homebase", icon: "clock", blurb: "Drop at homebase, ready the next day.", needsLoc: false },
  { id: "sameday", laborId: "lab_sameday", title: "Same-Day Homebase", icon: "bolt", blurb: "Drop off, pick up the same day.", needsLoc: false },
  { id: "mobile", laborId: "lab_mobile2", title: "Mobile Express", icon: "truck", blurb: "We come string at your court or home.", needsLoc: true },
];

function laborCost(data, type, count) {
  const get = (id) => (data.labor.find((l) => l.id === id) || {}).price || 0;
  if (type === "nextday") return get("lab_nextday") * count;
  if (type === "sameday") return get("lab_sameday") * count;
  if (type === "mobile") {
    if (count <= 1) return get("lab_mobile1");
    if (count <= 7) return get("lab_mobile2") * count;
    return get("lab_mobile8") * count;
  }
  return 0;
}
function feeVal(data, id) { return (data.fees.find((f) => f.id === id) || {}).price || 0; }

function genDays(n) {
  const out = [], now = new Date();
  for (let i = 0; i < n; i++) {
    const d = new Date(now); d.setDate(now.getDate() + i);
    out.push(d);
  }
  return out;
}
const TIME_SLOTS = [
  { id: "am", label: "Morning", time: "8–11 AM", evening: false },
  { id: "mid", label: "Midday", time: "11 AM–2 PM", evening: false },
  { id: "pm", label: "Afternoon", time: "2–6 PM", evening: false },
  { id: "eve", label: "Evening", time: "After 6 PM", evening: true },
];

function Stepper({ step, steps }) {
  return (
    <div style={{ display: "flex", gap: 7, alignItems: "center" }}>
      {steps.map((s, i) => (
        <div key={i} style={{ height: 6, flex: 1, borderRadius: 6,
          background: i <= step ? "var(--ball)" : "rgba(255,255,255,.22)", transition: "background .3s" }} />
      ))}
    </div>
  );
}

function OptionCard({ active, onClick, icon, title, blurb, right }) {
  return (
    <button onClick={onClick} style={{ textAlign: "left", width: "100%", display: "flex", gap: 14, alignItems: "center",
      padding: "16px 18px", borderRadius: 14, background: active ? "var(--green-soft)" : "#fff",
      border: `2px solid ${active ? "var(--green)" : "var(--line)"}`, transition: "all .15s" }}>
      <span style={{ width: 44, height: 44, borderRadius: 11, flexShrink: 0, display: "grid", placeItems: "center",
        background: active ? "var(--green)" : "var(--navy-soft)", color: active ? "#fff" : "var(--navy)" }}>
        <Icon name={icon} size={22} /></span>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontWeight: 800, fontSize: 16, color: "var(--navy)" }}>{title}</div>
        <div style={{ fontSize: 13.5, color: "var(--ink-2)" }}>{blurb}</div>
      </div>
      {right}
      {active && <span style={{ color: "var(--green)" }}><Icon name="check" size={22} stroke={3} /></span>}
    </button>
  );
}

function Field({ label, children, required }) {
  return (
    <label style={{ display: "block", marginBottom: 14 }}>
      <span style={{ display: "block", fontWeight: 700, fontSize: 13.5, marginBottom: 6, color: "var(--navy)" }}>
        {label}{required && <span style={{ color: "var(--green)" }}> *</span>}</span>
      {children}
    </label>
  );
}
const inputStyle = { width: "100%", padding: "12px 14px", borderRadius: 11, border: "2px solid var(--line)",
  fontSize: 15.5, color: "var(--ink)", background: "#fff", outline: "none" };

function BookingModal({ data, onClose, onComplete }) {
  const [step, setStep] = useStateBk(0);
  const [b, setB] = useStateBk({
    service: "mobile", count: 1, useOwn: false, stringId: null,
    dayIdx: 1, slot: "am", pickup: false,
    name: "", phone: "", email: "", address: "", notes: "", stencil: false,
  });
  const set = (patch) => setB((p) => ({ ...p, ...patch }));

  const flatStrings = useMemoBk(() => data.strings.flatMap((c) => c.items.map((it) => ({ ...it, cat: c.category }))), [data]);
  useEffectBk(() => { if (!b.stringId && flatStrings[0]) set({ stringId: flatStrings[0].id }); }, [flatStrings]);

  const svc = SERVICE_OPTS.find((s) => s.id === b.service);
  const chosenString = flatStrings.find((s) => s.id === b.stringId);
  const slot = TIME_SLOTS.find((t) => t.id === b.slot);
  const needsAddress = svc.needsLoc || b.pickup;

  const est = useMemoBk(() => {
    const labor = laborCost(data, b.service, b.count);
    const stringCost = b.useOwn ? 0 : (chosenString ? chosenString.price * b.count : 0);
    const pickup = b.pickup ? feeVal(data, "fee_pickup") * 2 : 0;
    const stencil = b.stencil ? feeVal(data, "fee_stencil") * b.count : 0;
    const emergency = slot && slot.evening ? feeVal(data, "fee_emergency") * b.count : 0;
    const total = labor + stringCost + pickup + stencil + emergency;
    return { labor, stringCost, pickup, stencil, emergency, total };
  }, [data, b, chosenString, slot]);

  const days = useMemoBk(() => genDays(14), []);
  const fmtDay = (d) => d.toLocaleDateString("en-US", { weekday: "short", month: "short", day: "numeric" });

  // availability snapshot taken when the modal opens
  const existingBookings = useMemoBk(() => window.ARS.loadBookings(), []);
  const existingAppts = useMemoBk(() => window.ARS.loadAppointments(), []);
  const blockedDays = useMemoBk(() => window.ARS.loadBlocked(), []);
  const dayInfo = (d) => {
    const iso = window.ARS.isoOf(d);
    const taken = window.ARS.takenWindows(existingBookings, existingAppts, iso);
    const blocked = blockedDays.includes(iso);
    return { iso, taken, blocked, full: blocked || taken.size >= TIME_SLOTS.length };
  };
  const selInfo = dayInfo(days[b.dayIdx]);
  // if the currently-selected window is taken, nudge to first open one
  useEffectBk(() => {
    if (selInfo.taken.has(b.slot)) {
      const open = TIME_SLOTS.find((t) => !selInfo.taken.has(t.id));
      if (open) set({ slot: open.id });
    }
  }, [b.dayIdx]);

  const steps = ["Service", "Racquets & String", "Date & Time", "Your Details", "Review"];
  const canNext = () => {
    if (step === 1) return b.count >= 1 && (b.useOwn || b.stringId);
    if (step === 2) return !selInfo.full && !selInfo.taken.has(b.slot);
    if (step === 3) return b.name.trim() && b.phone.trim() && (!needsAddress || b.address.trim());
    return true;
  };

  const submit = () => {
    const booking = {
      id: window.ARS.uid("bk"), created: Date.now(),
      service: svc.title, serviceId: b.service, count: b.count,
      string: b.useOwn ? "Customer-provided" : (chosenString ? `${chosenString.name} (${chosenString.detail})` : "—"),
      day: fmtDay(days[b.dayIdx]), slot: `${slot.label} · ${slot.time}`,
      dateISO: window.ARS.isoOf(days[b.dayIdx]), window: b.slot,
      pickup: b.pickup, stencil: b.stencil,
      name: b.name, phone: b.phone, email: b.email, address: b.address, notes: b.notes,
      total: est.total, status: "New",
    };
    onComplete(booking);
    setStep(5);
  };

  const header = (
    <div style={{ background: "var(--navy-deep)", color: "#fff", padding: "20px 26px 18px" }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 16 }}>
        <div style={{ display: "flex", alignItems: "center", gap: 11 }}>
          <BallMark size={34} />
          <div>
            <div style={{ fontWeight: 800, fontSize: 17 }}>Book your stringing</div>
            <div style={{ fontSize: 12.5, color: "rgba(255,255,255,.6)" }}>{step < 5 ? `Step ${step + 1} of 5 · ${steps[step]}` : "Confirmed"}</div>
          </div>
        </div>
        <button onClick={onClose} style={{ color: "#fff", padding: 6 }} title="Close"><Icon name="x" size={22} /></button>
      </div>
      {step < 5 && <Stepper step={step} steps={steps} />}
    </div>
  );

  let body;
  if (step === 0) {
    body = (
      <div>
        <h3 style={{ fontSize: 20, color: "var(--navy)", marginBottom: 4 }}>How would you like it done?</h3>
        <p style={{ color: "var(--ink-2)", marginTop: 0, marginBottom: 18, fontSize: 14.5 }}>Choose the service that fits your day.</p>
        <div style={{ display: "grid", gap: 12 }}>
          {SERVICE_OPTS.map((s) => (
            <OptionCard key={s.id} active={b.service === s.id} onClick={() => set({ service: s.id, pickup: s.needsLoc ? false : b.pickup })}
              icon={s.icon} title={s.title} blurb={s.blurb} />
          ))}
        </div>
        {b.service !== "mobile" && (
          <label style={{ display: "flex", gap: 12, alignItems: "center", marginTop: 16, padding: "14px 16px",
            borderRadius: 12, border: "2px solid var(--line)", cursor: "pointer", background: b.pickup ? "var(--green-soft)" : "#fff" }}>
            <input type="checkbox" checked={b.pickup} onChange={(e) => set({ pickup: e.target.checked })} style={{ width: 18, height: 18, accentColor: "var(--green)" }} />
            <span style={{ flex: 1 }}><b style={{ color: "var(--navy)" }}>Add pick-up & delivery</b>
              <span style={{ color: "var(--ink-2)", fontSize: 13.5 }}> — we collect and return your racquets (+${feeVal(data, "fee_pickup")} each way)</span></span>
          </label>
        )}
      </div>
    );
  } else if (step === 1) {
    body = (
      <div>
        <h3 style={{ fontSize: 20, color: "var(--navy)", marginBottom: 16 }}>Racquets & string</h3>
        <Field label="How many racquets?">
          <div style={{ display: "flex", alignItems: "center", gap: 14 }}>
            <button onClick={() => set({ count: Math.max(1, b.count - 1) })} className="btn btn-ghost" style={{ width: 48, height: 48, padding: 0, borderRadius: 12, justifyContent: "center" }}><Icon name="minus" size={20} stroke={3} /></button>
            <div className="display" style={{ fontSize: 40, color: "var(--navy)", minWidth: 56, textAlign: "center" }}>{b.count}</div>
            <button onClick={() => set({ count: Math.min(20, b.count + 1) })} className="btn btn-ghost" style={{ width: 48, height: 48, padding: 0, borderRadius: 12, justifyContent: "center" }}><Icon name="plus" size={20} stroke={3} /></button>
            {b.service === "mobile" && b.count >= 8 && <span className="tag" style={{ background: "var(--ball)", color: "var(--navy-deep)" }}>10% volume rate</span>}
          </div>
        </Field>
        <Field label="Choose your string">
          <div style={{ display: "grid", gap: 9, maxHeight: 230, overflowY: "auto", paddingRight: 4 }}>
            <button onClick={() => set({ useOwn: true })} style={{ textAlign: "left", padding: "12px 14px", borderRadius: 11,
              border: `2px solid ${b.useOwn ? "var(--green)" : "var(--line)"}`, background: b.useOwn ? "var(--green-soft)" : "#fff",
              display: "flex", justifyContent: "space-between", alignItems: "center" }}>
              <span><b style={{ color: "var(--navy)" }}>I'll provide my own string</b><br /><span style={{ fontSize: 13, color: "var(--ink-2)" }}>Labor only</span></span>
              {b.useOwn && <Icon name="check" size={20} stroke={3} style={{ color: "var(--green)" }} />}
            </button>
            {flatStrings.map((s) => {
              const on = !b.useOwn && b.stringId === s.id;
              return (
                <button key={s.id} onClick={() => set({ useOwn: false, stringId: s.id })} style={{ textAlign: "left", padding: "12px 14px",
                  borderRadius: 11, border: `2px solid ${on ? "var(--green)" : "var(--line)"}`, background: on ? "var(--green-soft)" : "#fff",
                  display: "flex", justifyContent: "space-between", alignItems: "center", gap: 10 }}>
                  <span style={{ minWidth: 0 }}><b style={{ color: "var(--navy)" }}>{s.name}</b>
                    <br /><span style={{ fontSize: 13, color: "var(--ink-2)" }}>{s.cat} · {s.detail}</span></span>
                  <span style={{ fontWeight: 800, color: "var(--navy)", whiteSpace: "nowrap" }}>${s.price}<span style={{ fontSize: 12, color: "var(--ink-2)" }}>/ea</span></span>
                </button>
              );
            })}
          </div>
        </Field>
      </div>
    );
  } else if (step === 2) {
    body = (
      <div>
        <h3 style={{ fontSize: 20, color: "var(--navy)", marginBottom: 16 }}>Pick a day & time</h3>
        <Field label="Date">
          <div style={{ display: "flex", gap: 9, overflowX: "auto", paddingBottom: 6 }}>
            {days.map((d, i) => {
              const on = b.dayIdx === i;
              const info = dayInfo(d);
              const dis = info.full;
              return (
                <button key={i} disabled={dis} onClick={() => !dis && set({ dayIdx: i })} style={{ flexShrink: 0, width: 76, padding: "12px 8px", borderRadius: 12, position: "relative",
                  border: `2px solid ${on ? "var(--navy)" : "var(--line)"}`, background: on ? "var(--navy)" : "#fff", color: on ? "#fff" : (dis ? "#b9bfc8" : "var(--ink)"), textAlign: "center", cursor: dis ? "not-allowed" : "pointer", opacity: dis ? .6 : 1 }}>
                  <div style={{ fontSize: 11.5, fontWeight: 700, textTransform: "uppercase", letterSpacing: ".05em", opacity: .8 }}>{i === 0 ? "Today" : d.toLocaleDateString("en-US", { weekday: "short" })}</div>
                  <div className="display" style={{ fontSize: 24, marginTop: 2 }}>{d.getDate()}</div>
                  <div style={{ fontSize: 11, opacity: .75 }}>{dis ? "Full" : d.toLocaleDateString("en-US", { month: "short" })}</div>
                </button>
              );
            })}
          </div>
        </Field>
        <Field label="Time window">
          <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(120px,1fr))", gap: 9 }}>
            {TIME_SLOTS.map((t) => {
              const on = b.slot === t.id;
              const taken = selInfo.taken.has(t.id);
              return (
                <button key={t.id} disabled={taken} onClick={() => !taken && set({ slot: t.id })} style={{ padding: "13px 12px", borderRadius: 12, textAlign: "left",
                  border: `2px solid ${on ? "var(--green)" : "var(--line)"}`, background: on ? "var(--green-soft)" : "#fff", cursor: taken ? "not-allowed" : "pointer", opacity: taken ? .5 : 1 }}>
                  <div style={{ fontWeight: 800, color: "var(--navy)", display: "flex", justifyContent: "space-between", alignItems: "center" }}>{t.label}{taken && <span style={{ fontSize: 10.5, fontWeight: 800, color: "#c0413a", letterSpacing: ".04em" }}>BOOKED</span>}</div>
                  <div style={{ fontSize: 13, color: "var(--ink-2)" }}>{t.time}</div>
                </button>
              );
            })}
          </div>
        </Field>
        {slot && slot.evening && <p style={{ fontSize: 13, color: "var(--green-deep)", background: "var(--green-soft)", padding: "10px 14px", borderRadius: 10, fontWeight: 600 }}>
          Heads up: evening jobs add a +${feeVal(data, "fee_emergency")}/racquet after-hours fee.</p>}
      </div>
    );
  } else if (step === 3) {
    body = (
      <div>
        <h3 style={{ fontSize: 20, color: "var(--navy)", marginBottom: 16 }}>Your details</h3>
        <Field label="Name" required><input style={inputStyle} value={b.name} onChange={(e) => set({ name: e.target.value })} placeholder="Full name" /></Field>
        <div className="ars-form2" style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 14 }}>
          <Field label="Phone" required><input style={inputStyle} value={b.phone} onChange={(e) => set({ phone: e.target.value })} placeholder="(832) 000-0000" /></Field>
          <Field label="Email"><input style={inputStyle} value={b.email} onChange={(e) => set({ email: e.target.value })} placeholder="you@email.com" /></Field>
        </div>
        {needsAddress && <Field label={svc.needsLoc ? "Where should we meet you?" : "Pick-up address"} required>
          <input style={inputStyle} value={b.address} onChange={(e) => set({ address: e.target.value })} placeholder="Court, club, or home address" /></Field>}
        <Field label="Notes / special requests"><textarea style={{ ...inputStyle, minHeight: 76, resize: "vertical" }} value={b.notes}
          onChange={(e) => set({ notes: e.target.value })} placeholder="Tension (e.g. 55 lbs), hybrid setup, racquet model…" /></Field>
        <label style={{ display: "flex", gap: 12, alignItems: "center", padding: "13px 16px", borderRadius: 12,
          border: "2px solid var(--line)", cursor: "pointer", background: b.stencil ? "var(--green-soft)" : "#fff" }}>
          <input type="checkbox" checked={b.stencil} onChange={(e) => set({ stencil: e.target.checked })} style={{ width: 18, height: 18, accentColor: "var(--green)" }} />
          <span style={{ flex: 1 }}><b style={{ color: "var(--navy)" }}>Add stenciling</b> <span style={{ color: "var(--ink-2)", fontSize: 13.5 }}>(+${feeVal(data, "fee_stencil")}/racquet · red & black)</span></span>
        </label>
      </div>
    );
  } else if (step === 4) {
    const rows = [
      ["Labor", `${svc.title} × ${b.count}`, est.labor],
      [b.useOwn ? "String (your own)" : "String", b.useOwn ? "Labor only" : `${chosenString ? chosenString.name : ""} × ${b.count}`, est.stringCost],
    ];
    if (est.pickup) rows.push(["Pick-up & delivery", "Both directions", est.pickup]);
    if (est.stencil) rows.push(["Stenciling", `× ${b.count}`, est.stencil]);
    if (est.emergency) rows.push(["After-hours", `× ${b.count}`, est.emergency]);
    body = (
      <div>
        <h3 style={{ fontSize: 20, color: "var(--navy)", marginBottom: 14 }}>Review & confirm</h3>
        <div className="ars-review2" style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10, marginBottom: 18 }}>
          {[["Service", svc.title], ["Racquets", b.count], ["When", `${fmtDay(days[b.dayIdx])} · ${slot.label}`], ["Contact", b.name || "—"]].map(([k, v]) => (
            <div key={k} style={{ background: "var(--paper)", borderRadius: 11, padding: "11px 14px" }}>
              <div style={{ fontSize: 11.5, fontWeight: 800, textTransform: "uppercase", letterSpacing: ".08em", color: "var(--ink-2)" }}>{k}</div>
              <div style={{ fontWeight: 700, color: "var(--navy)", marginTop: 2 }}>{v}</div>
            </div>
          ))}
        </div>
        <div className="card" style={{ padding: "6px 18px", marginBottom: 4 }}>
          {rows.map(([k, sub, val], i) => (
            <div key={i} style={{ display: "flex", justifyContent: "space-between", alignItems: "center", padding: "11px 0",
              borderBottom: i === rows.length - 1 ? "none" : "1px solid var(--line)" }}>
              <div><div style={{ fontWeight: 700 }}>{k}</div><div style={{ fontSize: 12.5, color: "var(--ink-2)" }}>{sub}</div></div>
              <div style={{ fontWeight: 800, color: "var(--navy)" }}>{val === 0 ? "—" : `$${val}`}</div>
            </div>
          ))}
        </div>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", padding: "14px 18px",
          background: "var(--navy)", borderRadius: 14, color: "#fff", marginTop: 12 }}>
          <span style={{ fontWeight: 700 }}>Estimated total</span>
          <span className="display" style={{ fontSize: 30, color: "var(--ball)" }}>${est.total}</span>
        </div>
        <p style={{ fontSize: 12.5, color: "var(--ink-2)", marginTop: 10 }}>Estimate only — final total confirmed on completion. Payment is collected in person (cash, card, Venmo, Zelle).</p>
      </div>
    );
  } else {
    // confirmation
    const smsBody = encodeURIComponent(`New ARS booking — ${svc.title}, ${b.count} racquet(s), ${fmtDay(days[b.dayIdx])} ${slot.label}. ${b.name}, ${b.phone}.`);
    body = (
      <div style={{ textAlign: "center", padding: "10px 0 4px" }}>
        <div style={{ width: 86, height: 86, borderRadius: "50%", background: "var(--green-soft)", display: "grid", placeItems: "center", margin: "0 auto 18px" }}>
          <span style={{ color: "var(--green)" }}><Icon name="check" size={46} stroke={3} /></span>
        </div>
        <h3 className="display" style={{ fontSize: 32, color: "var(--navy)" }}>You're booked!</h3>
        <p style={{ color: "var(--ink-2)", maxWidth: 380, margin: "10px auto 22px" }}>
          Thanks {b.name.split(" ")[0] || "there"} — your {svc.title.toLowerCase()} for <b>{fmtDay(days[b.dayIdx])}, {slot.label}</b> is in. Andy will text {b.phone} to confirm.</p>
        <div style={{ display: "flex", gap: 10, justifyContent: "center", flexWrap: "wrap" }}>
          <a className="btn btn-green" href={`sms:8325126570?&body=${smsBody}`}><Icon name="phone" size={17} /> Text Andy now</a>
          <button className="btn btn-ghost" onClick={onClose}>Done</button>
        </div>
      </div>
    );
  }

  return (
    <div onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}
      style={{ position: "fixed", inset: 0, zIndex: 150, background: "rgba(14,38,73,.55)", backdropFilter: "blur(4px)",
        display: "flex", alignItems: "flex-start", justifyContent: "center", padding: "min(6vh,52px) 16px", overflowY: "auto" }}>
      <div className="rise" style={{ width: "100%", maxWidth: 560, background: "#fff", borderRadius: 22, overflow: "hidden",
        boxShadow: "var(--shadow-lg)", margin: "auto" }}>
        {header}
        <div style={{ padding: "24px 26px" }}>{body}</div>
        {step < 5 && (
          <div style={{ display: "flex", justifyContent: "space-between", gap: 12, padding: "16px 26px 24px", borderTop: "1px solid var(--line)" }}>
            <button className="btn btn-ghost" onClick={() => (step === 0 ? onClose() : setStep(step - 1))}>{step === 0 ? "Cancel" : "Back"}</button>
            {step < 4
              ? <button className="btn btn-ball" disabled={!canNext()} onClick={() => canNext() && setStep(step + 1)}
                  style={{ opacity: canNext() ? 1 : .45, cursor: canNext() ? "pointer" : "not-allowed" }}>Continue <Icon name="arrow" size={18} /></button>
              : <button className="btn btn-ball" onClick={submit}>Confirm booking <Icon name="check" size={18} stroke={3} /></button>}
          </div>
        )}
      </div>
    </div>
  );
}

window.BookingModal = BookingModal;
