// views.jsx — internal pages: Bookings / Event Types / Availability / Teams / Integrations / Billing / Settings

// ──────────────────────────────────────────────────────────────────────────
// Plan limits, permissions & helpers (used throughout all views)
// ──────────────────────────────────────────────────────────────────────────
const PLAN_LIMITS = {
  starter:      { maxServices: 3, maxStaff: 1, deposits: false, coupons: false, waitlists: false, smsReminders: false, whatsapp: false, calendarSync: false, customBranding: false, advancedAnalytics: false, whiteLabel: false, multiLocation: false, webhooks: false },
  professional: { maxServices: Infinity, maxStaff: 5, deposits: true, coupons: true, waitlists: true, smsReminders: true, whatsapp: true, calendarSync: true, customBranding: true, advancedAnalytics: true, whiteLabel: false, multiLocation: false, webhooks: false },
  business:     { maxServices: Infinity, maxStaff: Infinity, deposits: true, coupons: true, waitlists: true, smsReminders: true, whatsapp: true, calendarSync: true, customBranding: true, advancedAnalytics: true, whiteLabel: true, multiLocation: true, webhooks: true },
};

function getPlan(data) {
  if (data?.profile?.isSuperAdmin) return "business"; // super admins have full access
  const raw = (data?.settings?.plan || "starter").toLowerCase();
  return PLAN_LIMITS[raw] ? raw : "starter";
}

function planLimits(data) {
  return PLAN_LIMITS[getPlan(data)] || PLAN_LIMITS.starter;
}

function PlanGate({ feature, requiredPlan = "Professional" }) {
  return (
    <div style={{
      display:"flex", alignItems:"center", gap:10,
      padding:"10px 14px", background:"var(--surface-2)",
      borderRadius:8, border:"1px solid var(--border)",
    }}>
      <I.shield size={14} style={{flexShrink:0, color:"var(--text-muted)"}}/>
      <div>
        <div style={{fontSize:13, fontWeight:500, color:"var(--text)"}}>
          {feature} — {requiredPlan} plan required
        </div>
        <div style={{fontSize:12, color:"var(--text-muted)", marginTop:2}}>
          Upgrade your plan in Billing to unlock this feature.
        </div>
      </div>
    </div>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Booking Edit Modal (admin reschedule / cancel)
// ──────────────────────────────────────────────────────────────────────────
function BookingEditModal({ booking, data, onClose, onSave }) {
  const event = data.events.find(e => e.id === booking.eventId);
  const [date,          setDate]          = React.useState(booking.date);
  const [time,          setTime]          = React.useState(booking.time);
  const [status,        setStatus]        = React.useState(booking.status);
  const [notes,         setNotes]         = React.useState(booking.notes || "");
  const [saving,        setSaving]        = React.useState(false);
  const [reviewSent,    setReviewSent]    = React.useState(booking.reviewSent || false);
  const [reviewSending, setReviewSending] = React.useState(false);
  const [invoiceSent,   setInvoiceSent]   = React.useState(false);
  const [invoiceSending,setInvoiceSending]= React.useState(false);
  const [clientNote,       setClientNote]       = React.useState(booking.clientNote || "");
  const [clientNoteSaving, setClientNoteSaving] = React.useState(false);

  const profile     = data.profile || {};
  const isPast      = booking.date < new Date().toISOString().slice(0, 10);
  const reviewsOn   = !!(profile.notifications?.reviews) && !!(profile.reviewLink);
  const hasPaid     = !!(booking.paymentAmount > 0);

  const handleSendReview = async () => {
    if (reviewSending || reviewSent) return;
    setReviewSending(true);
    await sendReviewRequest(booking, profile);
    setReviewSent(true);
    setReviewSending(false);
  };

  const handleSendInvoice = async () => {
    if (invoiceSending || invoiceSent) return;
    setInvoiceSending(true);
    await generateInvoice(booking, profile);
    setInvoiceSent(true);
    setInvoiceSending(false);
  };

  // Exclude current booking so its slot shows as free
  const dataWithout = React.useMemo(() => ({
    ...data, bookings: data.bookings.filter(b => b.id !== booking.id),
  }), [data, booking.id]);

  const slots = React.useMemo(() => {
    if (!event || !date) return [];
    return getAvailableTimes({ data: dataWithout, event, dateIso: date });
  }, [event, date, dataWithout]);

  const handleSave = async () => {
    setSaving(true);
    await onSave(booking.id, { date, time, status, notes, clientNote });
    setSaving(false);
    onClose();
  };

  const saveClientNote = async () => {
    setClientNoteSaving(true);
    await onSave(booking.id, { date, time, status, notes, clientNote });
    setClientNoteSaving(false);
  };

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal-card" onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <div>
            <h3 style={{margin:0}}>{booking.guestName}</h3>
            <span className="sub" style={{fontSize:12}}>{booking.eventName}</span>
          </div>
          <button className="modal-close" onClick={onClose}><I.x size={14}/></button>
        </div>
        <div className="modal-body">
          <div className="field-grid">
            <div className="bk-field">
              <label>Date</label>
              <input type="date" className="bk-input" value={date}
                onChange={e => { setDate(e.target.value); setTime(""); }}/>
            </div>
            <div className="bk-field">
              <label>Time</label>
              <select className="bk-input" value={time} onChange={e => setTime(e.target.value)}>
                {time && !slots.includes(time) && <option value={time}>{time} (current)</option>}
                {slots.map(s => <option key={s} value={s}>{s}</option>)}
                {slots.length === 0 && !time && <option value="">No slots available</option>}
              </select>
            </div>
            <div className="bk-field" style={{gridColumn:"1 / -1"}}>
              <label>Status</label>
              <select className="bk-input" value={status} onChange={e => setStatus(e.target.value)}>
                <option>Confirmed</option>
                <option>Pending</option>
                <option>Rescheduled</option>
                <option>Cancelled</option>
                <option>No-show</option>
              </select>
            </div>
            <div className="bk-field" style={{gridColumn:"1 / -1"}}>
              <label>Notes</label>
              <textarea className="bk-textarea" rows={3} value={notes}
                onChange={e => setNotes(e.target.value)} placeholder="Internal notes…"/>
            </div>
          </div>

          {/* Client note */}
          <div style={{borderLeft:"3px solid var(--accent)", paddingLeft:12, marginTop:16}}>
            <div style={{fontWeight:600, fontSize:13, marginBottom:2}}>Client note</div>
            <div style={{fontSize:11, color:"var(--text-muted)", marginBottom:8}}>Saved against this client — visible on all their bookings</div>
            <textarea className="bk-textarea" rows={3} value={clientNote}
              onChange={e => setClientNote(e.target.value)} placeholder="Add a note about this client…"/>
            <div style={{display:"flex", justifyContent:"flex-end", marginTop:8}}>
              <button className="btn ghost" style={{fontSize:12}} onClick={saveClientNote} disabled={clientNoteSaving}>
                {clientNoteSaving ? "Saving…" : "Save note"}
              </button>
            </div>
          </div>
        </div>
        <div className="modal-foot">
          <button className="btn ghost" onClick={onClose}>Cancel</button>
          {isPast && reviewsOn && (
            <button className="btn ghost" onClick={handleSendReview} disabled={reviewSending || reviewSent}>
              {reviewSent ? <><I.check size={13}/> Review sent</> : reviewSending ? "Sending…" : <><I.star size={13}/> Send review request</>}
            </button>
          )}
          {hasPaid && (
            <button className="btn ghost" onClick={handleSendInvoice} disabled={invoiceSending || invoiceSent}>
              {invoiceSent ? <><I.check size={13}/> Invoice sent</> : invoiceSending ? "Sending…" : <><I.card size={13}/> Send invoice</>}
            </button>
          )}
          <button className="btn primary" onClick={handleSave} disabled={saving || !date || !time}>
            {saving ? "Saving…" : "Save changes"}
          </button>
        </div>
      </div>
    </div>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Bookings
// ──────────────────────────────────────────────────────────────────────────
// ─── Recurring Booking Modal ──────────────────────────────────────────────────
function RecurringBookingModal({ data, actions, onClose }) {
  const events = (data.events || []).filter(e => e.enabled !== false);
  const staff  = data.staff || [];

  const tomorrow = (() => { const d = new Date(); d.setDate(d.getDate()+1); return d.toISOString().slice(0,10); })();

  const [guestName,  setGuestName]  = React.useState("");
  const [guestEmail, setGuestEmail] = React.useState("");
  const [guestPhone, setGuestPhone] = React.useState("");
  const [serviceId,  setServiceId]  = React.useState(events[0]?.id || null);
  const [staffId,    setStaffId]    = React.useState(null);
  const [startDate,  setStartDate]  = React.useState(tomorrow);
  const [time,       setTime]       = React.useState("09:00");
  const [repeat,     setRepeat]     = React.useState("weekly");
  const [endType,    setEndType]    = React.useState("count");   // "count" | "date"
  const [count,      setCount]      = React.useState(4);
  const [endDate,    setEndDate]    = React.useState("");
  const [notes,      setNotes]      = React.useState("");
  const [saving,     setSaving]     = React.useState(false);
  const [done,       setDone]       = React.useState(null); // number of bookings created

  // Preview the dates that will be created
  const previewDates = React.useMemo(() => {
    if (!startDate) return [];
    const dates = [];
    const d = new Date(startDate + "T12:00:00");
    const DELTAS = { weekly: 7, fortnightly: 14, monthly: null };
    let limit = endType === "count" ? Math.min(count, 52) : 52;
    const cutoff = endType === "date" && endDate ? new Date(endDate + "T23:59:59") : null;
    let i = 0;
    while (i < limit) {
      const iso = d.toISOString().slice(0, 10);
      if (cutoff && d > cutoff) break;
      dates.push(iso);
      if (repeat === "monthly") {
        d.setMonth(d.getMonth() + 1);
      } else {
        d.setDate(d.getDate() + DELTAS[repeat]);
      }
      i++;
    }
    return dates;
  }, [startDate, repeat, endType, count, endDate]);

  const serviceObj = events.find(e => e.id === serviceId);
  const staffObj   = staff.find(s => s.id === staffId);

  const handleCreate = async () => {
    if (!guestName.trim()) { alert("Please enter the client name."); return; }
    if (!serviceId) { alert("Please select a service."); return; }
    if (previewDates.length === 0) { alert("No dates to create bookings for."); return; }
    setSaving(true);
    let created = 0;
    for (const date of previewDates) {
      await actions.addBooking({
        date, time,
        eventId: serviceId,
        name: guestName.trim(),
        email: guestEmail.trim() || null,
        phone: guestPhone.trim() || null,
        staffId: staffId || null,
        staffName: staffObj?.name || null,
        notes: notes.trim() || null,
      });
      created++;
    }
    setSaving(false);
    setDone(created);
  };

  const REPEAT_OPTIONS = [["weekly","Weekly"],["fortnightly","Every 2 weeks"],["monthly","Monthly"]];
  const TIME_SLOTS = ["07:00","07:30","08:00","08:30","09:00","09:30","10:00","10:30","11:00","11:30","12:00","12:30","13:00","13:30","14:00","14:30","15:00","15:30","16:00","16:30","17:00","17:30","18:00","18:30","19:00","19:30","20:00"];

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal-card" style={{maxWidth:560,maxHeight:"90vh",overflowY:"auto"}} onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <div>
            <h2 style={{margin:0,fontSize:17}}>Recurring booking</h2>
            <p style={{margin:"4px 0 0",fontSize:13,color:"var(--text-muted)"}}>Create a repeating series for one client.</p>
          </div>
          <button className="modal-close" onClick={onClose}><I.x size={16}/></button>
        </div>
        <div style={{padding:"20px 24px", display:"flex", flexDirection:"column", gap:18}}>

          {done !== null ? (
            <div style={{textAlign:"center", padding:"40px 20px"}}>
              <div style={{fontSize:36, marginBottom:12}}>✓</div>
              <h3 style={{margin:"0 0 8px"}}>All done!</h3>
              <p style={{color:"var(--text-muted)", margin:"0 0 20px"}}>Created {done} recurring bookings for {guestName}.</p>
              <button className="btn primary" onClick={onClose}>Close</button>
            </div>
          ) : (
            <>
              {/* Client */}
              <div className="field-grid" style={{gridTemplateColumns:"1fr 1fr",gap:12}}>
                <div className="bk-field">
                  <label>Client name *</label>
                  <input className="bk-input" value={guestName} onChange={e => setGuestName(e.target.value)} placeholder="Full name"/>
                </div>
                <div className="bk-field">
                  <label>Email</label>
                  <input className="bk-input" type="email" value={guestEmail} onChange={e => setGuestEmail(e.target.value)} placeholder="email@example.com"/>
                </div>
                <div className="bk-field">
                  <label>Phone</label>
                  <input className="bk-input" value={guestPhone} onChange={e => setGuestPhone(e.target.value)} placeholder="+44 7700 900000"/>
                </div>
              </div>

              {/* Service */}
              {events.length > 0 && (
                <div className="bk-field">
                  <label>Service *</label>
                  <select className="bk-input" value={serviceId || ""} onChange={e => setServiceId(e.target.value)}>
                    {events.map(ev => <option key={ev.id} value={ev.id}>{ev.name}</option>)}
                  </select>
                </div>
              )}

              {/* Staff */}
              {staff.length > 0 && (
                <div className="bk-field">
                  <label>Staff member</label>
                  <select className="bk-input" value={staffId || ""} onChange={e => setStaffId(e.target.value || null)}>
                    <option value="">Any / unassigned</option>
                    {staff.map(m => <option key={m.id} value={m.id}>{m.name}</option>)}
                  </select>
                </div>
              )}

              {/* Start date + time */}
              <div className="field-grid" style={{gridTemplateColumns:"1fr 1fr",gap:12}}>
                <div className="bk-field">
                  <label>Start date *</label>
                  <input className="bk-input" type="date" value={startDate} onChange={e => setStartDate(e.target.value)}/>
                </div>
                <div className="bk-field">
                  <label>Time</label>
                  <select className="bk-input" value={time} onChange={e => setTime(e.target.value)}>
                    {TIME_SLOTS.map(t => <option key={t} value={t}>{t}</option>)}
                  </select>
                </div>
              </div>

              {/* Repeat frequency */}
              <div className="bk-field">
                <label>Repeat</label>
                <div style={{display:"flex",gap:8,flexWrap:"wrap"}}>
                  {REPEAT_OPTIONS.map(([v,label]) => (
                    <button key={v} className={"chip " + (repeat === v ? "is-active" : "")} onClick={() => setRepeat(v)}>{label}</button>
                  ))}
                </div>
              </div>

              {/* End condition */}
              <div className="bk-field">
                <label>Ends</label>
                <div style={{display:"flex",gap:8,marginBottom:10}}>
                  <button className={"chip " + (endType === "count" ? "is-active" : "")} onClick={() => setEndType("count")}>After N sessions</button>
                  <button className={"chip " + (endType === "date" ? "is-active" : "")} onClick={() => setEndType("date")}>On a date</button>
                </div>
                {endType === "count" ? (
                  <div style={{display:"flex",alignItems:"center",gap:10}}>
                    <input className="bk-input" type="number" min={1} max={52} value={count} onChange={e => setCount(Math.max(1,Math.min(52,Number(e.target.value))))} style={{width:80}}/>
                    <span style={{fontSize:13,color:"var(--text-muted)"}}>sessions</span>
                  </div>
                ) : (
                  <input className="bk-input" type="date" value={endDate} onChange={e => setEndDate(e.target.value)}/>
                )}
              </div>

              {/* Notes */}
              <div className="bk-field">
                <label>Notes</label>
                <textarea className="bk-input" rows={2} style={{resize:"vertical"}} value={notes} onChange={e => setNotes(e.target.value)} placeholder="Any notes for all sessions…"/>
              </div>

              {/* Preview */}
              {previewDates.length > 0 && (
                <div style={{background:"var(--surface-2)",border:"1px solid var(--border)",borderRadius:10,padding:"12px 16px"}}>
                  <div style={{fontSize:12,fontWeight:600,textTransform:"uppercase",letterSpacing:"0.05em",color:"var(--text-muted)",marginBottom:8}}>
                    Preview — {previewDates.length} session{previewDates.length !== 1 ? "s" : ""} will be created
                  </div>
                  <div style={{display:"flex",flexWrap:"wrap",gap:6}}>
                    {previewDates.slice(0, 12).map(d => (
                      <span key={d} style={{fontSize:12,background:"var(--surface)",border:"1px solid var(--border)",borderRadius:6,padding:"3px 8px",color:"var(--text-muted)"}}>
                        {new Date(d+"T12:00:00").toLocaleDateString("en-GB",{day:"numeric",month:"short"})}
                      </span>
                    ))}
                    {previewDates.length > 12 && (
                      <span style={{fontSize:12,color:"var(--text-muted)",padding:"3px 4px"}}>+{previewDates.length-12} more</span>
                    )}
                  </div>
                </div>
              )}

              <div style={{display:"flex",gap:10,justifyContent:"flex-end",paddingTop:4}}>
                <button className="btn ghost" onClick={onClose}>Cancel</button>
                <button className="btn primary" disabled={saving || previewDates.length === 0} onClick={handleCreate}>
                  {saving ? "Creating…" : `Create ${previewDates.length} booking${previewDates.length !== 1 ? "s" : ""}`}
                </button>
              </div>
            </>
          )}
        </div>
      </div>
    </div>
  );
}

function ViewBookings({ industry, data, actions, onOpenBooking }) {
  const [filter, setFilter] = React.useState("all");
  const [search, setSearch] = React.useState("");
  const [editingBooking, setEditingBooking] = React.useState(null);
  const [showWaitlist, setShowWaitlist] = React.useState(false);
  const [showRecurring, setShowRecurring] = React.useState(false);

  const all = data.bookings;
  const waitlistAll = data.waitlist || [];

  const counts = {
    all: all.length,
    confirmed: all.filter(b => b.status === "Confirmed").length,
    pending: all.filter(b => b.status === "Pending").length,
    cancelled: all.filter(b => b.status === "Cancelled").length,
  };

  const filtered = all.filter(b => {
    if (filter !== "all" && b.status.toLowerCase() !== filter) return false;
    if (search && !(b.guestName + b.eventName + b.guestEmail).toLowerCase().includes(search.toLowerCase())) return false;
    return true;
  });

  const FILTERS = [
    { id: "all", label: "All" },
    { id: "confirmed", label: "Confirmed" },
    { id: "pending", label: "Pending" },
    { id: "cancelled", label: "Cancelled" },
  ];

  return (
    <>
      <div className="view-h">
        <div>
          <h1>Bookings</h1>
          <div className="sub">Every appointment across your services.</div>
        </div>
        <div className="view-actions">
          {!showWaitlist && (
            <button className="btn ghost" onClick={() => downloadCsv("nexus-bookings.csv", [
              ["Date","Time","Service","Guest name","Email","Phone","Status","Payment status","Payment amount","Payment provider","Staff","Coupon","Discount","Source","Booking ID","Created at"],
              ...all.map(b => [b.date, b.time, b.eventName, b.guestName, b.guestEmail, b.guestPhone||"", b.status, b.paymentStatus||"", b.paymentAmount||0, b.paymentProvider||"", b.staffName||"", b.couponCode||"", b.discountApplied||0, b.source||"", b.id, b.createdAt||""])
            ])}><I.arrow size={13}/> Export CSV</button>
          )}
          <button className="btn ghost" title="Create recurring booking series" onClick={() => setShowRecurring(true)}><I.clock size={13}/> Recurring</button>
          <button className="btn primary" onClick={onOpenBooking}><I.cal size={13}/> New booking</button>
        </div>
      </div>
      {showRecurring && <RecurringBookingModal data={data} actions={actions} onClose={() => setShowRecurring(false)}/>}

      {/* Tab switcher */}
      <div style={{display:"flex", gap:8, marginBottom:16}}>
        <button
          className={"chip " + (!showWaitlist ? "is-active" : "")}
          onClick={() => setShowWaitlist(false)}>
          Bookings <span className="count">{all.length}</span>
        </button>
        <button
          className={"chip " + (showWaitlist ? "is-active" : "")}
          onClick={() => setShowWaitlist(true)}>
          <I.clock size={11}/> Waitlist <span className="count">{waitlistAll.length}</span>
        </button>
      </div>

      {showWaitlist ? (
        /* ── Waitlist table ── */
        <div className="card">
          <table className="table">
            <thead>
              <tr>
                <th>Date & Time</th>
                <th>{industry.serviceLabel}</th>
                <th>Guest</th>
                <th>Status</th>
                <th></th>
              </tr>
            </thead>
            <tbody>
              {waitlistAll.length === 0 && (
                <tr><td colSpan="5" style={{padding:"40px 20px", textAlign:"center", color:"var(--text-muted)"}}>
                  No one on the waitlist yet.
                </td></tr>
              )}
              {waitlistAll.map((w, i) => (
                <tr key={w.id || i}>
                  <td><span className="cell-date"><I.cal size={13}/>{w.date ? formatIsoDate(w.date, { year: true }) : "—"}{w.time ? ` · ${w.time}` : ""}</span></td>
                  <td>{w.eventName}</td>
                  <td>
                    <div>{w.guestName}</div>
                    <div style={{fontSize:11, color:"var(--text-muted)"}}>{w.guestEmail}</div>
                  </td>
                  <td>
                    <span className={"pill " + (w.status === "Notified" ? "confirmed" : w.status === "Removed" ? "cancelled" : "pending")}>
                      {w.status}
                    </span>
                  </td>
                  <td style={{textAlign:"right"}}>
                    <div style={{display:"flex", gap:6, justifyContent:"flex-end"}}>
                      {w.status === "Waiting" && (
                        <button className="btn ghost" style={{padding:"4px 8px", fontSize:12, color:"var(--accent)"}}
                          onClick={() => actions.notifyWaitlistEntry(w.id)}>
                          Notify
                        </button>
                      )}
                      <button className="btn ghost" style={{padding:"4px 8px", fontSize:12, color:"var(--danger)"}}
                        onClick={() => actions.removeWaitlistEntry(w.id)}>
                        Remove
                      </button>
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
          <div className="pagination">
            <span>{waitlistAll.length} {waitlistAll.length === 1 ? "person" : "people"} waiting</span>
          </div>
        </div>
      ) : (
        /* ── Bookings table ── */
        <>
          <div className="toolbar">
            <div className="search">
              <I.show size={14}/>
              <input placeholder="Search guest or service…" value={search} onChange={e => setSearch(e.target.value)}/>
            </div>
            <div className="chips">
              {FILTERS.map(f => (
                <button key={f.id}
                  className={"chip " + (filter === f.id ? "is-active" : "")}
                  onClick={() => setFilter(f.id)}>
                  {f.label} <span className="count">{counts[f.id]}</span>
                </button>
              ))}
            </div>
            <div style={{marginLeft: "auto"}}>
              <button className="btn ghost"><I.cal size={13}/> May 1 – 31, 2026</button>
            </div>
          </div>

          <div className="card">
            <table className="table">
              <thead>
                <tr>
                  <th>Date & Time</th>
                  <th>{industry.serviceLabel}</th>
                  <th>Guest</th>
                  <th>Status</th>
                  <th></th>
                </tr>
              </thead>
              <tbody>
                {filtered.length === 0 && (
                  <tr><td colSpan="5" style={{padding:"40px 20px", textAlign:"center", color:"var(--text-muted)"}}>
                    No bookings match your filters.
                  </td></tr>
                )}
                {filtered.map((r, i) => (
                  <tr key={i}>
                    <td><span className="cell-date"><I.cal size={13}/>{bookingDateTimeLabel(r)}</span></td>
                    <td>{r.eventName}</td>
                    <td>{r.guestName}</td>
                    <td><span className={"pill " + r.status.toLowerCase()}>{r.status}</span></td>
                    <td style={{textAlign:"right", display:"flex", gap:6, alignItems:"center", justifyContent:"flex-end"}}>
                      <select className="status-select" value={r.status} onChange={(e) => actions.updateBookingStatus(r.id, e.target.value)}>
                        <option>Confirmed</option>
                        <option>Pending</option>
                        <option>Rescheduled</option>
                        <option>Cancelled</option>
                        <option>No-show</option>
                      </select>
                      <button className="btn ghost" style={{padding:"4px 8px", fontSize:12}} onClick={() => setEditingBooking(r)}>Edit</button>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
            <div className="pagination">
              <span>Showing {filtered.length} of {all.length}</span>
              <div className="nums">
                <button disabled><I.chevL size={12}/></button>
                <button className="is-active">1</button>
                <button>2</button>
                <button>3</button>
                <button><I.chev size={12}/></button>
              </div>
            </div>
          </div>
          {editingBooking && (
            <BookingEditModal
              booking={editingBooking}
              data={data}
              onClose={() => setEditingBooking(null)}
              onSave={(id, patch) => actions.rescheduleBooking(id, patch)}
            />
          )}
        </>
      )}
    </>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Event Types
// ──────────────────────────────────────────────────────────────────────────
// ──────────────────────────────────────────────────────────────────────────
// Share Modal
// ──────────────────────────────────────────────────────────────────────────
function ShareModal({ event, profile, onClose }) {
  const [copied, setCopied] = React.useState(null); // null | "link" | "instagram" | "website"

  const bookingUrl = getBookingUrl(profile.bookingUrl);
  const caption = `📅 ${event.name}${event.duration ? ` — ${event.duration} mins` : ""}${event.price ? ` · £${event.price}` : ""}${event.maxSpaces ? ` · ${event.maxSpaces} spaces` : ""}\n\n${profile.bio || "Book your spot now — spaces are limited."}\n\n🔗 ${bookingUrl}`;

  const copy = (text, key) => {
    navigator.clipboard?.writeText(text).catch(() => {});
    setCopied(key);
    setTimeout(() => setCopied(null), 2200);
  };

  const shareToFacebook = () => {
    window.open(`https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(bookingUrl)}&quote=${encodeURIComponent(caption)}`, "_blank", "width=600,height=500");
  };

  return (
    <div className="modal-backdrop" role="dialog" aria-modal="true">
      <div className="modal share-modal">
        <div className="modal-h">
          <div>
            <h3>Share class</h3>
            <div className="sub" style={{marginTop:2}}>{event.name}</div>
          </div>
          <button className="row-actions" onClick={onClose}><I.more size={16}/></button>
        </div>

        {/* Preview caption */}
        <div className="share-preview">
          <div className="share-preview-label">Caption preview</div>
          <div className="share-preview-text">{caption}</div>
        </div>

        {/* Platform buttons */}
        <div className="share-platforms">

          {/* Facebook */}
          <button className="share-platform-btn" style={{"--platform-color":"#1877F2"}} onClick={shareToFacebook}>
            <span className="share-platform-icon" style={{background:"#1877F2"}}>
              <svg width="18" height="18" viewBox="0 0 24 24" fill="white"><path d="M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z"/></svg>
            </span>
            <div className="share-platform-info">
              <div className="share-platform-name">Facebook</div>
              <div className="share-platform-desc">Open share dialog</div>
            </div>
            <I.arrow size={14} className="share-platform-arrow"/>
          </button>

          {/* Instagram */}
          <button className="share-platform-btn" style={{"--platform-color":"#E1306C"}}
            onClick={() => copy(caption, "instagram")}>
            <span className="share-platform-icon" style={{background:"linear-gradient(135deg,#f09433,#e6683c,#dc2743,#cc2366,#bc1888)"}}>
              <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="white" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="2" y="2" width="20" height="20" rx="5"/><circle cx="12" cy="12" r="4.5"/><circle cx="17.5" cy="6.5" r="1" fill="white" stroke="none"/></svg>
            </span>
            <div className="share-platform-info">
              <div className="share-platform-name">Instagram</div>
              <div className="share-platform-desc">Copy caption &amp; link to paste</div>
            </div>
            {copied === "instagram"
              ? <span className="share-copied"><I.check size={13}/> Copied</span>
              : <I.copy size={14} className="share-platform-arrow"/>}
          </button>

          {/* Website / direct link */}
          <button className="share-platform-btn" style={{"--platform-color":"var(--accent)"}}
            onClick={() => copy(bookingUrl, "website")}>
            <span className="share-platform-icon" style={{background:"var(--accent)"}}>
              <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="white" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="9"/><path d="M3.5 12h17M12 3.5c2.5 3 2.5 14 0 17M12 3.5c-2.5 3-2.5 14 0 17"/></svg>
            </span>
            <div className="share-platform-info">
              <div className="share-platform-name">Website</div>
              <div className="share-platform-desc">{bookingUrl}</div>
            </div>
            {copied === "website"
              ? <span className="share-copied"><I.check size={13}/> Copied</span>
              : <I.copy size={14} className="share-platform-arrow"/>}
          </button>

        </div>

        <div className="modal-actions">
          <button className="btn ghost" onClick={onClose}>Close</button>
        </div>
      </div>
    </div>
  );
}

function ViewEventTypes({ industry, data, actions }) {
  const [editing, setEditing] = React.useState(null);
  const [sharing, setSharing] = React.useState(null);
  const currency = getCurrency(data.profile.currency);
  const bookingCounts = data.bookings.reduce((acc, b) => {
    acc[b.eventName] = (acc[b.eventName] || 0) + 1;
    return acc;
  }, {});
  const blankEvent = { name: "", duration: 30, slotInterval: 30, bufferAfter: 0, color: "#efa403", price: 0, location: "", description: "", questions: [], requireTerms: false, termsText: "", paymentMode: "none", depositAmount: "", useCustomAvailability: false, customAvailability: [], enabled: true, cancellationPolicy: "flexible", cancellationHours: 24 };

  const limits = planLimits(data);
  const atServiceLimit = data.events.length >= limits.maxServices;

  return (
    <>
      <div className="view-h">
        <div>
          <h1>Event Types</h1>
          <div className="sub">Configure the services you offer and share booking links.</div>
        </div>
        <div className="view-actions">
          <button className="btn primary"
            onClick={() => !atServiceLimit && setEditing(blankEvent)}
            disabled={atServiceLimit}
            title={atServiceLimit ? `Service limit reached — upgrade your plan to add more` : undefined}>
            <I.tag size={13}/> New service
            {atServiceLimit && <span style={{marginLeft:6, fontSize:11, opacity:0.75}}>({limits.maxServices} max)</span>}
          </button>
        </div>
      </div>
      {atServiceLimit && limits.maxServices < Infinity && (
        <div style={{marginBottom:16}}>
          <PlanGate feature={`${limits.maxServices} service types`} requiredPlan="Professional"/>
        </div>
      )}

      <div className="events-grid">
        {data.events.map((e) => (
          <div key={e.id} className={"evt-card " + (e.enabled ? "" : "is-off")}>
            <div className="evt-card-h">
              <div className="evt-card-title">
                <div className="swatch-lg" style={{background: e.color}}/>
                <div>
                  <h3>{e.name}</h3>
                  <div className="duration"><I.clock size={11} style={{verticalAlign:"-1px", marginRight:4}}/>{e.duration} minutes · every {e.slotInterval || 30}</div>
                </div>
              </div>
              <label className="switch">
                <input type="checkbox" checked={e.enabled}
                  onChange={() => actions.toggleEvent(e.id)}/>
                <span className="track"><span className="knob"/></span>
              </label>
            </div>
            <div className="desc">{e.description}</div>
            <div className="evt-location"><I.location size={12}/>{
              e.location === "google_meet" ? "Google Meet" :
              e.location === "zoom"        ? "Zoom" :
              e.location === "teams"       ? "Microsoft Teams" :
              e.location || "No location set"
            }</div>
            <div className="evt-card-meta">
              <div className="price">{e.price ? formatMoney(e.price, data.profile.currency) : "Free"}</div>
              {e.useCustomAvailability && <span className="bookings-count">Custom hours</span>}
              {Number(e.bufferAfter || 0) > 0 && <span className="bookings-count"><I.clock size={11} style={{verticalAlign:"-1px", marginRight:3}}/>+{e.bufferAfter}m buffer</span>}
              {Number(e.maxSpaces || 0) > 0 && <span className="bookings-count"><I.users size={11} style={{verticalAlign:"-1px", marginRight:3}}/>{e.maxSpaces} spaces</span>}
              {e.paymentMode === "term" && Number(e.termWeeks || 0) > 0 && <span className="bookings-count"><I.cal size={11} style={{verticalAlign:"-1px", marginRight:3}}/>{e.termWeeks}-wk term</span>}
              {e.paymentMode === "deposit" && <span className="bookings-count">Deposit</span>}
              {e.paymentMode === "term" && Number(e.classPrice || 0) > 0 && Number(e.termWeeks || 0) > 0 && (() => {
                const saving = (Number(e.classPrice) * Number(e.termWeeks)) - Number(e.price || 0);
                return saving > 0 ? <span className="bookings-count saving-badge">Save {formatMoney(saving, data.profile.currency)}</span> : null;
              })()}
              <span className="bookings-count">{bookingCounts[e.name] || 0} bookings</span>
            </div>
            <div className="evt-card-actions">
              <button title="Share" onClick={() => setSharing(e)}><I.share size={13}/></button>
              <button title="Edit" onClick={() => setEditing(e)}><I.cog size={13}/></button>
              <button title="Delete" onClick={() => actions.deleteEvent(e.id)}><I.more size={13}/></button>
            </div>
          </div>
        ))}
        <button className="add-card" onClick={() => !atServiceLimit && setEditing(blankEvent)}
          disabled={atServiceLimit}
          style={atServiceLimit ? {opacity:0.45, cursor:"not-allowed"} : undefined}>
          <span className="plus"><I.tag size={16}/></span>
          {atServiceLimit ? `Plan limit (${limits.maxServices})` : "New service"}
        </button>
      </div>
      {editing && (
        <EventEditor
          event={editing}
          currency={currency.symbol}
          onClose={() => setEditing(null)}
          onSave={(event) => { actions.saveEvent(event); setEditing(null); }}
        />
      )}
      {sharing && (
        <ShareModal
          event={sharing}
          profile={data.profile}
          onClose={() => setSharing(null)}
        />
      )}
    </>
  );
}

function EventEditor({ event, currency, onClose, onSave }) {
  const [draft, setDraft] = React.useState(() => normalizeEvent ? normalizeEvent(event) : event);
  const set = (key, value) => setDraft((d) => ({ ...d, [key]: value }));
  const customDays = draft.customAvailability?.length ? draft.customAvailability : makeAvailability();
  const setCustomDay = (index, patch) => setDraft((d) => {
    const next = (d.customAvailability?.length ? d.customAvailability : makeAvailability()).map((day, i) => i === index ? { ...day, ...patch } : day);
    return { ...d, customAvailability: next };
  });
  const valid = draft.name.trim().length > 1 && Number(draft.duration) > 0;
  const addQuestion = () => setDraft((d) => ({
    ...d,
    questions: [...(d.questions || []), { id: uid("q"), label: "", type: "text", required: false }],
  }));
  const updateQuestion = (id, patch) => setDraft((d) => ({
    ...d,
    questions: (d.questions || []).map((q) => q.id === id ? { ...q, ...patch } : q),
  }));
  const removeQuestion = (id) => setDraft((d) => ({
    ...d,
    questions: (d.questions || []).filter((q) => q.id !== id),
  }));
  return (
    <div className="modal-backdrop" role="dialog" aria-modal="true">
      <div className="modal">
        <div className="modal-h">
          <h3>{event.id ? "Edit service" : "New service"}</h3>
          <button className="row-actions" onClick={onClose}><I.more size={16}/></button>
        </div>
        <div className="field-grid">
          <div className="bk-field"><label>Name</label><input className="bk-input" value={draft.name} onChange={(e) => set("name", e.target.value)}/></div>
          <div className="bk-field">
            <label>Duration</label>
            <select className="bk-input" value={draft.duration} onChange={(e) => set("duration", e.target.value)}>
              <option value="15">15 minutes</option>
              <option value="30">30 minutes</option>
              <option value="45">45 minutes</option>
              <option value="60">60 minutes</option>
            </select>
          </div>
          <div className="bk-field">
            <label>Slot starts every</label>
            <select className="bk-input" value={draft.slotInterval || 30} onChange={(e) => set("slotInterval", e.target.value)}>
              <option value="15">15 minutes</option>
              <option value="30">30 minutes</option>
              <option value="45">45 minutes</option>
              <option value="60">60 minutes</option>
            </select>
          </div>
          <div className="bk-field">
            <label>Buffer after appointment</label>
            <select className="bk-input" value={draft.bufferAfter || 0} onChange={(e) => set("bufferAfter", Number(e.target.value))}>
              <option value="0">No buffer</option>
              <option value="5">5 minutes</option>
              <option value="10">10 minutes</option>
              <option value="15">15 minutes</option>
              <option value="20">20 minutes</option>
              <option value="30">30 minutes</option>
              <option value="45">45 minutes</option>
              <option value="60">60 minutes</option>
            </select>
          </div>
          <div className="bk-field">
            <label>Max spaces <span className="opt">(0 = unlimited)</span></label>
            <input className="bk-input" type="text" inputMode="numeric" placeholder="0" value={draft.maxSpaces || ""} onChange={(e) => set("maxSpaces", e.target.value)}/>
          </div>
          <div className="bk-field">
            <label>Meeting type</label>
            <select className="bk-input" value={["google_meet","zoom","teams"].includes(draft.location) ? draft.location : "in_person"} onChange={(e) => {
              const v = e.target.value;
              set("location", v === "in_person" ? "" : v);
            }}>
              <option value="in_person">In person / custom location</option>
              <option value="google_meet">Google Meet</option>
              <option value="zoom">Zoom</option>
              <option value="teams">Microsoft Teams</option>
            </select>
          </div>
          {!["google_meet","zoom","teams"].includes(draft.location) && (
            <div className="bk-field"><label>Location</label><input className="bk-input" placeholder="e.g. 123 High Street" value={draft.location} onChange={(e) => set("location", e.target.value)}/></div>
          )}
          {["google_meet","zoom","teams"].includes(draft.location) && (
            <div className="bk-field" style={{gridColumn:"1/-1"}}>
              <div style={{fontSize:12,color:"var(--text-muted)",background:"var(--surface-2,#f4f5f7)",borderRadius:8,padding:"10px 14px"}}>
                A meeting link will be created automatically when a booking is made and sent to the guest.
              </div>
            </div>
          )}
        </div>
        <div className="bk-field" style={{marginTop:16}}>
          <label>Description</label>
          <textarea className="bk-textarea" value={draft.description} onChange={(e) => set("description", e.target.value)}/>
        </div>
        <div className="color-picker-row" style={{marginTop:16}}>
          {["#efa403", "#7aa7ff", "#a78bfa", "#6ee7a3", "#f59e9e"].map((color) => (
            <button key={color} className={"color-swatch " + (draft.color === color ? "is-selected" : "")} style={{background: color}} onClick={() => set("color", color)}/>
          ))}
        </div>
        <div className="event-editor-section">
          <div className="card-h" style={{padding:0, border:0, marginBottom:10}}>
            <h3>Payments</h3>
            <span className="sub">Stripe and PayPal can be offered at checkout.</span>
          </div>
          <div className="field-grid">
            <div className="bk-field">
              <label>Payment at booking</label>
              <select className="bk-input" value={draft.paymentMode || "none"} onChange={(e) => set("paymentMode", e.target.value)}>
                <option value="none">No payment required</option>
                <option value="full">Pay per class (full price)</option>
                <option value="deposit">Pay per class (deposit)</option>
                <option value="term">Pay by term (full term upfront)</option>
              </select>
            </div>
            {(draft.paymentMode === "none" || draft.paymentMode === "full") && (
              <div className="bk-field">
                <label>Price per class ({currency})</label>
                <input className="bk-input" type="text" inputMode="numeric" value={draft.price} onChange={(e) => set("price", e.target.value)}/>
              </div>
            )}
            {draft.paymentMode === "deposit" && (
              <div className="bk-field">
                <label>Deposit amount ({currency})</label>
                <input className="bk-input" type="text" inputMode="numeric" value={draft.depositAmount || ""} onChange={(e) => set("depositAmount", e.target.value)}/>
              </div>
            )}
            {draft.paymentMode === "term" && (
              <>
                <div className="bk-field">
                  <label>Term price ({currency})</label>
                  <input className="bk-input" type="text" inputMode="numeric" value={draft.price} onChange={(e) => set("price", e.target.value)}/>
                </div>
                <div className="bk-field">
                  <label>Price per individual class ({currency})</label>
                  <input className="bk-input" type="text" inputMode="numeric" value={draft.classPrice || ""} placeholder="0.00" onChange={(e) => set("classPrice", e.target.value)}/>
                </div>
                <div className="bk-field" style={{gridColumn:"1 / -1"}}>
                  <label>Term length</label>
                  <select className="bk-input" value={draft.termWeeks || 4} onChange={(e) => set("termWeeks", Number(e.target.value))}>
                    <option value={4}>4 weeks</option>
                    <option value={6}>6 weeks</option>
                    <option value={8}>8 weeks</option>
                    <option value={10}>10 weeks</option>
                    <option value={12}>12 weeks</option>
                  </select>
                </div>
                {(() => {
                  const saving = (Number(draft.classPrice || 0) * Number(draft.termWeeks || 0)) - Number(draft.price || 0);
                  if (saving <= 0 || !Number(draft.classPrice) || !Number(draft.price)) return null;
                  return (
                    <div className="term-saving-preview" style={{gridColumn:"1 / -1"}}>
                      <I.tag size={13}/> Saves {formatMoney(saving, currency)} vs booking per class
                    </div>
                  );
                })()}
              </>
            )}
          </div>
        </div>
        <div className="event-editor-section">
          <div className="card-h" style={{padding:0, border:0, marginBottom:10}}>
            <h3>Service-specific hours</h3>
          </div>
          <label className="mini-check">
            <input type="checkbox" checked={!!draft.useCustomAvailability} onChange={() => {
              setDraft((d) => ({
                ...d,
                useCustomAvailability: !d.useCustomAvailability,
                customAvailability: d.customAvailability?.length ? d.customAvailability : makeAvailability(),
              }));
            }}/>
            Use different hours for this service
          </label>
          {draft.useCustomAvailability && (
            <div className="service-hours-editor">
              {customDays.map((day, index) => (
                <div className="service-hours-row" key={day.name}>
                  <label className="switch">
                    <input type="checkbox" checked={!!day.on} onChange={() => setCustomDay(index, { on: !day.on })}/>
                    <span className="track"><span className="knob"/></span>
                  </label>
                  <span>{day.name}</span>
                  {day.on ? (
                    <>
                      <input className="time-input" type="time" value={day.start} onChange={(e) => setCustomDay(index, { start: e.target.value })}/>
                      <input className="time-input" type="time" value={day.end} onChange={(e) => setCustomDay(index, { end: e.target.value })}/>
                    </>
                  ) : (
                    <span className="unavail-tag">Unavailable</span>
                  )}
                </div>
              ))}
            </div>
          )}
        </div>
        <div className="event-editor-section">
          <div className="card-h" style={{padding:0, border:0, marginBottom:10}}>
            <h3>Booking questions</h3>
            <button className="card-link" onClick={addQuestion}>+ Add question</button>
          </div>
          <div className="question-list">
            {(draft.questions || []).map((question) => (
              <div className="question-row" key={question.id}>
                <input className="bk-input" placeholder="Question shown to guest" value={question.label} onChange={(e) => updateQuestion(question.id, { label: e.target.value })}/>
                <select className="bk-input" value={question.type || "text"} onChange={(e) => updateQuestion(question.id, { type: e.target.value })}>
                  <option value="text">Short answer</option>
                  <option value="textarea">Long answer</option>
                </select>
                <label className="mini-check"><input type="checkbox" checked={!!question.required} onChange={() => updateQuestion(question.id, { required: !question.required })}/> Required</label>
                <button className="row-actions" onClick={() => removeQuestion(question.id)}><I.more size={14}/></button>
              </div>
            ))}
            {(draft.questions || []).length === 0 && <div className="empty-inline">No extra questions yet.</div>}
          </div>
        </div>
        <div className="event-editor-section">
          <label className="mini-check">
            <input type="checkbox" checked={!!draft.requireTerms} onChange={() => set("requireTerms", !draft.requireTerms)}/>
            Require guest to accept terms
          </label>
          {draft.requireTerms && (
            <textarea className="bk-textarea" style={{marginTop:10}} value={draft.termsText || ""} onChange={(e) => set("termsText", e.target.value)} placeholder="Terms text shown beside the checkbox"/>
          )}
        </div>

        <div className="event-editor-section">
          <div style={{fontWeight:600,fontSize:13,marginBottom:10}}>Cancellation policy</div>
          <div style={{display:"flex",gap:8,marginBottom: draft.cancellationPolicy !== "none" ? 12 : 0}}>
            <button
              type="button"
              className={"btn " + (draft.cancellationPolicy !== "none" ? "primary" : "ghost")}
              style={{fontSize:13,padding:"6px 14px"}}
              onClick={() => set("cancellationPolicy", "flexible")}
            >
              Flexible
            </button>
            <button
              type="button"
              className={"btn " + (draft.cancellationPolicy === "none" ? "primary" : "ghost")}
              style={{fontSize:13,padding:"6px 14px"}}
              onClick={() => set("cancellationPolicy", "none")}
            >
              No cancellations
            </button>
          </div>
          {draft.cancellationPolicy !== "none" && (
            <div style={{display:"flex",alignItems:"center",gap:10,flexWrap:"wrap"}}>
              <span style={{fontSize:13,color:"var(--text-muted)"}}>Free cancellation up to</span>
              <input
                type="number"
                className="bk-input"
                style={{width:70,textAlign:"center",padding:"6px 8px"}}
                value={draft.cancellationHours ?? 24}
                min={0}
                step={1}
                onChange={e => set("cancellationHours", Number(e.target.value))}
              />
              <span style={{fontSize:13,color:"var(--text-muted)"}}>hours before the appointment</span>
            </div>
          )}
          {draft.cancellationPolicy === "none" && (
            <p style={{fontSize:12,color:"var(--text-muted)",margin:"6px 0 0"}}>Guests will not be able to cancel once booked.</p>
          )}
        </div>

        <div className="modal-actions">
          <button className="btn ghost" onClick={onClose}>Cancel</button>
          <button className="btn primary" disabled={!valid} onClick={() => onSave(draft)}>Save service</button>
        </div>
      </div>
    </div>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Availability
// ──────────────────────────────────────────────────────────────────────────
function ViewAvailability({ data, actions }) {
  const [days, setDays] = React.useState(data.availability);
  const [blockDate, setBlockDate] = React.useState(todayIso());
  const [blockReason, setBlockReason] = React.useState("");
  const [timeBlock, setTimeBlock] = React.useState({ date: todayIso(), start: "12:00", end: "13:00", reason: "" });
  React.useEffect(() => setDays(data.availability), [data.availability]);

  return (
    <>
      <div className="view-h">
        <div>
          <h1>Availability</h1>
          <div className="sub">Set when you're open. Blocked dates override your weekly hours.</div>
        </div>
        <div className="view-actions">
          <button className="btn ghost"><I.copy size={13}/> Copy from another team member</button>
          <button className="btn primary" onClick={() => actions.saveAvailability(days)}>Save changes</button>
        </div>
      </div>

      <div className="avail-grid">
        <div className="card">
          <div className="card-h">
            <h3>Weekly hours <span className="sub">(GMT-4 Eastern Time)</span></h3>
          </div>
          <div className="avail-editor">
            {days.map((d, i) => (
              <div key={d.name} className="avail-edit-row">
                <div className="day-toggle">
                  <label className="switch">
                    <input type="checkbox" checked={d.on}
                      onChange={() => setDays(s => s.map((x, j) => j === i ? {...x, on: !x.on} : x))}/>
                    <span className="track"><span className="knob"/></span>
                  </label>
                  <span className="day-name">{d.name}</span>
                </div>
                {d.on ? (
                  <div className="time-pickers">
                    <input className="time-input" type="time" value={d.start}
                      onChange={e => setDays(s => s.map((x, j) => j === i ? {...x, start: e.target.value} : x))}/>
                    <span className="dash">—</span>
                    <input className="time-input" type="time" value={d.end}
                      onChange={e => setDays(s => s.map((x, j) => j === i ? {...x, end: e.target.value} : x))}/>
                    <button className="add-slot"><I.bolt size={11}/> Add slot</button>
                  </div>
                ) : (
                  <span className="unavail-tag">Unavailable</span>
                )}
                <button className="row-actions" title="Duplicate to all"><I.copy size={14}/></button>
              </div>
            ))}
          </div>
        </div>

        <div style={{display:"flex", flexDirection:"column", gap:20}}>
          <div className="card">
            <div className="card-h">
              <h3>Blocked dates</h3>
              <button className="card-link">+ Add</button>
            </div>
            <div className="blocked-list">
              {data.blockedDates.map((b) => (
                <div className="blocked-row" key={b.id}>
                  <div>
                    <div style={{fontWeight:500}}>{formatIsoDate(b.date, { year: true })}</div>
                    <div className="reason">{b.reason}</div>
                  </div>
                  <button className="row-actions" onClick={() => actions.removeBlockedDate(b.id)}><I.more size={14}/></button>
                </div>
              ))}
              <div className="blocked-add">
                <input className="bk-input" type="text" placeholder="YYYY-MM-DD" value={blockDate} onChange={(e) => setBlockDate(e.target.value)}/>
                <input className="bk-input" placeholder="Reason" value={blockReason} onChange={(e) => setBlockReason(e.target.value)}/>
                <button className="btn primary" onClick={() => { if (blockDate) actions.addBlockedDate(blockDate, blockReason || "Blocked"); setBlockReason(""); }}>Add</button>
              </div>
            </div>
          </div>

          <div className="card">
            <div className="card-h">
              <h3>Blocked time slots</h3>
              <span className="sub">Hide specific times on a date</span>
            </div>
            <div className="blocked-list">
              {(data.blockedTimes || []).map((b) => (
                <div className="blocked-row" key={b.id}>
                  <div>
                    <div style={{fontWeight:500}}>{formatIsoDate(b.date, { year: true })} · {b.start} – {b.end}</div>
                    <div className="reason">{b.reason}</div>
                  </div>
                  <button className="row-actions" onClick={() => actions.removeBlockedTime(b.id)}><I.more size={14}/></button>
                </div>
              ))}
              <div className="blocked-add time-exception-add">
                <input className="bk-input" type="text" placeholder="YYYY-MM-DD" value={timeBlock.date} onChange={(e) => setTimeBlock({...timeBlock, date: e.target.value})}/>
                <input className="bk-input" type="time" value={timeBlock.start} onChange={(e) => setTimeBlock({...timeBlock, start: e.target.value})}/>
                <input className="bk-input" type="time" value={timeBlock.end} onChange={(e) => setTimeBlock({...timeBlock, end: e.target.value})}/>
                <input className="bk-input" placeholder="Reason" value={timeBlock.reason} onChange={(e) => setTimeBlock({...timeBlock, reason: e.target.value})}/>
                <button className="btn primary" onClick={() => {
                  if (timeBlock.date && timeBlock.start && timeBlock.end) {
                    actions.addBlockedTime({...timeBlock, reason: timeBlock.reason || "Blocked time"});
                    setTimeBlock({...timeBlock, reason: ""});
                  }
                }}>Add</button>
              </div>
            </div>
          </div>
        </div>
      </div>
    </>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Teams
// ──────────────────────────────────────────────────────────────────────────
// ── Staff color swatches ────────────────────────────────────────
const STAFF_SWATCHES = ["#7aa7ff","#6ee7a3","#f59e9e","#a78bfa","#fbbf24","#34d399","#f472b6","#60a5fa","#fb923c","#818cf8"];

const DEFAULT_STAFF_AVAIL = [
  { day:"Monday",    on:true,  start:"09:00", end:"17:00" },
  { day:"Tuesday",   on:true,  start:"09:00", end:"17:00" },
  { day:"Wednesday", on:true,  start:"09:00", end:"17:00" },
  { day:"Thursday",  on:true,  start:"09:00", end:"17:00" },
  { day:"Friday",    on:true,  start:"09:00", end:"17:00" },
  { day:"Saturday",  on:false, start:"09:00", end:"13:00" },
  { day:"Sunday",    on:false, start:"09:00", end:"13:00" },
];

function StaffModal({ member, events, locations, onSave, onClose }) {
  const isNew = !member?.id;
  const [form, setForm] = React.useState(() => member ? { ...member } : {
    name: "", email: "", bio: "", color: STAFF_SWATCHES[0],
    active: true, serviceIds: [], locationIds: [],
    useCustomAvailability: false,
    customAvailability: DEFAULT_STAFF_AVAIL.map(d => ({ ...d })),
  });
  const [errors, setErrors] = React.useState({});
  const upd = (k, v) => setForm(f => ({ ...f, [k]: v }));

  const toggleService = (id) => {
    setForm(f => {
      const ids = f.serviceIds || [];
      return { ...f, serviceIds: ids.includes(id) ? ids.filter(x => x !== id) : [...ids, id] };
    });
  };

  const toggleLocation = (id) => {
    setForm(f => {
      const ids = f.locationIds || [];
      return { ...f, locationIds: ids.includes(id) ? ids.filter(x => x !== id) : [...ids, id] };
    });
  };

  const updateAvail = (day, patch) => {
    setForm(f => ({
      ...f,
      customAvailability: (f.customAvailability || []).map(d => d.day === day ? { ...d, ...patch } : d),
    }));
  };

  const ensureAvail = (f) => {
    if ((f.customAvailability || []).length > 0) return f.customAvailability;
    return DEFAULT_STAFF_AVAIL.map(d => ({ ...d }));
  };

  const handleSave = () => {
    const errs = {};
    if (!form.name.trim()) errs.name = true;
    setErrors(errs);
    if (Object.keys(errs).length > 0) return;
    const clean = { ...form, name: form.name.trim(), customAvailability: ensureAvail(form) };
    onSave(clean);
  };

  const avail = form.customAvailability && form.customAvailability.length > 0
    ? form.customAvailability : DEFAULT_STAFF_AVAIL;

  const initials = (form.name || "?").split(" ").map(w => w[0]).join("").toUpperCase().slice(0, 2) || "?";

  return (
    <div className="modal-overlay" onClick={e => e.target === e.currentTarget && onClose()}>
      <div className="modal-panel" style={{maxWidth:520}}>
        <div className="modal-head">
          <h3>{isNew ? "Add staff member" : "Edit staff member"}</h3>
          <button className="modal-close" onClick={onClose}><I.x size={14}/></button>
        </div>

        <div className="modal-body">
          {/* Preview */}
          <div style={{display:"flex", alignItems:"center", gap:14, marginBottom:20}}>
            <div className="staff-avatar-lg" style={{background: form.color || "#7aa7ff"}}>{initials}</div>
            <div>
              <div style={{fontWeight:600, color:"var(--text)"}}>{form.name || "New member"}</div>
              {form.email && <div style={{fontSize:12, color:"var(--text-muted)"}}>{form.email}</div>}
            </div>
          </div>

          <div className="bk-form" style={{gap:14}}>
            {/* Name */}
            <div className="bk-field">
              <label>Name <span className="req">*</span></label>
              <input className={"bk-input " + (errors.name ? "invalid" : "")}
                value={form.name} placeholder="e.g. Maya Reyes"
                onChange={e => upd("name", e.target.value)}/>
            </div>
            {/* Email */}
            <div className="bk-field">
              <label>Email <span className="opt">(optional)</span></label>
              <input className="bk-input" type="email" value={form.email}
                placeholder="staff@example.com"
                onChange={e => upd("email", e.target.value)}/>
            </div>
            {/* Bio */}
            <div className="bk-field">
              <label>Bio / role <span className="opt">(optional)</span></label>
              <input className="bk-input" value={form.bio}
                placeholder="e.g. Senior stylist · 5 years experience"
                onChange={e => upd("bio", e.target.value)}/>
            </div>
            {/* Color */}
            <div className="bk-field">
              <label>Colour</label>
              <div style={{display:"flex", gap:8, flexWrap:"wrap"}}>
                {STAFF_SWATCHES.map(c => (
                  <button key={c} type="button"
                    style={{width:26, height:26, borderRadius:"50%", background:c, border: form.color === c ? "3px solid var(--text)" : "3px solid transparent", cursor:"pointer"}}
                    onClick={() => upd("color", c)}/>
                ))}
              </div>
            </div>
            {/* Services */}
            {events.length > 0 && (
              <div className="bk-field">
                <label>Assigned services</label>
                <div style={{display:"flex", flexDirection:"column", gap:6}}>
                  {events.map(ev => (
                    <label key={ev.id} style={{display:"flex", alignItems:"center", gap:8, cursor:"pointer", fontSize:13}}>
                      <input type="checkbox" checked={(form.serviceIds || []).includes(ev.id)}
                        onChange={() => toggleService(ev.id)}/>
                      <span style={{color:"var(--text)"}}>{ev.name}</span>
                      <span style={{color:"var(--text-muted)", fontSize:12}}>{ev.duration} min</span>
                    </label>
                  ))}
                </div>
                {(form.serviceIds || []).length === 0 && (
                  <div style={{fontSize:12, color:"var(--text-muted)", marginTop:4}}>No services selected — this staff member won't appear on the booking page.</div>
                )}
              </div>
            )}

            {/* Locations (Business plan) */}
            {locations && locations.length > 0 && (
              <div className="bk-field">
                <label>Assigned locations</label>
                <div style={{display:"flex", flexDirection:"column", gap:6}}>
                  {locations.map(loc => (
                    <label key={loc.id} style={{display:"flex", alignItems:"center", gap:8, cursor:"pointer", fontSize:13}}>
                      <input type="checkbox" checked={(form.locationIds || []).includes(loc.id)}
                        onChange={() => toggleLocation(loc.id)}/>
                      <span style={{width:10, height:10, borderRadius:"50%", background:loc.color || "#006e78", flexShrink:0, display:"inline-block"}}/>
                      <span style={{color:"var(--text)"}}>{loc.name}</span>
                      {loc.address && <span style={{color:"var(--text-muted)", fontSize:12}}>{loc.address}</span>}
                    </label>
                  ))}
                </div>
                {(form.locationIds || []).length === 0 && (
                  <div style={{fontSize:12, color:"var(--text-muted)", marginTop:4}}>Not assigned to any location.</div>
                )}
              </div>
            )}

            {/* Custom availability */}
            <div className="bk-field">
              <label style={{display:"flex", alignItems:"center", gap:10, cursor:"pointer"}}>
                <input type="checkbox" checked={!!form.useCustomAvailability}
                  onChange={e => upd("useCustomAvailability", e.target.checked)}/>
                Use custom availability schedule
              </label>
              {!form.useCustomAvailability && (
                <div style={{fontSize:12, color:"var(--text-muted)", marginTop:4}}>Will use the global availability schedule.</div>
              )}
            </div>

            {form.useCustomAvailability && (
              <div className="avail-grid" style={{marginTop:0}}>
                {avail.map(d => (
                  <div key={d.day} className={"avail-row " + (d.on ? "is-on" : "")}>
                    <label className="avail-toggle">
                      <input type="checkbox" checked={!!d.on} onChange={e => updateAvail(d.day, { on: e.target.checked })}/>
                      <span className="avail-day">{d.day.slice(0,3)}</span>
                    </label>
                    {d.on ? (
                      <div className="avail-times">
                        <input type="time" className="avail-time-input" value={d.start}
                          onChange={e => updateAvail(d.day, { start: e.target.value })}/>
                        <span style={{color:"var(--text-muted)", fontSize:12}}>to</span>
                        <input type="time" className="avail-time-input" value={d.end}
                          onChange={e => updateAvail(d.day, { end: e.target.value })}/>
                      </div>
                    ) : (
                      <div style={{fontSize:12, color:"var(--text-muted)"}}>Unavailable</div>
                    )}
                  </div>
                ))}
              </div>
            )}
          </div>
        </div>

        <div className="modal-foot">
          <button className="btn ghost" onClick={onClose}>Cancel</button>
          <button className="btn primary" onClick={handleSave}>
            {isNew ? "Add member" : "Save changes"}
          </button>
        </div>
      </div>
    </div>
  );
}

function ViewTeams({ data, actions }) {
  const [editingMember, setEditingMember] = React.useState(null);   // null = closed, {} = new, {...} = editing
  const [confirmDelete, setConfirmDelete] = React.useState(null);   // member to delete

  const staff   = data?.staff || [];
  const events  = data?.events || [];
  const active  = staff.filter(s => s.active);
  const inactive = staff.filter(s => !s.active);

  const limits       = planLimits(data);
  const maxStaff     = limits.maxStaff;
  const atStaffLimit = staff.length >= maxStaff;

  const handleSave = (member) => {
    actions.saveStaff(member);
    setEditingMember(null);
  };

  const handleDelete = (s) => {
    actions.deleteStaff(s.id);
    setConfirmDelete(null);
  };

  // bookings per staff member
  const bookingsForStaff = (id) =>
    (data?.bookings || []).filter(b => b.staffId === id).length;

  const servicesForStaff = (s) =>
    (s.serviceIds || []).map(id => events.find(e => e.id === id)?.name).filter(Boolean);

  const initials = (name) => (name || "?").split(" ").map(w => w[0]).join("").toUpperCase().slice(0, 2);

  return (
    <>
      <div className="view-h">
        <div>
          <h1>Staff</h1>
          <div className="sub">
            {staff.length} member{staff.length !== 1 ? "s" : ""}
            {active.length > 0 ? ` · ${active.length} active` : ""}
            {maxStaff < Infinity ? ` · ${staff.length}/${maxStaff} plan limit` : ""}
          </div>
        </div>
        <div className="view-actions">
          <button className="btn primary"
            onClick={() => !atStaffLimit && setEditingMember({})}
            disabled={atStaffLimit}
            title={atStaffLimit ? `Staff limit reached — upgrade your plan to add more members` : undefined}>
            <I.users size={13}/> Add member
            {atStaffLimit && <span style={{marginLeft:6, fontSize:11, opacity:0.75}}>({maxStaff} max)</span>}
          </button>
        </div>
      </div>
      {atStaffLimit && maxStaff < Infinity && (
        <div style={{marginBottom:16}}>
          <PlanGate
            feature={maxStaff === 1 ? "Multiple staff members" : `More than ${maxStaff} staff members`}
            requiredPlan={maxStaff === 1 ? "Professional" : "Business"}/>
        </div>
      )}

      {staff.length === 0 ? (
        <div className="empty-state">
          <I.users size={32}/>
          <h3>No staff members yet</h3>
          <p>Add your first team member to enable staff routing on your booking page.</p>
          <button className="btn primary" onClick={() => !atStaffLimit && setEditingMember({})} disabled={atStaffLimit}>
            Add staff member
          </button>
        </div>
      ) : (
        <>
          <div className="staff-manage-grid">
            {staff.map(s => (
              <div key={s.id} className={"staff-manage-card " + (s.active ? "" : "is-inactive")}>
                <div className="staff-manage-top">
                  <div className="staff-avatar-lg" style={{background: s.color || "#7aa7ff"}}>
                    {s.photoUrl ? <img src={s.photoUrl} alt={s.name}/> : initials(s.name)}
                  </div>
                  <div className="staff-manage-meta">
                    <div className="staff-manage-name">{s.name}</div>
                    {s.bio && <div className="staff-manage-bio">{s.bio}</div>}
                    {s.email && <div className="staff-manage-email">{s.email}</div>}
                  </div>
                  <label className="toggle-switch" title={s.active ? "Active" : "Inactive"}>
                    <input type="checkbox" checked={!!s.active}
                      onChange={() => actions.toggleStaff(s.id)}/>
                    <span className="toggle-track"/>
                  </label>
                </div>

                {(s.serviceIds || []).length > 0 && (
                  <div className="staff-manage-services">
                    {servicesForStaff(s).map((name, i) => (
                      <span key={i} className="staff-service-chip">{name}</span>
                    ))}
                  </div>
                )}

                <div className="staff-manage-stats">
                  <div className="staff-stat">
                    <span className="staff-stat-num">{bookingsForStaff(s.id)}</span>
                    <span className="staff-stat-lbl">Bookings</span>
                  </div>
                  <div className="staff-stat">
                    <span className="staff-stat-num">{(s.serviceIds || []).length}</span>
                    <span className="staff-stat-lbl">Services</span>
                  </div>
                  <div className="staff-stat">
                    <span className="staff-stat-num">{s.useCustomAvailability ? "Custom" : "Global"}</span>
                    <span className="staff-stat-lbl">Schedule</span>
                  </div>
                </div>

                <div className="staff-manage-actions">
                  <button className="btn ghost" style={{flex:1}} onClick={() => setEditingMember(s)}>Edit</button>
                  <button className="btn ghost" style={{flex:1, color:"var(--danger, #ef4444)"}}
                    onClick={() => setConfirmDelete(s)}>Remove</button>
                </div>
              </div>
            ))}
            <button className="add-card" onClick={() => setEditingMember({})}>
              <span className="plus"><I.users size={16}/></span>
              Add member
            </button>
          </div>

          {inactive.length > 0 && (
            <div style={{marginTop:8, fontSize:12, color:"var(--text-muted)"}}>
              {inactive.length} inactive member{inactive.length !== 1 ? "s" : ""} hidden from the booking page.
            </div>
          )}
        </>
      )}

      {editingMember !== null && (
        <StaffModal
          member={editingMember.id ? editingMember : null}
          events={events}
          locations={limits.multiLocation ? (data?.locations || []) : []}
          onSave={handleSave}
          onClose={() => setEditingMember(null)}/>
      )}

      {confirmDelete && (
        <div className="modal-overlay" onClick={e => e.target === e.currentTarget && setConfirmDelete(null)}>
          <div className="modal-panel" style={{maxWidth:380}}>
            <div className="modal-head"><h3>Remove {confirmDelete.name}?</h3></div>
            <div className="modal-body">
              <p style={{color:"var(--text-muted)", fontSize:14}}>This will remove them from all services and the booking page. Their past bookings won't be affected.</p>
            </div>
            <div className="modal-foot">
              <button className="btn ghost" onClick={() => setConfirmDelete(null)}>Cancel</button>
              <button className="btn primary" style={{background:"var(--danger, #ef4444)"}}
                onClick={() => handleDelete(confirmDelete)}>Remove member</button>
            </div>
          </div>
        </div>
      )}
    </>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Integrations
// ──────────────────────────────────────────────────────────────────────────
// ── Payment credential form (Stripe / PayPal) ────────────────
function PaymentCredentialForm({ provider, logoEl, logoBg, fields, connected, maskedKey, onSave, onDisconnect }) {
  const [open, setOpen]   = React.useState(false);
  const [vals, setVals]   = React.useState({});
  const [saving, setSaving] = React.useState(false);
  const [err, setErr]     = React.useState("");

  const upd = (k, v) => setVals(f => ({ ...f, [k]: v }));

  const handleSave = async () => {
    for (const f of fields) {
      if (!vals[f.key]?.trim()) { setErr(`${f.label} is required`); return; }
    }
    setErr(""); setSaving(true);
    await onSave(vals);
    setSaving(false);
    setOpen(false);
    setVals({});
  };

  return (
    <div className="intg-card payment-intg-card">
      <div className="intg-card-h">
        <div className="intg-logo">{logoEl}</div>
        <div>
          <div className="name">{provider}</div>
          {connected && <div style={{fontSize:11, color:"var(--accent)", fontWeight:600, marginTop:2}}>● Connected</div>}
        </div>
      </div>

      {connected ? (
        <>
          <div style={{fontSize:12, color:"var(--text-muted)", margin:"8px 0"}}>
            Key: <code style={{background:"var(--surface-3)", padding:"2px 6px", borderRadius:4, fontSize:11}}>{maskedKey}</code>
          </div>
          <div className="actions">
            <button className="btn primary" style={{fontSize:12, padding:"5px 10px"}} onClick={() => { setOpen(o => !o); setVals({}); }}>Update keys</button>
            <button className="btn disconnect" style={{fontSize:12, padding:"5px 10px"}} onClick={onDisconnect}>Disconnect</button>
          </div>
        </>
      ) : (
        <div className="actions">
          <span style={{fontSize:12, color:"var(--text-muted)"}}>Not connected</span>
          <button className="btn primary" style={{fontSize:12, padding:"5px 12px"}} onClick={() => setOpen(o => !o)}>
            {open ? "Cancel" : "Connect"}
          </button>
        </div>
      )}

      {open && (
        <div className="payment-cred-form">
          {fields.map(f => (
            <div key={f.key} className="bk-field" style={{marginBottom:10}}>
              <label style={{fontSize:12}}>{f.label}</label>
              <input
                className="bk-input"
                style={{fontSize:12, fontFamily:"monospace"}}
                type={f.secret ? "password" : "text"}
                placeholder={f.placeholder}
                value={vals[f.key] || ""}
                onChange={e => upd(f.key, e.target.value)}
                autoComplete="off"
              />
            </div>
          ))}
          {err && <div style={{fontSize:12, color:"var(--danger, #ef4444)", marginBottom:8}}>{err}</div>}
          <button className="btn primary" style={{width:"100%", fontSize:13}} onClick={handleSave} disabled={saving}>
            {saving ? "Saving…" : "Save & connect"}
          </button>
        </div>
      )}
    </div>
  );
}

function TwilioCredentialForm({ connected, phone, onSave, onDisconnect }) {
  const [open, setOpen]           = React.useState(false);
  const [accountSid, setAccountSid] = React.useState("");
  const [authToken, setAuthToken] = React.useState("");
  const [fromNumber, setFromNumber] = React.useState("");
  const [saving, setSaving]       = React.useState(false);

  const handleSave = async () => {
    if (!accountSid.trim() || !authToken.trim() || !fromNumber.trim()) return;
    setSaving(true);
    await onSave({ accountSid: accountSid.trim(), authToken: authToken.trim(), fromNumber: fromNumber.trim() });
    setSaving(false);
    setOpen(false);
    setAccountSid(""); setAuthToken(""); setFromNumber("");
  };

  return (
    <div className="intg-card payment-intg-card">
      <div className="intg-card-h">
        <div className="intg-logo" style={{flexShrink:0}}>{Bl.twilio}</div>
        <div style={{flex:1,minWidth:0}}>
          <div className="name">Twilio</div>
          {connected && phone && (
            <div style={{fontSize:12,color:"var(--text-muted)",marginTop:2}}>{phone}</div>
          )}
        </div>
        {connected && <span style={{fontSize:11,fontWeight:600,color:"#22c55e",background:"rgba(34,197,94,.12)",borderRadius:6,padding:"3px 8px",whiteSpace:"nowrap"}}>Connected</span>}
      </div>
      <div className="desc" style={{margin:"12px 0 16px"}}>
        Send SMS booking confirmations and reminders directly to guests. Requires your own Twilio account.
      </div>
      {connected ? (
        <button className="btn disconnect" style={{fontSize:13}} onClick={onDisconnect}>Disconnect</button>
      ) : !open ? (
        <button className="btn primary" style={{fontSize:13}} onClick={() => setOpen(true)}>Connect Twilio</button>
      ) : (
        <div style={{display:"flex",flexDirection:"column",gap:10}}>
          <div className="bk-field" style={{margin:0}}>
            <label style={{fontSize:12}}>Account SID</label>
            <input className="bk-input" style={{fontSize:13}} placeholder="ACxxxxxxxxxxxxxxxx"
              value={accountSid} onChange={e => setAccountSid(e.target.value)}/>
          </div>
          <div className="bk-field" style={{margin:0}}>
            <label style={{fontSize:12}}>Auth token</label>
            <input className="bk-input" style={{fontSize:13}} type="password" placeholder="••••••••"
              value={authToken} onChange={e => setAuthToken(e.target.value)}/>
          </div>
          <div className="bk-field" style={{margin:0}}>
            <label style={{fontSize:12}}>From number <span style={{color:"var(--text-muted)",fontWeight:400}}>(e.g. +441234567890)</span></label>
            <input className="bk-input" style={{fontSize:13}} placeholder="+44…"
              value={fromNumber} onChange={e => setFromNumber(e.target.value)}/>
          </div>
          <div style={{display:"flex",gap:8,marginTop:4}}>
            <button className="btn ghost" style={{fontSize:13}} onClick={() => setOpen(false)}>Cancel</button>
            <button className="btn primary" style={{fontSize:13,flex:1}} onClick={handleSave} disabled={saving || !accountSid || !authToken || !fromNumber}>
              {saving ? "Saving…" : "Save & connect"}
            </button>
          </div>
        </div>
      )}
    </div>
  );
}

function AppleCalendarCredentialForm({ connected, email, onSave, onDisconnect }) {
  const [open, setOpen]       = React.useState(false);
  const [appleId, setAppleId] = React.useState("");
  const [appPass, setAppPass] = React.useState("");
  const [saving, setSaving]   = React.useState(false);
  const [err, setErr]         = React.useState("");

  const handleSave = async () => {
    if (!appleId.trim() || !appPass.trim()) { setErr("Both fields are required."); return; }
    setErr(""); setSaving(true);
    await onSave(appleId.trim(), appPass.trim());
    setSaving(false);
    setOpen(false);
    setAppleId(""); setAppPass("");
  };

  return (
    <div className="intg-card payment-intg-card">
      <div className="intg-card-h">
        <div className="intg-logo" style={{flexShrink:0}}>{Bl.apple}</div>
        <div style={{flex:1,minWidth:0}}>
          <div className="name">Apple Calendar</div>
          {connected && email && (
            <div style={{fontSize:12,color:"var(--text-muted)",marginTop:2,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}>{email}</div>
          )}
        </div>
        {connected && <span style={{fontSize:11,fontWeight:600,color:"#22c55e",background:"rgba(34,197,94,.12)",borderRadius:6,padding:"3px 8px",whiteSpace:"nowrap"}}>Connected</span>}
      </div>
      <div className="desc" style={{margin:"12px 0 16px"}}>
        Sync bookings to your iCloud calendar both ways via CalDAV. Requires your Apple ID and an app-specific password generated at <strong>appleid.apple.com</strong>.
      </div>
      {connected ? (
        <button className="btn disconnect" style={{fontSize:13}} onClick={onDisconnect}>Disconnect</button>
      ) : !open ? (
        <button className="btn primary" style={{fontSize:13}} onClick={() => setOpen(true)}>Connect Apple Calendar</button>
      ) : (
        <div style={{display:"flex",flexDirection:"column",gap:10}}>
          <div className="bk-field" style={{margin:0}}>
            <label style={{fontSize:12}}>Apple ID (email)</label>
            <input className="bk-input" style={{fontSize:13}} placeholder="you@icloud.com"
              type="email" value={appleId} onChange={e => setAppleId(e.target.value)} autoComplete="off"/>
          </div>
          <div className="bk-field" style={{margin:0}}>
            <label style={{fontSize:12}}>App-specific password <span style={{color:"var(--text-muted)",fontWeight:400}}>— generated at appleid.apple.com</span></label>
            <input className="bk-input" style={{fontSize:13,fontFamily:"monospace"}} type="password" placeholder="xxxx-xxxx-xxxx-xxxx"
              value={appPass} onChange={e => setAppPass(e.target.value)} autoComplete="off"/>
          </div>
          {err && <div style={{fontSize:12,color:"var(--danger,#ef4444)"}}>{err}</div>}
          <div style={{display:"flex",gap:8,marginTop:4}}>
            <button className="btn ghost" style={{fontSize:13}} onClick={() => { setOpen(false); setErr(""); }}>Cancel</button>
            <button className="btn primary" style={{fontSize:13,flex:1}} onClick={handleSave} disabled={saving || !appleId || !appPass}>
              {saving ? "Saving…" : "Save & connect"}
            </button>
          </div>
        </div>
      )}
    </div>
  );
}

function WhatsAppCredentialForm({ connected, phone, onSave, onDisconnect }) {
  const [open, setOpen]       = React.useState(false);
  const [number, setNumber]   = React.useState("");
  const [saving, setSaving]   = React.useState(false);

  const handleSave = async () => {
    if (!number.trim()) return;
    setSaving(true);
    await onSave(number.trim());
    setSaving(false);
    setOpen(false);
    setNumber("");
  };

  return (
    <div className="intg-card payment-intg-card">
      <div className="intg-card-h">
        <div className="intg-logo" style={{flexShrink:0}}>{Bl.whatsapp}</div>
        <div style={{flex:1,minWidth:0}}>
          <div className="name">WhatsApp Business</div>
          {connected && phone && (
            <div style={{fontSize:12,color:"var(--text-muted)",marginTop:2}}>{phone}</div>
          )}
        </div>
        {connected && <span style={{fontSize:11,fontWeight:600,color:"#22c55e",background:"rgba(34,197,94,.12)",borderRadius:6,padding:"3px 8px",whiteSpace:"nowrap"}}>Connected</span>}
      </div>
      <div className="desc" style={{margin:"12px 0 16px"}}>
        Send booking confirmations and reminders directly to guests via WhatsApp. Requires a WhatsApp Business account.
      </div>
      {connected ? (
        <button className="btn disconnect" style={{fontSize:13}} onClick={onDisconnect}>Disconnect</button>
      ) : !open ? (
        <button className="btn primary" style={{fontSize:13}} onClick={() => setOpen(true)}>Connect WhatsApp</button>
      ) : (
        <div style={{display:"flex",flexDirection:"column",gap:10}}>
          <div className="bk-field" style={{margin:0}}>
            <label style={{fontSize:12}}>WhatsApp Business phone number <span style={{color:"var(--text-muted)",fontWeight:400}}>(e.g. +441234567890)</span></label>
            <input className="bk-input" style={{fontSize:13}} placeholder="+44…"
              value={number} onChange={e => setNumber(e.target.value)}/>
          </div>
          <div style={{display:"flex",gap:8,marginTop:4}}>
            <button className="btn ghost" style={{fontSize:13}} onClick={() => setOpen(false)}>Cancel</button>
            <button className="btn primary" style={{fontSize:13,flex:1}} onClick={handleSave} disabled={saving || !number}>
              {saving ? "Saving…" : "Save & connect"}
            </button>
          </div>
        </div>
      )}
    </div>
  );
}

function ZoomCredentialForm({ connected, onSave, onDisconnect }) {
  const [open,   setOpen]   = React.useState(false);
  const [saving, setSaving] = React.useState(false);
  const [vals,   setVals]   = React.useState({ accountId: "", clientId: "", clientSecret: "" });
  const set = (k) => (e) => setVals(v => ({ ...v, [k]: e.target.value }));
  return (
    <div className="intg-card payment-intg-card">
      <div className="intg-card-h">
        <div className="intg-logo" style={{flexShrink:0}}>{Bl.zoom}</div>
        <div style={{flex:1,minWidth:0}}><div className="name">Zoom</div></div>
        {connected && <span style={{fontSize:11,fontWeight:600,color:"#22c55e",background:"rgba(34,197,94,.12)",borderRadius:6,padding:"3px 8px",whiteSpace:"nowrap"}}>Connected</span>}
      </div>
      <div className="desc" style={{margin:"12px 0 16px"}}>
        Automatically creates a Zoom meeting when a video booking is made and saves the join link.
      </div>
      {connected ? (
        <button className="btn disconnect" style={{fontSize:13}} onClick={onDisconnect}>Disconnect</button>
) : open ? (
        <>
          {[
            { k:"accountId",    label:"Account ID",    ph:"your_account_id" },
            { k:"clientId",     label:"Client ID",     ph:"your_client_id"  },
            { k:"clientSecret", label:"Client Secret", ph:"your_client_secret", secret:true },
          ].map(({k,label,ph,secret}) => (
            <div key={k} style={{marginBottom:10}}>
              <div style={{fontSize:12,color:"var(--text-muted)",marginBottom:4}}>{label}</div>
              <input
                type={secret ? "password" : "text"}
                className="field"
                placeholder={ph}
                value={vals[k]}
                onChange={set(k)}
                style={{width:"100%",boxSizing:"border-box"}}
              />
            </div>
          ))}
          <div style={{display:"flex",gap:8,marginTop:4}}>
            <button className="btn ghost" style={{fontSize:13}} onClick={() => setOpen(false)}>Cancel</button>
            <button
              className="btn primary"
              style={{fontSize:13}}
              disabled={saving || !vals.accountId || !vals.clientId || !vals.clientSecret}
              onClick={async () => {
                setSaving(true);
                await onSave(vals.accountId, vals.clientId, vals.clientSecret);
                setSaving(false);
                setOpen(false);
              }}
            >
              {saving ? "Saving…" : "Save & connect"}
            </button>
          </div>
        </>
      ) : (
        <button className="btn primary" style={{fontSize:13}} onClick={() => setOpen(true)}>Connect Zoom</button>
      )}
    </div>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Locations (Business plan)
// ──────────────────────────────────────────────────────────────────────────

const LOC_SWATCHES = ["#006e78","#7aa7ff","#f59e9e","#a78bfa","#6ee7a3","#fbbf24","#ef4444","#64748b"];

function LocationForm({ loc, staff, onSave, onClose }) {
  const isNew = !loc.id;
  const [form, setForm] = React.useState({
    name: "", address: "", phone: "", email: "", color: "#006e78", ...loc,
  });
  const [errors, setErrors] = React.useState({});
  const upd = (k, v) => setForm(f => ({ ...f, [k]: v }));

  const handleSave = () => {
    const errs = {};
    if (!form.name.trim()) errs.name = true;
    setErrors(errs);
    if (Object.keys(errs).length > 0) return;
    onSave({ ...form, name: form.name.trim() });
  };

  return (
    <div className="modal-overlay" onClick={e => e.target === e.currentTarget && onClose()}>
      <div className="modal-panel" style={{maxWidth:480}}>
        <div className="modal-head">
          <h3>{isNew ? "Add location" : "Edit location"}</h3>
          <button className="modal-close" onClick={onClose}><I.x size={14}/></button>
        </div>
        <div className="modal-body">
          {/* Colour preview dot */}
          <div style={{display:"flex", alignItems:"center", gap:12, marginBottom:20}}>
            <div style={{width:42, height:42, borderRadius:"50%", background:form.color || "#006e78", display:"flex", alignItems:"center", justifyContent:"center"}}>
              <I.location size={18} style={{color:"#fff"}}/>
            </div>
            <div style={{fontWeight:600, color:"var(--text)", fontSize:15}}>{form.name || "New location"}</div>
          </div>
          <div className="bk-form" style={{gap:14}}>
            <div className="bk-field">
              <label>Location name <span className="req">*</span></label>
              <input className={"bk-input " + (errors.name ? "invalid" : "")}
                value={form.name} placeholder="e.g. Main Studio"
                onChange={e => upd("name", e.target.value)}/>
            </div>
            <div className="bk-field">
              <label>Address</label>
              <input className="bk-input" value={form.address} placeholder="e.g. 12 High Street, London, EC1A 1BB"
                onChange={e => upd("address", e.target.value)}/>
            </div>
            <div style={{display:"grid", gridTemplateColumns:"1fr 1fr", gap:12}}>
              <div className="bk-field">
                <label>Phone <span className="opt">(optional)</span></label>
                <input className="bk-input" value={form.phone} placeholder="+44 20 1234 5678"
                  onChange={e => upd("phone", e.target.value)}/>
              </div>
              <div className="bk-field">
                <label>Email <span className="opt">(optional)</span></label>
                <input className="bk-input" type="email" value={form.email} placeholder="location@example.com"
                  onChange={e => upd("email", e.target.value)}/>
              </div>
            </div>
            <div className="bk-field">
              <label>Colour</label>
              <div style={{display:"flex", gap:8, flexWrap:"wrap"}}>
                {LOC_SWATCHES.map(c => (
                  <button key={c} type="button"
                    style={{width:26, height:26, borderRadius:"50%", background:c, border: form.color === c ? "3px solid var(--text)" : "3px solid transparent", cursor:"pointer"}}
                    onClick={() => upd("color", c)}/>
                ))}
              </div>
            </div>
          </div>
        </div>
        <div className="modal-foot">
          <button className="btn ghost" onClick={onClose}>Cancel</button>
          <button className="btn primary" onClick={handleSave}>{isNew ? "Add location" : "Save changes"}</button>
        </div>
      </div>
    </div>
  );
}

function ViewLocations({ data, actions }) {
  const [editing, setEditing]     = React.useState(null);   // null=closed, {}=new, {...}=editing
  const [confirmDel, setConfirmDel] = React.useState(null); // location to delete
  const limits    = planLimits(data);
  const locations = data?.locations || [];
  const staff     = data?.staff || [];

  if (!limits.multiLocation) {
    return (
      <>
        <div className="view-h">
          <div>
            <h1>Locations</h1>
            <div className="sub">Manage multiple business locations and assign staff to each.</div>
          </div>
        </div>
        <PlanGate feature="Multiple locations" requiredPlan="Business"/>
      </>
    );
  }

  const staffForLocation = (locId) =>
    staff.filter(s => (s.locationIds || []).includes(locId));

  const handleSave = (loc) => {
    actions.saveLocation(loc);
    setEditing(null);
  };

  const handleDelete = (loc) => {
    actions.deleteLocation(loc.id);
    setConfirmDel(null);
  };

  return (
    <>
      <div className="view-h">
        <div>
          <h1>Locations</h1>
          <div className="sub">{locations.length} location{locations.length !== 1 ? "s" : ""} · Assign staff to each branch from the Teams view</div>
        </div>
        <div className="view-actions">
          <button className="btn primary" onClick={() => setEditing({})}>
            <I.plus size={13}/> Add location
          </button>
        </div>
      </div>

      {locations.length === 0 ? (
        <div className="placeholder">
          <div className="placeholder-inner">
            <div className="placeholder-icon"><I.location size={20}/></div>
            <h3>No locations yet</h3>
            <p>Add your first location to manage multiple branches, assign staff, and route bookings.</p>
            <button className="btn primary" onClick={() => setEditing({})}>
              <I.plus size={13}/> Add location
            </button>
          </div>
        </div>
      ) : (
        <div className="staff-manage-grid">
          {locations.map(loc => {
            const assigned = staffForLocation(loc.id);
            return (
              <div key={loc.id} className="staff-manage-card">
                <div className="staff-manage-top">
                  <div className="staff-avatar-lg" style={{background: loc.color || "#006e78"}}>
                    <I.location size={18} style={{color:"#fff"}}/>
                  </div>
                  <div className="staff-manage-meta">
                    <div className="staff-manage-name">{loc.name}</div>
                    {loc.address && <div className="staff-manage-bio">{loc.address}</div>}
                    {loc.phone   && <div className="staff-manage-email">{loc.phone}</div>}
                  </div>
                </div>
                {assigned.length > 0 && (
                  <div className="staff-manage-services" style={{marginTop:10}}>
                    {assigned.map(s => (
                      <span key={s.id} className="staff-service-chip">{s.name}</span>
                    ))}
                  </div>
                )}
                {assigned.length === 0 && (
                  <div style={{fontSize:12, color:"var(--text-muted)", marginTop:10}}>No staff assigned — go to Teams to assign staff to this location.</div>
                )}
                <div className="staff-manage-stats" style={{marginTop:12}}>
                  <div className="staff-stat">
                    <span className="staff-stat-num">{assigned.length}</span>
                    <span className="staff-stat-lbl">Staff</span>
                  </div>
                  {loc.email && (
                    <div className="staff-stat" style={{flex:2, textAlign:"left"}}>
                      <span className="staff-stat-num" style={{fontSize:12}}>{loc.email}</span>
                      <span className="staff-stat-lbl">Email</span>
                    </div>
                  )}
                </div>
                <div className="staff-manage-actions">
                  <button className="btn ghost sm" onClick={() => setEditing(loc)}>Edit</button>
                  <button className="btn ghost sm" style={{color:"var(--danger)"}} onClick={() => setConfirmDel(loc)}>Remove</button>
                </div>
              </div>
            );
          })}
        </div>
      )}

      {editing !== null && (
        <LocationForm
          loc={editing}
          staff={staff}
          onSave={handleSave}
          onClose={() => setEditing(null)}
        />
      )}

      {confirmDel && (
        <div className="modal-overlay" onClick={e => e.target === e.currentTarget && setConfirmDel(null)}>
          <div className="modal-panel" style={{maxWidth:380}}>
            <div className="modal-head">
              <h3>Remove location</h3>
              <button className="modal-close" onClick={() => setConfirmDel(null)}><I.x size={14}/></button>
            </div>
            <div className="modal-body">
              <p style={{margin:0, color:"var(--text-muted)", fontSize:14, lineHeight:1.6}}>
                Are you sure you want to remove <strong style={{color:"var(--text)"}}>{confirmDel.name}</strong>? This will also unassign any staff from this location.
              </p>
            </div>
            <div className="modal-foot">
              <button className="btn ghost" onClick={() => setConfirmDel(null)}>Cancel</button>
              <button className="btn danger" onClick={() => handleDelete(confirmDel)}>Remove location</button>
            </div>
          </div>
        </div>
      )}
    </>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Reserve with Google integration card
// ──────────────────────────────────────────────────────────────────────────
function ReserveWithGoogleCard({ data, actions }) {
  const profile = data.profile || {};
  const isConnected = !!(profile.reserveWithGoogle?.enabled);
  const [saving, setSaving] = React.useState(false);
  const [saved, setSaved]   = React.useState(false);

  const handleToggle = async () => {
    setSaving(true);
    const next = !isConnected;
    await actions.saveSettings({ reserveWithGoogle: { enabled: next } });
    setSaved(true);
    setSaving(false);
    setTimeout(() => setSaved(false), 2000);
  };

  return (
    <div className="intg-card payment-intg-card" style={{gridColumn: "1 / -1"}}>
      <div className="intg-card-h">
        <div className="intg-logo" style={{flexShrink:0, background:"#fff", border:"1px solid var(--border)", display:"flex", alignItems:"center", justifyContent:"center", gap:2, padding:"0 6px"}}>
          <span style={{fontWeight:800, fontSize:13, color:"#4285F4"}}>G</span>
          <span style={{fontWeight:800, fontSize:11, color:"#34A853"}}>o</span>
          <span style={{fontWeight:800, fontSize:11, color:"#FBBC05"}}>o</span>
          <span style={{fontWeight:800, fontSize:11, color:"#EA4335"}}>g</span>
          <span style={{fontWeight:800, fontSize:11, color:"#4285F4"}}>l</span>
          <span style={{fontWeight:800, fontSize:11, color:"#34A853"}}>e</span>
        </div>
        <div style={{flex:1, minWidth:0}}>
          <div className="name">Reserve with Google</div>
          <div style={{fontSize:12, color:"var(--text-muted)", marginTop:2}}>Show a "Book" button directly in Google Search &amp; Maps results</div>
        </div>
        {isConnected && (
          <span className="pill confirmed" style={{fontSize:11}}>Enabled</span>
        )}
      </div>

      <div style={{marginTop:14, fontSize:13, color:"var(--text-muted)", lineHeight:1.65}}>
        Reserve with Google puts a <strong style={{color:"var(--text)"}}>Book online</strong> button on your Google Business Profile — so anyone searching for your business on Google or Maps can book instantly without leaving Google. It's one of the highest-impact discovery channels for local service businesses.
      </div>

      <div style={{marginTop:14, padding:"12px 16px", background:"var(--surface-2)", borderRadius:8, border:"1px solid var(--border)"}}>
        <div style={{fontWeight:600, fontSize:13, marginBottom:8}}>How to get started</div>
        <ol style={{margin:0, paddingLeft:18, fontSize:13, color:"var(--text-muted)", lineHeight:1.8}}>
          <li>Make sure your <strong style={{color:"var(--text)"}}>Google Business Profile</strong> is verified and up to date.</li>
          <li>Apply for Reserve with Google via <a href="https://reserve.google.com/business" target="_blank" rel="noopener noreferrer" style={{color:"var(--accent)"}}>reserve.google.com/business</a>.</li>
          <li>Once approved, Google will contact you with setup instructions. Your Nexus booking link will be used as the booking URL.</li>
          <li>Toggle this on once your Google Business listing is live with the booking button.</li>
        </ol>
      </div>

      <div style={{marginTop:14, display:"flex", alignItems:"center", gap:12}}>
        <label className="switch" style={{flexShrink:0}}>
          <input type="checkbox" checked={isConnected} onChange={handleToggle} disabled={saving}/>
          <span className="track"><span className="knob"/></span>
        </label>
        <div style={{fontSize:13, color:"var(--text-muted)"}}>
          {isConnected
            ? "Marked as active — your booking link is live on Google."
            : "Toggle on once your Reserve with Google listing is approved and live."}
        </div>
        {saved && <span style={{fontSize:12, color:"#16a34a"}}><I.check size={12}/> Saved</span>}
      </div>
    </div>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Win-back automation card
// ──────────────────────────────────────────────────────────────────────────
function WinBackCard({ data, actions }) {
  const profile  = data.profile || {};
  const saved    = profile.winback || {};

  const [enabled,   setEnabled]   = React.useState(!!(saved.enabled));
  const [days,      setDays]      = React.useState(saved.days      || 60);
  const [subject,   setSubject]   = React.useState(saved.subject   || "We miss you, {name} 👋");
  const [body,      setBody]      = React.useState(saved.body      || "Hi {name},\n\nIt's been a while since your last visit with us! We'd love to see you again.\n\nBook your next appointment here: {bookingLink}\n\nTalk soon,\n{businessName}");
  const [saving,    setSaving]    = React.useState(false);
  const [savedOk,   setSavedOk]   = React.useState(false);

  const handleSave = async () => {
    setSaving(true);
    await actions.saveSettings({ winback: { enabled, days: Number(days), subject, body } });
    setSavedOk(true);
    setSaving(false);
    setTimeout(() => setSavedOk(false), 2000);
  };

  const TOKENS = ["{name}", "{businessName}", "{bookingLink}"];

  return (
    <div className="card" style={{padding:"20px 24px"}}>
      <div style={{display:"flex", alignItems:"flex-start", gap:14, marginBottom:16}}>
        <div style={{
          width:40, height:40, borderRadius:10, flexShrink:0,
          background:"linear-gradient(135deg,#7aa7ff,#a78bfa)",
          display:"flex", alignItems:"center", justifyContent:"center",
        }}>
          <I.mail size={18} style={{color:"#fff"}}/>
        </div>
        <div style={{flex:1}}>
          <div style={{fontWeight:600, fontSize:15}}>Win-back emails</div>
          <div style={{fontSize:13, color:"var(--text-muted)", marginTop:2}}>Automatically email clients who haven't booked in a while — bring them back without any manual effort.</div>
        </div>
        <label className="switch" style={{flexShrink:0, marginTop:4}}>
          <input type="checkbox" checked={enabled} onChange={() => setEnabled(e => !e)}/>
          <span className="track"><span className="knob"/></span>
        </label>
      </div>

      {/* Config */}
      <div style={{display: enabled ? "block" : "none"}}>
        <div className="field-grid" style={{marginBottom:16}}>
          <div className="bk-field">
            <label>Send after</label>
            <select className="bk-input" value={days} onChange={(e) => setDays(e.target.value)}>
              <option value="30">30 days without a booking</option>
              <option value="45">45 days without a booking</option>
              <option value="60">60 days without a booking</option>
              <option value="90">90 days without a booking</option>
              <option value="120">120 days without a booking</option>
            </select>
          </div>
          <div className="bk-field">
            <label>Email subject</label>
            <input className="bk-input" value={subject} onChange={(e) => setSubject(e.target.value)} placeholder="We miss you, {name} 👋"/>
          </div>
          <div className="bk-field" style={{gridColumn:"1 / -1"}}>
            <label>Email body</label>
            <textarea className="bk-textarea" rows={7} value={body} onChange={(e) => setBody(e.target.value)}/>
          </div>
        </div>

        {/* Token hints */}
        <div style={{marginBottom:16}}>
          <div style={{fontSize:12, color:"var(--text-muted)", marginBottom:6}}>Available placeholders:</div>
          <div style={{display:"flex", gap:6, flexWrap:"wrap"}}>
            {TOKENS.map((t) => (
              <button key={t} className="btn ghost" style={{fontSize:11, padding:"2px 8px", fontFamily:"monospace"}}
                onClick={() => setBody(b => b + t)}>
                {t}
              </button>
            ))}
          </div>
        </div>

        {/* Preview */}
        <div style={{background:"var(--surface-2)", border:"1px solid var(--border)", borderRadius:8, padding:"12px 16px", marginBottom:16}}>
          <div style={{fontSize:11, fontWeight:600, textTransform:"uppercase", letterSpacing:"0.05em", color:"var(--text-muted)", marginBottom:6}}>Preview</div>
          <div style={{fontSize:13, fontWeight:600, marginBottom:4}}>{subject.replace("{name}", "Sarah").replace("{businessName}", profile.brandName || "Your Business")}</div>
          <div style={{fontSize:12, color:"var(--text-muted)", whiteSpace:"pre-wrap", lineHeight:1.6}}>
            {body
              .replace(/{name}/g, "Sarah")
              .replace(/{businessName}/g, profile.brandName || "Your Business")
              .replace(/{bookingLink}/g, getBookingUrl(profile.bookingUrl || ""))}
          </div>
        </div>
      </div>

      <div style={{display:"flex", alignItems:"center", justifyContent:"flex-end", gap:10}}>
        {savedOk && <span style={{fontSize:12, color:"#16a34a"}}><I.check size={12}/> Saved</span>}
        <button className="btn primary" onClick={handleSave} disabled={saving}>
          {saving ? "Saving…" : "Save settings"}
        </button>
      </div>
    </div>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Integrations
// ──────────────────────────────────────────────────────────────────────────
function ViewIntegrations({ data, actions }) {
  const intg = data.integrations || {};
  const stripeConnected = intg.Stripe?.connected;
  const paypalConnected = intg.PayPal?.connected;
  const gcalConnected   = intg["Google Calendar"]?.connected;
  const gcalEmail       = intg["Google Calendar"]?.email || "";
  const teamsConnected  = intg["Microsoft Teams"]?.connected;
  const zoomConnected   = intg["Zoom"]?.connected;

  const [gcalLoading,   setGcalLoading]   = React.useState(false);
  const [teamsLoading,  setTeamsLoading]  = React.useState(false);

  const limits = planLimits(data);


  const maskKey = (key) => {
    if (!key || key.length < 8) return "••••••••";
    return key.slice(0, 7) + "•".repeat(Math.min(key.length - 7, 12));
  };

  return (
    <>
      <div className="view-h">
        <div>
          <h1>Integrations</h1>
          <div className="sub">Connect the tools you use to power your business.</div>
        </div>
      </div>

      <h3 className="intg-section-h">Payments</h3>
      <div className="intg-grid" style={{marginBottom:32}}>
        <PaymentCredentialForm
          provider="Stripe"
          logoEl={Bl.stripe}
          connected={stripeConnected}
          maskedKey={maskKey(intg.Stripe?.publishableKey)}
          fields={[
            { key: "publishableKey", label: "Publishable key", placeholder: "pk_live_…", secret: false },
            { key: "secretKey",      label: "Secret key",      placeholder: "sk_live_…", secret: true  },
          ]}
          onSave={async (vals) => {
            await actions.savePaymentSetup("Stripe", vals.publishableKey, vals.secretKey);
          }}
          onDisconnect={() => actions.removePaymentSetup("Stripe")}
        />
        <PaymentCredentialForm
          provider="PayPal"
          logoEl={Bl.paypal}
          connected={paypalConnected}
          maskedKey={maskKey(intg.PayPal?.clientId)}
          fields={[
            { key: "clientId", label: "Client ID",     placeholder: "AaBbCcDd…", secret: false },
            { key: "secret",   label: "Client secret", placeholder: "EeFfGg…",   secret: true  },
          ]}
          onSave={async (vals) => {
            await actions.savePaymentSetup("PayPal", vals.clientId, vals.secret);
          }}
          onDisconnect={() => actions.removePaymentSetup("PayPal")}
        />
      </div>

      <h3 className="intg-section-h">Calendar</h3>
      <div className="intg-grid" style={{marginBottom:32}}>
        {limits.calendarSync ? (
          <AppleCalendarCredentialForm
            connected={intg["Apple Calendar"]?.connected}
            email={intg["Apple Calendar"]?.email || ""}
            onSave={async (appleId, appPass) => { await actions.saveAppleCalendarSetup(appleId, appPass); }}
            onDisconnect={() => actions.removeAppleCalendarSetup()}
          />
        ) : (
          <div className="intg-card payment-intg-card">
            <div className="intg-card-h">
              <div className="intg-logo" style={{flexShrink:0}}>{Bl.apple}</div>
              <div style={{flex:1,minWidth:0}}><div className="name">Apple Calendar</div></div>
            </div>
            <div style={{marginTop:12}}><PlanGate feature="Apple Calendar sync" requiredPlan="Professional"/></div>
          </div>
        )}
        <div className="intg-card payment-intg-card">
          <div className="intg-card-h">
            <div className="intg-logo" style={{flexShrink:0}}>{Bl.gcal}</div>
            <div style={{flex:1,minWidth:0}}>
              <div className="name">Google Calendar</div>
              {gcalConnected && gcalEmail && (
                <div style={{fontSize:12,color:"var(--text-muted)",marginTop:2,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}>{gcalEmail}</div>
              )}
            </div>
            {gcalConnected && <span style={{fontSize:11,fontWeight:600,color:"#22c55e",background:"rgba(34,197,94,.12)",borderRadius:6,padding:"3px 8px",whiteSpace:"nowrap"}}>Connected</span>}
          </div>
          <div className="desc" style={{margin:"12px 0 16px"}}>
            Automatically creates, updates, and removes Google Calendar events when bookings are made, rescheduled, or cancelled.
          </div>
          {limits.calendarSync ? (
            gcalConnected ? (
              <button
                className="btn disconnect"
                style={{fontSize:13}}
                disabled={gcalLoading}
                onClick={async () => {
                  setGcalLoading(true);
                  await actions.disconnectGoogleCalendar();
                  setGcalLoading(false);
                }}
              >
                {gcalLoading ? "Disconnecting…" : "Disconnect"}
              </button>
            ) : (
              <button
                className="btn primary"
                style={{fontSize:13}}
                disabled={gcalLoading}
                onClick={async () => {
                  setGcalLoading(true);
                  await actions.connectGoogleCalendar();
                  // page will redirect to Google — loading stays true
                }}
              >
                {gcalLoading ? "Redirecting…" : "Connect Google Calendar"}
              </button>
            )
          ) : (
            <PlanGate feature="Google Calendar sync" requiredPlan="Professional"/>
          )}
        </div>
      </div>

      <h3 className="intg-section-h">Messaging</h3>
      <div className="intg-grid" style={{marginBottom:32}}>
        {limits.whatsapp ? (
          <WhatsAppCredentialForm
            connected={intg.WhatsApp?.connected}
            phone={intg.WhatsApp?.phone || ""}
            onSave={async (phone) => { await actions.saveWhatsAppSetup(phone); }}
            onDisconnect={() => actions.removeWhatsAppSetup()}
          />
        ) : (
          <div className="intg-card payment-intg-card">
            <div className="intg-card-h">
              <div className="intg-logo" style={{flexShrink:0}}>{Bl.whatsapp || <span style={{fontSize:22}}>💬</span>}</div>
              <div style={{flex:1,minWidth:0}}><div className="name">WhatsApp Business</div></div>
            </div>
            <div style={{marginTop:12}}><PlanGate feature="WhatsApp notifications" requiredPlan="Professional"/></div>
          </div>
        )}
        {limits.smsReminders ? (
          <TwilioCredentialForm
            connected={intg.Twilio?.connected}
            phone={intg.Twilio?.phone || ""}
            onSave={async (vals) => {
              await actions.saveTwilioSetup(vals.accountSid, vals.authToken, vals.fromNumber);
            }}
            onDisconnect={() => actions.removeTwilioSetup()}
          />
        ) : (
          <div className="intg-card payment-intg-card">
            <div className="intg-card-h">
              <div className="intg-logo" style={{flexShrink:0}}>{Bl.twilio}</div>
              <div style={{flex:1,minWidth:0}}><div className="name">Twilio</div></div>
            </div>
            <div style={{marginTop:12}}><PlanGate feature="SMS reminders (Twilio)" requiredPlan="Professional"/></div>
          </div>
        )}
      </div>

      <h3 className="intg-section-h">Video Meetings</h3>
      <div className="intg-grid" style={{marginBottom:32}}>

        {/* Google Meet — included with Google Calendar */}
        <div className="intg-card payment-intg-card">
          <div className="intg-card-h">
            <div className="intg-logo" style={{flexShrink:0}}>{Bl.gmeet}</div>
            <div style={{flex:1,minWidth:0}}><div className="name">Google Meet</div></div>
            {gcalConnected && <span style={{fontSize:11,fontWeight:600,color:"#22c55e",background:"rgba(34,197,94,.12)",borderRadius:6,padding:"3px 8px",whiteSpace:"nowrap"}}>Ready</span>}
          </div>
          <div className="desc" style={{margin:"12px 0 16px"}}>
            {gcalConnected
              ? "Google Meet links will be generated automatically when a Google Meet booking is made."
              : "Connect Google Calendar above to enable Google Meet links for video bookings."
            }
          </div>
          {!gcalConnected && (
            <button
              className="btn primary"
              style={{fontSize:13}}
              disabled={gcalLoading}
              onClick={async () => {
                setGcalLoading(true);
                await actions.connectGoogleCalendar();
              }}
            >
              {gcalLoading ? "Redirecting…" : "Connect Google Calendar"}
            </button>
          )}
        </div>

        {/* Zoom */}
        <ZoomCredentialForm
          connected={zoomConnected}
          onSave={async (accountId, clientId, clientSecret) => {
            await actions.saveZoomSetup(accountId, clientId, clientSecret);
          }}
          onDisconnect={() => actions.removeZoomSetup()}
        />

        {/* Microsoft Teams */}
        <div className="intg-card payment-intg-card">
          <div className="intg-card-h">
            <div className="intg-logo" style={{flexShrink:0}}>{Bl.teams}</div>
            <div style={{flex:1,minWidth:0}}><div className="name">Microsoft Teams</div></div>
            {teamsConnected && <span style={{fontSize:11,fontWeight:600,color:"#22c55e",background:"rgba(34,197,94,.12)",borderRadius:6,padding:"3px 8px",whiteSpace:"nowrap"}}>Connected</span>}
          </div>
          <div className="desc" style={{margin:"12px 0 16px"}}>
            Automatically creates a Teams meeting when a video booking is made and saves the join link.
          </div>
          {teamsConnected ? (
            <button
              className="btn disconnect"
              style={{fontSize:13}}
              disabled={teamsLoading}
              onClick={async () => {
                setTeamsLoading(true);
                await actions.disconnectMicrosoftTeams();
                setTeamsLoading(false);
              }}
            >
              {teamsLoading ? "Disconnecting…" : "Disconnect"}
            </button>
          ) : (
            <button
              className="btn primary"
              style={{fontSize:13}}
              disabled={teamsLoading}
              onClick={async () => {
                setTeamsLoading(true);
                await actions.connectMicrosoftTeams();
              }}
            >
              {teamsLoading ? "Redirecting…" : "Connect Microsoft Teams"}
            </button>
          )}
        </div>

      </div>

      {/* ── Automation (Webhooks + Zapier) ── */}
      <h3 className="intg-section-h">Automation</h3>
      <div className="intg-grid" style={{marginBottom:32}}>

        {/* Webhooks card */}
        {limits.webhooks ? (
          <WebhooksCard data={data} actions={actions}/>
        ) : (
          <div className="intg-card payment-intg-card">
            <div className="intg-card-h">
              <div className="intg-logo" style={{flexShrink:0, background:"#1e293b", display:"flex", alignItems:"center", justifyContent:"center"}}>
                <I.bolt size={18} style={{color:"#7aa7ff"}}/>
              </div>
              <div style={{flex:1,minWidth:0}}><div className="name">Webhooks</div></div>
            </div>
            <div style={{marginTop:12}}><PlanGate feature="Webhook endpoints" requiredPlan="Business"/></div>
          </div>
        )}

        {/* Zapier card */}
        {limits.webhooks ? (
          <ZapierCard data={data} actions={actions}/>
        ) : (
          <div className="intg-card payment-intg-card">
            <div className="intg-card-h">
              <div className="intg-logo" style={{flexShrink:0}}>{Bl.zapier || <span style={{fontWeight:800, fontSize:15, color:"#FF4A00", letterSpacing:"-0.5px"}}>Zap</span>}</div>
              <div style={{flex:1,minWidth:0}}><div className="name">Zapier</div></div>
            </div>
            <div style={{marginTop:12}}><PlanGate feature="Zapier integration" requiredPlan="Business"/></div>
          </div>
        )}

      </div>

      {/* ── Discovery ── */}
      <h3 className="intg-section-h">Discovery</h3>
      <div className="intg-grid" style={{marginBottom:32}}>
        <ReserveWithGoogleCard data={data} actions={actions}/>
      </div>

      {/* ── Client Engagement ── */}
      <h3 className="intg-section-h">Client Engagement</h3>
      <div style={{marginBottom:32}}>
        <WinBackCard data={data} actions={actions}/>
      </div>

    </>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Webhooks management card
// ──────────────────────────────────────────────────────────────────────────

const WEBHOOK_EVENTS = [
  { id: "booking.created",     label: "Booking created",     desc: "Fires when a new booking is confirmed" },
  { id: "booking.cancelled",   label: "Booking cancelled",   desc: "Fires when a booking is cancelled" },
  { id: "booking.rescheduled", label: "Booking rescheduled", desc: "Fires when a booking is moved to a new time" },
  { id: "payment.received",    label: "Payment received",    desc: "Fires when a deposit or full payment is taken" },
];

function WebhookModal({ hook, onSave, onClose }) {
  const isNew = !hook?.id;
  const [form, setForm] = React.useState({
    name: "", url: "", events: [], secret: "", active: true, ...hook,
  });
  const [errors, setErrors] = React.useState({});
  const upd = (k, v) => setForm(f => ({ ...f, [k]: v }));

  const toggleEvent = (id) => {
    setForm(f => {
      const evs = f.events || [];
      return { ...f, events: evs.includes(id) ? evs.filter(e => e !== id) : [...evs, id] };
    });
  };

  const handleSave = () => {
    const errs = {};
    if (!form.url.trim()) errs.url = true;
    else if (!form.url.startsWith("http")) errs.url = "url";
    if ((form.events || []).length === 0) errs.events = true;
    setErrors(errs);
    if (Object.keys(errs).length > 0) return;
    onSave({ ...form, url: form.url.trim() });
  };

  return (
    <div className="modal-overlay" onClick={e => e.target === e.currentTarget && onClose()}>
      <div className="modal-panel" style={{maxWidth:500}}>
        <div className="modal-head">
          <h3>{isNew ? "Add webhook endpoint" : "Edit webhook"}</h3>
          <button className="modal-close" onClick={onClose}><I.x size={14}/></button>
        </div>
        <div className="modal-body">
          <div className="bk-form" style={{gap:16}}>
            <div className="bk-field">
              <label>Endpoint name <span className="opt">(optional)</span></label>
              <input className="bk-input" value={form.name} placeholder="e.g. Zapier booking handler"
                onChange={e => upd("name", e.target.value)}/>
            </div>
            <div className="bk-field">
              <label>Endpoint URL <span className="req">*</span></label>
              <input className={"bk-input " + (errors.url ? "invalid" : "")} value={form.url}
                placeholder="https://hooks.zapier.com/hooks/catch/…"
                onChange={e => upd("url", e.target.value)}/>
              {errors.url && <div style={{fontSize:12, color:"var(--danger)", marginTop:4}}>Enter a valid URL starting with https://</div>}
            </div>
            <div className="bk-field">
              <label>Events to send <span className="req">*</span></label>
              {errors.events && <div style={{fontSize:12, color:"var(--danger)", marginBottom:6}}>Select at least one event</div>}
              <div style={{display:"flex", flexDirection:"column", gap:8}}>
                {WEBHOOK_EVENTS.map(ev => (
                  <label key={ev.id} style={{display:"flex", alignItems:"flex-start", gap:10, cursor:"pointer"}}>
                    <input type="checkbox" style={{marginTop:2}} checked={(form.events || []).includes(ev.id)}
                      onChange={() => toggleEvent(ev.id)}/>
                    <div>
                      <div style={{fontSize:13, fontWeight:500, color:"var(--text)"}}>{ev.label}</div>
                      <div style={{fontSize:12, color:"var(--text-muted)"}}>{ev.desc}</div>
                    </div>
                  </label>
                ))}
              </div>
            </div>
            <div className="bk-field">
              <label>Secret token <span className="opt">(optional)</span></label>
              <input className="bk-input" value={form.secret} placeholder="Used as X-Nexus-Signature header"
                onChange={e => upd("secret", e.target.value)}/>
              <div style={{fontSize:12, color:"var(--text-muted)", marginTop:4}}>We'll send this as an <code>X-Nexus-Signature</code> header so you can verify requests.</div>
            </div>
            <div className="bk-field">
              <label style={{display:"flex", alignItems:"center", gap:10, cursor:"pointer"}}>
                <input type="checkbox" checked={!!form.active} onChange={e => upd("active", e.target.checked)}/>
                Endpoint active
              </label>
            </div>
          </div>
        </div>
        <div className="modal-foot">
          <button className="btn ghost" onClick={onClose}>Cancel</button>
          <button className="btn primary" onClick={handleSave}>{isNew ? "Add endpoint" : "Save changes"}</button>
        </div>
      </div>
    </div>
  );
}

function WebhooksCard({ data, actions }) {
  const [editing, setEditing]     = React.useState(null);
  const [confirmDel, setConfirmDel] = React.useState(null);
  const [testResult, setTestResult] = React.useState({}); // { [id]: "ok"|"fail"|"sending" }
  const webhooks = data?.webhooks || [];

  const handleSave = (hook) => {
    actions.saveWebhook(hook);
    setEditing(null);
  };

  const sendTest = async (hook) => {
    setTestResult(r => ({ ...r, [hook.id]: "sending" }));
    try {
      await fetch(hook.url, {
        method: "POST",
        headers: { "Content-Type": "application/json", ...(hook.secret ? { "X-Nexus-Signature": hook.secret } : {}) },
        body: JSON.stringify({
          event: "test",
          timestamp: new Date().toISOString(),
          data: { message: "This is a test payload from Nexus Booking." },
        }),
      });
      setTestResult(r => ({ ...r, [hook.id]: "ok" }));
    } catch {
      setTestResult(r => ({ ...r, [hook.id]: "fail" }));
    }
    setTimeout(() => setTestResult(r => { const n = { ...r }; delete n[hook.id]; return n; }), 4000);
  };

  return (
    <div className="intg-card payment-intg-card" style={{gridColumn: webhooks.length > 0 ? "1 / -1" : undefined}}>
      <div className="intg-card-h" style={{marginBottom:14}}>
        <div style={{display:"flex", alignItems:"center", gap:10}}>
          <div className="intg-logo" style={{flexShrink:0, background:"#1e293b", display:"flex", alignItems:"center", justifyContent:"center"}}>
            <I.bolt size={18} style={{color:"#7aa7ff"}}/>
          </div>
          <div>
            <div className="name">Webhooks</div>
            <div style={{fontSize:12, color:"var(--text-muted)", marginTop:1}}>POST payloads to your endpoints on booking events</div>
          </div>
        </div>
        <button className="btn primary sm" style={{flexShrink:0}} onClick={() => setEditing({})}>
          <I.plus size={12}/> Add endpoint
        </button>
      </div>

      {webhooks.length === 0 ? (
        <div style={{padding:"20px 0", textAlign:"center", color:"var(--text-muted)", fontSize:13}}>
          No endpoints yet — add one to start receiving events.
        </div>
      ) : (
        <div style={{display:"flex", flexDirection:"column", gap:10}}>
          {webhooks.map(hook => {
            const tr = testResult[hook.id];
            return (
              <div key={hook.id} style={{
                background:"var(--surface-2)", borderRadius:10, padding:"12px 14px",
                border:"1px solid var(--border)",
                display:"flex", alignItems:"flex-start", gap:12,
              }}>
                <div style={{flex:1, minWidth:0}}>
                  <div style={{display:"flex", alignItems:"center", gap:8, flexWrap:"wrap"}}>
                    <span style={{fontWeight:600, fontSize:13, color:"var(--text)"}}>{hook.name || "Unnamed endpoint"}</span>
                    <span style={{
                      fontSize:11, fontWeight:600, borderRadius:6, padding:"2px 7px",
                      background: hook.active !== false ? "rgba(34,197,94,.12)" : "rgba(148,163,184,.12)",
                      color: hook.active !== false ? "#22c55e" : "var(--text-muted)",
                    }}>
                      {hook.active !== false ? "Active" : "Paused"}
                    </span>
                  </div>
                  <div style={{fontSize:12, color:"var(--text-muted)", marginTop:3, wordBreak:"break-all"}}>{hook.url}</div>
                  <div style={{display:"flex", gap:6, flexWrap:"wrap", marginTop:6}}>
                    {(hook.events || []).map(ev => (
                      <span key={ev} style={{
                        fontSize:11, background:"var(--surface)", border:"1px solid var(--border)",
                        borderRadius:5, padding:"2px 6px", color:"var(--text-muted)",
                      }}>{ev}</span>
                    ))}
                  </div>
                </div>
                <div style={{display:"flex", gap:6, flexShrink:0}}>
                  <button className="btn ghost sm" onClick={() => sendTest(hook)} disabled={tr === "sending"}>
                    {tr === "sending" ? "Sending…" : tr === "ok" ? <><I.check size={12}/> Sent</> : tr === "fail" ? "Failed" : "Test"}
                  </button>
                  <button className="btn ghost sm" onClick={() => setEditing(hook)}>Edit</button>
                  <button className="btn ghost sm" style={{color:"var(--danger)"}} onClick={() => setConfirmDel(hook)}>Remove</button>
                </div>
              </div>
            );
          })}
        </div>
      )}

      {editing !== null && (
        <WebhookModal hook={editing} onSave={handleSave} onClose={() => setEditing(null)}/>
      )}
      {confirmDel && (
        <div className="modal-overlay" onClick={e => e.target === e.currentTarget && setConfirmDel(null)}>
          <div className="modal-panel" style={{maxWidth:380}}>
            <div className="modal-head">
              <h3>Remove webhook</h3>
              <button className="modal-close" onClick={() => setConfirmDel(null)}><I.x size={14}/></button>
            </div>
            <div className="modal-body">
              <p style={{margin:0, color:"var(--text-muted)", fontSize:14, lineHeight:1.6}}>
                Remove the endpoint <strong style={{color:"var(--text)"}}>{confirmDel.name || confirmDel.url}</strong>? Events will stop being sent to this URL.
              </p>
            </div>
            <div className="modal-foot">
              <button className="btn ghost" onClick={() => setConfirmDel(null)}>Cancel</button>
              <button className="btn danger" onClick={() => { actions.deleteWebhook(confirmDel.id); setConfirmDel(null); }}>Remove</button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Zapier integration card
// ──────────────────────────────────────────────────────────────────────────

function ZapierCard({ data, actions }) {
  const [showSteps, setShowSteps] = React.useState(false);
  const webhooks = data?.webhooks || [];
  const hasWebhook = webhooks.length > 0;

  return (
    <div className="intg-card payment-intg-card">
      <div className="intg-card-h">
        <div className="intg-logo" style={{flexShrink:0, background:"#FF4A00", display:"flex", alignItems:"center", justifyContent:"center"}}>
          <I.bolt size={18} style={{color:"#fff"}}/>
        </div>
        <div style={{flex:1,minWidth:0}}>
          <div className="name">Zapier</div>
          {hasWebhook && <span style={{fontSize:11,fontWeight:600,color:"#22c55e",background:"rgba(34,197,94,.12)",borderRadius:6,padding:"3px 8px",whiteSpace:"nowrap",display:"inline-block",marginTop:2}}>Ready to connect</span>}
        </div>
      </div>
      <div className="desc" style={{margin:"12px 0 14px"}}>
        Connect Nexus Booking to 7,000+ apps via Zapier. Use your webhook endpoint with Zapier's built-in <strong>Webhooks by Zapier</strong> trigger — no Zapier developer account needed.
      </div>

      {!hasWebhook && (
        <div style={{
          background:"rgba(239,164,3,0.08)", border:"1px solid rgba(239,164,3,0.25)",
          borderRadius:8, padding:"10px 12px", fontSize:13, color:"var(--text-muted)", marginBottom:14,
        }}>
          <I.warn size={13} style={{marginRight:6, color:"#efa403", verticalAlign:"text-bottom"}}/>
          Add a webhook endpoint above first, then use that URL in Zapier.
        </div>
      )}

      <button className="btn ghost" style={{fontSize:13, width:"100%", justifyContent:"center"}}
        onClick={() => setShowSteps(v => !v)}>
        {showSteps ? "Hide" : "Show"} setup instructions <I.chevDn size={13} style={{marginLeft:4, transform: showSteps ? "rotate(180deg)" : undefined, transition:"transform 0.2s"}}/>
      </button>

      {showSteps && (
        <div style={{marginTop:14, display:"flex", flexDirection:"column", gap:12}}>
          {[
            { n:1, title:"Add a webhook endpoint", body:`Click "Add endpoint" in the Webhooks card on the left. Choose the events you want to send (e.g. booking.created). Copy the URL Zapier gives you and paste it as the endpoint URL.` },
            { n:2, title:"Create a Zap in Zapier", body:`Go to zapier.com and create a new Zap. For the trigger, search for "Webhooks by Zapier" and choose "Catch Hook". Zapier will give you a unique webhook URL.` },
            { n:3, title:"Paste the URL into Nexus", body:`Copy the Zapier webhook URL, come back here, and paste it as the Endpoint URL when adding your webhook above. Select the events you want to fire.` },
            { n:4, title:"Test the connection", body:`Hit the Test button on your endpoint. Zapier will show the sample payload. Use the field data to build your Zap actions — send a Slack message, create a HubSpot contact, add a row to Google Sheets, or anything else.` },
            { n:5, title:"Turn on your Zap", body:`Once you've mapped the fields in Zapier, turn the Zap on. Every matching booking event from Nexus will now trigger your Zap automatically.` },
          ].map(step => (
            <div key={step.n} style={{display:"flex", gap:12, alignItems:"flex-start"}}>
              <div style={{
                width:24, height:24, borderRadius:"50%", background:"var(--accent)", color:"#fff",
                display:"flex", alignItems:"center", justifyContent:"center",
                fontSize:12, fontWeight:700, flexShrink:0, marginTop:1,
              }}>{step.n}</div>
              <div>
                <div style={{fontWeight:600, fontSize:13, color:"var(--text)", marginBottom:2}}>{step.title}</div>
                <div style={{fontSize:13, color:"var(--text-muted)", lineHeight:1.5}}>{step.body}</div>
              </div>
            </div>
          ))}
          <a href="https://zapier.com" target="_blank" rel="noopener noreferrer"
            style={{display:"flex", alignItems:"center", gap:6, fontSize:13, color:"var(--accent)", marginTop:4, textDecoration:"none", fontWeight:500}}>
            Open Zapier <I.arrow size={13}/>
          </a>
        </div>
      )}
    </div>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Billing
// ──────────────────────────────────────────────────────────────────────────
// ── Card brand SVG logos ───────────────────────────────────────
const CARD_BRAND_SLUGS = {
  visa:               "visa",
  mastercard:         "mastercard",
  "master card":      "mastercard",
  amex:               "amex",
  "american express": "amex",
  discover:           "discover",
  maestro:            "maestro",
  jcb:                "jcb",
  unionpay:           "unionpay",
  "union pay":        "unionpay",
  diners:             "diners",
  "diners club":      "diners",
};

const CDN_BASE = "https://cdn.jsdelivr.net/gh/aaronfagan/svg-credit-card-payment-icons@main/flat-rounded/";

function CardBrandSVG({ brand = "visa" }) {
  const slug = CARD_BRAND_SLUGS[brand.toLowerCase()] || null;
  if (slug) {
    return (
      <img
        src={`${CDN_BASE}${slug}.svg`}
        alt={brand}
        width="52"
        height="36"
        style={{ display:"block", borderRadius:4, objectFit:"contain" }}
      />
    );
  }
  // Generic fallback (unknown brand)
  return (
    <svg viewBox="0 0 52 36" xmlns="http://www.w3.org/2000/svg" width="52" height="36">
      <rect width="52" height="36" rx="4" fill="#f0f0f0"/>
      <rect x="6" y="11" width="40" height="6" rx="2" fill="#ccc"/>
      <rect x="6" y="22" width="18" height="4" rx="2" fill="#ccc"/>
    </svg>
  );
}

// Plan display metadata for the billing view
const PLAN_DISPLAY = {
  starter:      { label: "Starter",      monthlyPrice: 19, annualPrice: 15, desc: "Unlimited bookings, 3 service types, and 1 staff member." },
  professional: { label: "Professional", monthlyPrice: 39, annualPrice: 29, desc: "Unlimited bookings, up to 5 staff, deposits, coupons, SMS reminders, and calendar sync.", next: "Business" },
  business:     { label: "Business",     monthlyPrice: 79, annualPrice: 59, desc: "Everything in Professional plus unlimited staff, white-label, multiple locations, and webhook access." },
};

function ViewBilling({ industry, data }) {
  const currency  = getCurrency(data.profile.currency);
  const plan      = getPlan(data);
  const limits    = planLimits(data);
  const planMeta  = PLAN_DISPLAY[plan] || PLAN_DISPLAY.professional;
  // Seed invoices use the annual rate (£29/mo billed annually for Professional)
  const invoiceAmt = `${currency.symbol}${planMeta.annualPrice}.00`;
  const invoices = [
    { id: "INV-2026-005", date: "May 1, 2026",  amount: invoiceAmt, status: "Paid" },
    { id: "INV-2026-004", date: "Apr 1, 2026",  amount: invoiceAmt, status: "Paid" },
    { id: "INV-2026-003", date: "Mar 1, 2026",  amount: invoiceAmt, status: "Paid" },
    { id: "INV-2026-002", date: "Feb 1, 2026",  amount: invoiceAmt, status: "Paid" },
    { id: "INV-2026-001", date: "Jan 1, 2026",  amount: invoiceAmt, status: "Paid" },
  ];

  // Pending plan — set in localStorage by login.jsx when signing up from a pricing card
  const PLAN_LABELS = { starter: "Starter", professional: "Professional", business: "Business" };
  const [pendingPlan, setPendingPlan] = React.useState(() => {
    const p = localStorage.getItem("nexus_pending_plan");
    return PLAN_LABELS[p] && p !== plan ? p : null;
  });
  const dismissPending = () => { localStorage.removeItem("nexus_pending_plan"); setPendingPlan(null); };

  return (
    <>
      <div className="view-h">
        <div>
          <h1>Billing</h1>
          <div className="sub">Plan, payment, and invoice history.</div>
        </div>
      </div>

      {/* Pending plan banner — shown once after signing up from a pricing card */}
      {pendingPlan && (
        <div style={{
          display:"flex", alignItems:"center", justifyContent:"space-between", flexWrap:"wrap", gap:12,
          padding:"14px 18px", marginBottom:20, borderRadius:10,
          background:"var(--accent-soft, #eef2ff)", border:"1px solid var(--accent-border, #c7d2fe)",
        }}>
          <div style={{display:"flex", alignItems:"center", gap:10}}>
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="var(--accent,#4f46e5)" strokeWidth="2.5">
              <path d="M20 12V22H4V12"/><path d="M22 7H2v5h20V7z"/><path d="M12 22V7"/><path d="M12 7H7.5a2.5 2.5 0 0 1 0-5C11 2 12 7 12 7z"/><path d="M12 7h4.5a2.5 2.5 0 0 0 0-5C13 2 12 7 12 7z"/>
            </svg>
            <div>
              <div style={{fontWeight:600, fontSize:14, color:"var(--accent,#4f46e5)"}}>
                You selected the {PLAN_LABELS[pendingPlan]} plan
              </div>
              <div style={{fontSize:12, color:"var(--text-muted)", marginTop:2}}>
                Activate your plan below to unlock all {PLAN_LABELS[pendingPlan]} features.
              </div>
            </div>
          </div>
          <div style={{display:"flex", gap:8}}>
            <button className="btn primary" style={{fontSize:13}} onClick={dismissPending}>
              Activate {PLAN_LABELS[pendingPlan]}
            </button>
            <button className="btn ghost" style={{fontSize:13}} onClick={dismissPending}>Dismiss</button>
          </div>
        </div>
      )}

      <div className="billing-top">
        <div className="plan-card">
          <span className="badge">Current plan</span>
          <h2>{planMeta.label}</h2>
          <div className="desc">{planMeta.desc}</div>
          <div className="price">{currency.symbol}{planMeta.annualPrice}<small>/month</small></div>
          <div style={{fontSize:12, color:"var(--text-muted)", marginTop:4}}>Billed annually (monthly rate: {currency.symbol}{planMeta.monthlyPrice}/mo)</div>
          <div className="actions" style={{marginTop:18}}>
            {planMeta.next && <button className="btn primary">Upgrade to {planMeta.next}</button>}
            <button className="btn ghost">Cancel plan</button>
          </div>
        </div>

        <div className="card usage-card">
          <h3>Usage this month</h3>
          <div className="usage-row">
            <div className="usage-h"><span className="label">Bookings</span><span className="val">428 / Unlimited</span></div>
            <div className="usage-bar"><div className="fill" style={{width:"28%"}}/></div>
          </div>
          <div className="usage-row">
            {(() => {
              const currentStaff = (data.staff || []).length;
              const staffMax     = limits.maxStaff < Infinity ? limits.maxStaff : null;
              const staffPct     = staffMax ? Math.min(100, Math.round((currentStaff / staffMax) * 100)) : 10;
              return (
                <>
                  <div className="usage-h">
                    <span className="label">Team members</span>
                    <span className="val">{currentStaff} / {staffMax !== null ? staffMax : "Unlimited"}</span>
                  </div>
                  <div className="usage-bar"><div className={"fill" + (staffPct >= 80 ? " warn" : "")} style={{width:`${staffPct}%`}}/></div>
                </>
              );
            })()}
          </div>
          <div className="usage-row">
            <div className="usage-h"><span className="label">SMS reminders</span><span className="val">86 / 100</span></div>
            <div className="usage-bar"><div className="fill warn" style={{width:"86%"}}/></div>
          </div>
          <div className="usage-row">
            <div className="usage-h"><span className="label">Storage</span><span className="val">1.2 / 5 GB</span></div>
            <div className="usage-bar"><div className="fill" style={{width:"24%"}}/></div>
          </div>
        </div>
      </div>

      <div style={{display:"grid", gridTemplateColumns:"1fr 1fr", gap:20, marginBottom:24}}>
        <div>
          <h3 style={{margin:"0 0 12px", fontSize:13, fontWeight:500, color:"var(--text-muted)", textTransform:"uppercase", letterSpacing:"0.06em"}}>
            Payment method
          </h3>
          <div className="payment-card">
            <div className="card-art"><CardBrandSVG brand="visa"/></div>
            <div style={{flex:1}}>
              <div className="num">•••• •••• •••• 4242</div>
              <div className="exp">Expires 08/2028 · Nora Singh</div>
            </div>
            <button className="btn ghost">Update</button>
          </div>
        </div>
        <div>
          <h3 style={{margin:"0 0 12px", fontSize:13, fontWeight:500, color:"var(--text-muted)", textTransform:"uppercase", letterSpacing:"0.06em"}}>
            Billing email
          </h3>
          <div className="payment-card">
            <div className="card-art" style={{background:"var(--surface-2)"}}><I.bell size={14}/></div>
            <div style={{flex:1}}>
              <div className="num" style={{fontSize:13}}>nora@apexadvisors.com</div>
              <div className="exp">Receipts & renewal notices</div>
            </div>
            <button className="btn ghost">Edit</button>
          </div>
        </div>
      </div>

      <div className="card">
        <div className="card-h">
          <h3>Invoices</h3>
          <button className="card-link">Download all</button>
        </div>
        <table className="table">
          <thead>
            <tr><th>Invoice</th><th>Date</th><th>Amount</th><th>Status</th><th></th></tr>
          </thead>
          <tbody>
            {invoices.map((inv, i) => (
              <tr key={inv.id}>
                <td style={{fontVariantNumeric:"tabular-nums"}}>{inv.id}</td>
                <td>{inv.date}</td>
                <td style={{fontVariantNumeric:"tabular-nums"}}>{inv.amount}</td>
                <td><span className="pill confirmed">{inv.status}</span></td>
                <td style={{textAlign:"right"}}>
                  <button className="row-actions" title="Download"><I.arrow size={14} style={{transform:"rotate(90deg)"}}/></button>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Settings
// ──────────────────────────────────────────────────────────────────────────
const COUNTRIES = [
  { code: "GB", name: "United Kingdom" }, { code: "US", name: "United States" },
  { code: "IE", name: "Ireland" },        { code: "AU", name: "Australia" },
  { code: "CA", name: "Canada" },         { code: "NZ", name: "New Zealand" },
  { code: "DE", name: "Germany" },        { code: "FR", name: "France" },
  { code: "ES", name: "Spain" },          { code: "IT", name: "Italy" },
  { code: "NL", name: "Netherlands" },    { code: "BE", name: "Belgium" },
  { code: "SE", name: "Sweden" },         { code: "NO", name: "Norway" },
  { code: "DK", name: "Denmark" },        { code: "FI", name: "Finland" },
  { code: "PT", name: "Portugal" },       { code: "CH", name: "Switzerland" },
  { code: "AT", name: "Austria" },        { code: "PL", name: "Poland" },
];

function ViewSettings({ data, actions }) {
  const [tab, setTab] = React.useState("profile");
  const [profileDraft, setProfileDraft] = React.useState(data.profile);
  const [notifs, setNotifs] = React.useState(data.notifications || {});
  React.useEffect(() => setProfileDraft(data.profile), [data.profile]);
  React.useEffect(() => setNotifs(data.notifications || {}), [data.notifications]);
  const [reminderTiming,      setReminderTiming]      = React.useState(() => (data.notifications || {}).reminderTiming || "both");
  const [reminderChannels,    setReminderChannels]    = React.useState(() => (data.notifications || {}).reminderChannels || "email");
  const [reminderEmailSubject,setReminderEmailSubject]= React.useState(() => (data.notifications || {}).reminderEmailSubject || "Reminder: your appointment is coming up");
  const [reminderEmailBody,   setReminderEmailBody]   = React.useState(() => (data.notifications || {}).reminderEmailBody || "Hi {{guest_name}},\n\nThis is a friendly reminder that your {{service_name}} appointment is coming up on {{date}} at {{time}}.\n\nLooking forward to seeing you!\n\n{{business_name}}");
  const [reminderSmsBody,     setReminderSmsBody]     = React.useState(() => (data.notifications || {}).reminderSmsBody || "Reminder: {{service_name}} on {{date}} at {{time}}. Reply STOP to opt out. — {{business_name}}");
  const [confirmEmailSubject, setConfirmEmailSubject] = React.useState(() => (data.notifications || {}).confirmEmailSubject || "Your booking is confirmed — {{service_name}}");
  const [confirmEmailBody,    setConfirmEmailBody]    = React.useState(() => (data.notifications || {}).confirmEmailBody || "Hi {{guest_name}},\n\nYour {{service_name}} booking is confirmed for {{date}} at {{time}}.\n\nIf you need to make any changes, please contact us.\n\nSee you soon!\n{{business_name}}");
  const [confirmSmsBody,      setConfirmSmsBody]      = React.useState(() => (data.notifications || {}).confirmSmsBody || "Booking confirmed: {{service_name}} on {{date}} at {{time}}. — {{business_name}}");
  const setProfile = (key, value) => setProfileDraft((p) => ({ ...p, [key]: value }));
  const swatches = ["#006e78", "#0070BA", "#635BFF", "#10b981", "#f59e9e", "#111827"];
  const [policy, setPolicyDraft] = React.useState(() => data.profile.policy || {});
  const setPolicy = (k, v) => setPolicyDraft(d => ({...d, [k]: v}));

  // ── Company info state ────────────────────────────────────
  const companyFields = ["vatNumber","companyName","address1","address2","city","postcode","country","companyEmail","companyPhone","website","whatsapp","facebook","instagram","twitter","linkedin","hideEmail","hideAddress","companyLat","companyLon"];
  const [company, setCompanyDraft] = React.useState(() => {
    const c = {};
    companyFields.forEach(k => { c[k] = data.profile[k] ?? ""; });
    c.country = c.country || "GB";
    c.hideEmail = !!data.profile.hideEmail;
    c.hideAddress = !!data.profile.hideAddress;
    return c;
  });
  const setComp = (key, value) => setCompanyDraft(d => ({ ...d, [key]: value }));
  const saveCompany = () => actions.updateProfile({ ...data.profile, ...company });

  // ── Map state ─────────────────────────────────────────────
  const DEFAULT_MAP = "https://www.openstreetmap.org/export/embed.html?bbox=-5.5,49.8,2.1,58.7&layer=mapnik";
  const [mapQuery, setMapQuery] = React.useState("");
  const [mapSrc, setMapSrc] = React.useState(() => {
    const lat = data.profile.companyLat, lon = data.profile.companyLon;
    if (lat && lon) {
      const d = 0.02;
      return `https://www.openstreetmap.org/export/embed.html?bbox=${lon-d},${lat-d},${lon+d},${lat+d}&layer=mapnik&marker=${lat},${lon}`;
    }
    return DEFAULT_MAP;
  });
  const [mapBusy, setMapBusy] = React.useState(false);
  const [mapErr, setMapErr]   = React.useState("");

  // ── Embed tab state (hoisted to top level — hooks must not be conditional) ─
  const [activeSnippet, setActiveSnippet] = React.useState("floating");
  const [embedCopied, setEmbedCopied]     = React.useState(false);

  // ── Security / password state ────────────────────────────
  const [pwCurrent, setPwCurrent]   = React.useState("");
  const [pwNew,     setPwNew]       = React.useState("");
  const [pwBusy,    setPwBusy]      = React.useState(false);
  const [pwMsg,     setPwMsg]       = React.useState(null); // { type: "success"|"error", text }

  const updatePassword = () => {
    if (!pwCurrent) { setPwMsg({ type:"error", text:"Please enter your current password." }); return; }
    if (pwNew.length < 12) { setPwMsg({ type:"error", text:"New password must be at least 12 characters." }); return; }
    setPwBusy(true); setPwMsg(null);
    setTimeout(() => {
      setPwBusy(false);
      setPwMsg({ type:"success", text:"Password updated successfully." });
      setPwCurrent(""); setPwNew("");
    }, 900);
  };

  // ── Security / 2FA state ──────────────────────────────────
  const [tfState, setTfState]   = React.useState(() => data.profile.twoFactor || { enabled: false, method: null });
  const [mfaModal, setMfaModal] = React.useState(null); // null | "totp" | "email" | "disable"
  const [mfaStep,  setMfaStep]  = React.useState(1);
  const [mfaCode,  setMfaCode]  = React.useState("");
  const [mfaBusy,  setMfaBusy]  = React.useState(false);
  const [mfaErr,   setMfaErr]   = React.useState("");
  const [emailSent, setEmailSent] = React.useState(false);

  const openMfa  = (type) => { setMfaModal(type); setMfaStep(1); setMfaCode(""); setMfaErr(""); setEmailSent(false); };
  const closeMfa = ()     => { setMfaModal(null); setMfaStep(1); setMfaCode(""); setMfaErr(""); setMfaBusy(false); setEmailSent(false); };

  const simulateVerify = (onSuccess) => {
    setMfaBusy(true); setMfaErr("");
    setTimeout(() => {
      setMfaBusy(false);
      if (mfaCode.length === 6 && /^\d+$/.test(mfaCode)) { onSuccess(); }
      else { setMfaErr("That code doesn't look right — please check and try again."); }
    }, 900);
  };

  const enableTwoFactor = (method) => {
    const updated = { enabled: true, method };
    setTfState(updated);
    actions.updateProfile({ ...data.profile, twoFactor: updated });
    setMfaStep(3); // success step
  };

  const disableTwoFactor = () => {
    const updated = { enabled: false, method: null };
    setTfState(updated);
    actions.updateProfile({ ...data.profile, twoFactor: updated });
    closeMfa();
  };

  const searchMap = async () => {
    const q = mapQuery.trim();
    if (!q) return;
    setMapBusy(true); setMapErr("");
    try {
      const res = await fetch(`https://nominatim.openstreetmap.org/search?q=${encodeURIComponent(q)}&format=json&limit=1`);
      const results = await res.json();
      if (!results.length) { setMapErr("Address not found — try adding a city or postcode."); return; }
      const { lat, lon, boundingbox } = results[0];
      const [s, n, w, e] = (boundingbox || []).map(Number);
      const bbox = boundingbox ? `${w},${s},${e},${n}` : `${lon-0.01},${lat-0.01},${lon+0.01},${lat+0.01}`;
      setMapSrc(`https://www.openstreetmap.org/export/embed.html?bbox=${bbox}&layer=mapnik&marker=${lat},${lon}`);
      setComp("companyLat", Number(lat));
      setComp("companyLon", Number(lon));
    } catch { setMapErr("Search failed — please try again."); }
    finally { setMapBusy(false); }
  };

  const sections = [
    { id: "profile",      label: "Profile" },
    { id: "branding",     label: "Branding" },
    { id: "company",      label: "Company" },
    { id: "notifications",label: "Notifications" },
    { id: "policies",     label: "Policies" },
    { id: "security",     label: "Security" },
    { id: "embed",        label: "Embed" },
  ];

  return (
    <>
      <div className="view-h">
        <div>
          <h1>Settings</h1>
          <div className="sub">Profile, branding, notifications, and account preferences.</div>
        </div>
      </div>

      <div className="settings-layout">
        <nav className="settings-nav">
          {sections.map(s => (
            <button key={s.id}
              className={tab === s.id ? "is-active" : ""}
              onClick={() => setTab(s.id)}>{s.label}</button>
          ))}
        </nav>

        <div>
          {tab === "profile" && (
            <div className="settings-section">
              <h3 className="section-h">Profile</h3>
              <p className="section-sub">How you appear to guests on your booking page.</p>
              <div className="card settings-card">
                <div style={{display:"flex", gap:18, alignItems:"center", marginBottom:24}}>
                  <div className="avatar lg" style={{position:"relative"}}>
                    {profileDraft.photoUrl
                      ? <img src={profileDraft.photoUrl} alt="" style={{position:"absolute",inset:0,width:"100%",height:"100%",objectFit:"cover",display:"block"}}/>
                      : profileDraft.initials}
                  </div>
                  <div style={{display:"flex", gap:8}}>
                    <label style={{display:"inline-flex", alignItems:"center", gap:7, padding:"7px 14px", background:"var(--surface-2)", border:"1px solid var(--border)", borderRadius:7, fontSize:13, fontWeight:500, color:"var(--text)", cursor:"pointer"}}>
                      Upload photo
                      <input type="file" accept="image/*" style={{display:"none"}} onChange={(e) => {
                        const file = e.target.files?.[0];
                        if (!file) return;
                        const reader = new FileReader();
                        reader.onload = (ev) => {
                          const img = new Image();
                          img.onload = () => {
                            const MAX = 512;
                            const scale = Math.min(1, MAX / Math.max(img.width, img.height));
                            const canvas = document.createElement("canvas");
                            canvas.width  = Math.round(img.width  * scale);
                            canvas.height = Math.round(img.height * scale);
                            canvas.getContext("2d").drawImage(img, 0, 0, canvas.width, canvas.height);
                            setProfile("photoUrl", canvas.toDataURL("image/jpeg", 0.82));
                          };
                          img.src = ev.target.result;
                        };
                        reader.readAsDataURL(file);
                      }}/>
                    </label>
                    {profileDraft.photoUrl && (
                      <button className="btn ghost" onClick={() => setProfile("photoUrl", "")}>Remove</button>
                    )}
                  </div>
                </div>
                <div className="field-grid">
                  <div className="bk-field"><label>Full name</label><input className="bk-input" value={profileDraft.name} onChange={(e) => setProfile("name", e.target.value)}/></div>
                  <div className="bk-field"><label>Display title</label><input className="bk-input" value={profileDraft.title} onChange={(e) => setProfile("title", e.target.value)}/></div>
                  <div className="bk-field"><label>Email</label><input className="bk-input" value={profileDraft.email} onChange={(e) => setProfile("email", e.target.value)}/></div>
                  <div className="bk-field"><label>Phone</label><input className="bk-input" value={profileDraft.phone} onChange={(e) => setProfile("phone", e.target.value)}/></div>
                  <div className="bk-field">
                    <label>Currency</label>
                    <select className="bk-input" value={profileDraft.currency || "GBP"} onChange={(e) => setProfile("currency", e.target.value)}>
                      {CURRENCIES.map((currency) => (
                        <option key={currency.code} value={currency.code}>
                          {currency.symbol} {currency.code} · {currency.label}
                        </option>
                      ))}
                    </select>
                  </div>
                </div>
                <div className="field-grid single" style={{marginTop:16}}>
                  <div className="bk-field">
                    <label>Public bio <span className="opt">(shown on booking page)</span></label>
                    <textarea className="bk-textarea" value={profileDraft.bio} onChange={(e) => setProfile("bio", e.target.value)}/>
                  </div>
                </div>
                <div style={{display:"flex", justifyContent:"flex-end", gap:8, marginTop:18}}>
                  <button className="btn ghost" onClick={() => setProfileDraft(data.profile)}>Cancel</button>
                  <button className="btn primary" onClick={() => actions.updateProfile({ ...profileDraft, initials: (profileDraft.name || "").split(" ").map((p) => p[0] || "").join("").slice(0, 2).toUpperCase() || getLogoText(profileDraft) })}>Save changes</button>
                </div>
              </div>
            </div>
          )}

          {tab === "branding" && (
            <div className="settings-section">
              <h3 className="section-h">Branding</h3>
              <p className="section-sub">Make the booking page feel like yours.</p>
              <div className="card settings-card">
                <div className="field-grid">
                  <div className="bk-field"><label>Brand name</label><input className="bk-input" value={profileDraft.brandName} onChange={(e) => setProfile("brandName", e.target.value)}/></div>
                  <div className="bk-field"><label>Booking URL</label><input className="bk-input" value={profileDraft.bookingUrl} onChange={(e) => setProfile("bookingUrl", e.target.value)}/></div>
                  <div className="bk-field"><label>Logo text</label><input className="bk-input" maxLength="3" value={profileDraft.logoText || getLogoText(profileDraft)} onChange={(e) => setProfile("logoText", e.target.value.toUpperCase())}/></div>
                  <div className="bk-field"><label>Logo background</label><input className="bk-input" value={profileDraft.logoBg || profileDraft.accent} onChange={(e) => setProfile("logoBg", e.target.value)}/></div>
                  <div className="bk-field" style={{gridColumn:"1 / -1"}}>
                    <label>Logo image <span className="opt">(optional)</span></label>
                    <div style={{display:"flex", alignItems:"center", gap:12, marginTop:4}}>
                      {profileDraft.logoUrl && (
                        <div style={{width:52, height:52, borderRadius:10, overflow:"hidden", border:"1px solid var(--border)", flexShrink:0, background:"var(--surface-2)", display:"flex", alignItems:"center", justifyContent:"center"}}>
                          <img src={profileDraft.logoUrl} alt="Logo" style={{width:"100%", height:"100%", objectFit:"contain"}}/>
                        </div>
                      )}
                      <div style={{display:"flex", flexDirection:"column", gap:6}}>
                        <label style={{display:"inline-flex", alignItems:"center", gap:7, padding:"7px 14px", background:"var(--surface-2)", border:"1px solid var(--border)", borderRadius:7, fontSize:13, fontWeight:500, color:"var(--text)", cursor:"pointer"}}>
                          <I.plus size={13}/> {profileDraft.logoUrl ? "Change image" : "Upload image"}
                          <input type="file" accept="image/*" style={{display:"none"}} onChange={(e) => {
                            const file = e.target.files?.[0];
                            if (!file) return;
                            const objectUrl = URL.createObjectURL(file);
                            const img = new Image();
                            img.onload = () => {
                              URL.revokeObjectURL(objectUrl);
                              const MAX = 512;
                              const scale = Math.min(1, MAX / Math.max(img.width, img.height));
                              const canvas = document.createElement("canvas");
                              canvas.width  = Math.round(img.width  * scale);
                              canvas.height = Math.round(img.height * scale);
                              canvas.getContext("2d").drawImage(img, 0, 0, canvas.width, canvas.height);
                              setProfile("logoUrl", canvas.toDataURL("image/jpeg", 0.82));
                            };
                            img.src = objectUrl;
                          }}/>
                        </label>
                        {profileDraft.logoUrl && (
                          <button className="btn ghost" style={{fontSize:12, color:"var(--text-muted)", padding:"3px 0", textAlign:"left"}} onClick={() => setProfile("logoUrl", "")}>Remove image</button>
                        )}
                      </div>
                    </div>
                  </div>
                </div>
                <div style={{marginTop:18}}>
                  <label style={{fontSize:12, color:"var(--text-muted)", display:"block", marginBottom:8}}>Brand accent color</label>
                  {planLimits(data).customBranding ? (
                    <div className="color-picker-row">
                      {swatches.map(s => (
                        <button key={s} className={"color-swatch " + (profileDraft.accent === s ? "is-selected" : "")}
                          style={{background: s}} onClick={() => setProfileDraft((p) => ({ ...p, accent: s, logoBg: p.logoBg || s }))} aria-label={s}/>
                      ))}
                      <input className="bk-input" style={{maxWidth:120, marginLeft:8}}
                        value={profileDraft.accent} onChange={e => setProfile("accent", e.target.value)}/>
                    </div>
                  ) : (
                    <div style={{display:"flex", alignItems:"center", gap:10, padding:"10px 14px", background:"var(--surface-2)", borderRadius:8, border:"1px solid var(--border)"}}>
                      <div style={{width:22, height:22, borderRadius:6, background:"#006e78", flexShrink:0}}/>
                      <div>
                        <div style={{fontSize:13, fontWeight:500, color:"var(--text)"}}>Nexus Booking teal — platform default</div>
                        <div style={{fontSize:12, color:"var(--text-muted)", marginTop:2}}>Custom brand colours are available on the <strong>Professional</strong> plan.</div>
                      </div>
                    </div>
                  )}
                </div>
                <div style={{marginTop:18}}>
                  <label style={{fontSize:12, color:"var(--text-muted)", display:"block", marginBottom:8}}>Brand preview</label>
                  <div className="brand-preview" style={getBrandStyle(profileDraft)}>
                    <div className="sb-mark" style={{width:48, height:48, fontSize:18}}>{profileDraft.logoUrl ? <img src={profileDraft.logoUrl} alt=""/> : getLogoText(profileDraft)}</div>
                    <div>
                      <div className="brand-preview-name">{profileDraft.brandName}</div>
                      <div className="brand-preview-url">{profileDraft.bookingUrl}</div>
                    </div>
                    <button className="btn primary" style={{marginLeft:"auto"}}>Book now</button>
                  </div>
                </div>
                <div className="notif-row" style={{marginTop:18}}>
                  <div>
                    <div className="title">White-label public booking page</div>
                    <div className="desc">
                      Hide Nexus Booking branding from guest booking and confirmation pages.
                      {!planLimits(data).whiteLabel && (
                        <span style={{display:"flex", alignItems:"center", gap:5, marginTop:4, color:"var(--text-muted)", fontSize:12}}>
                          <I.shield size={12} style={{flexShrink:0}}/> Available on the <strong>Business</strong> plan — upgrade in Billing.
                        </span>
                      )}
                    </div>
                  </div>
                  <label className="switch" title={!planLimits(data).whiteLabel ? "Business plan required" : undefined}>
                    <input type="checkbox"
                      checked={!!profileDraft.whiteLabel}
                      disabled={!planLimits(data).whiteLabel}
                      onChange={() => planLimits(data).whiteLabel && setProfile("whiteLabel", !profileDraft.whiteLabel)}/>
                    <span className="track"><span className="knob"/></span>
                  </label>
                </div>
                <div style={{display:"flex", justifyContent:"flex-end", gap:8, marginTop:24}}>
                  <button className="btn primary" onClick={() => actions.updateProfile(profileDraft)}>Save changes</button>
                </div>
              </div>
            </div>
          )}

          {tab === "company" && (
            <div className="settings-section">
              <h3 className="section-h">Company Information</h3>
              <p className="section-sub">Business details shown on your booking page and in confirmation emails.</p>
              <div className="company-grid">

                {/* ── Left column ── */}
                <div style={{display:"flex", flexDirection:"column", gap:20}}>
                  <div className="card settings-card">
                    <h4 className="company-section-h">General information</h4>
                    <div className="field-grid single">
                      <div className="bk-field"><label>VAT / Tax number</label><input className="bk-input" value={company.vatNumber} onChange={e => setComp("vatNumber", e.target.value)} placeholder="GB123456789"/></div>
                      <div className="bk-field"><label>Business name <span className="req">*</span></label><input className="bk-input" value={company.companyName} onChange={e => setComp("companyName", e.target.value)}/></div>
                      <div className="bk-field"><label>Address line 1</label><input className="bk-input" value={company.address1} onChange={e => setComp("address1", e.target.value)}/></div>
                      <div className="bk-field"><label>Address line 2</label><input className="bk-input" value={company.address2} onChange={e => setComp("address2", e.target.value)}/></div>
                      <div className="bk-field"><label>City</label><input className="bk-input" value={company.city} onChange={e => setComp("city", e.target.value)}/></div>
                      <div className="bk-field"><label>Postcode</label><input className="bk-input" value={company.postcode} onChange={e => setComp("postcode", e.target.value)}/></div>
                      <div className="bk-field">
                        <label>Country</label>
                        <select className="bk-input" value={company.country} onChange={e => setComp("country", e.target.value)}>
                          {COUNTRIES.map(c => <option key={c.code} value={c.code}>{c.name}</option>)}
                        </select>
                      </div>
                      <div className="bk-field"><label>Business email <span className="req">*</span></label><input className="bk-input" type="email" value={company.companyEmail} onChange={e => setComp("companyEmail", e.target.value)}/></div>
                      <div className="bk-field"><label>Phone</label><input className="bk-input" type="tel" value={company.companyPhone} onChange={e => setComp("companyPhone", e.target.value)}/></div>
                      <div className="bk-field"><label>Website</label><input className="bk-input" type="url" value={company.website} onChange={e => setComp("website", e.target.value)} placeholder="https://"/></div>
                    </div>
                  </div>

                  <div className="card settings-card">
                    <h4 className="company-section-h">Social &amp; messaging</h4>
                    <div className="field-grid single">
                      <div className="bk-field">
                        <label><span className="company-social-icon" style={{background:"#25D366"}}>W</span> WhatsApp</label>
                        <input className="bk-input" type="tel" value={company.whatsapp} onChange={e => setComp("whatsapp", e.target.value)} placeholder="+44 7700 000000"/>
                      </div>
                      <div className="bk-field">
                        <label><span className="company-social-icon" style={{background:"#1877F2"}}>f</span> Facebook</label>
                        <input className="bk-input" value={company.facebook} onChange={e => setComp("facebook", e.target.value)} placeholder="https://facebook.com/yourpage"/>
                      </div>
                      <div className="bk-field">
                        <label><span className="company-social-icon" style={{background:"linear-gradient(135deg,#f09433,#dc2743,#bc1888)"}}>Ig</span> Instagram</label>
                        <input className="bk-input" value={company.instagram} onChange={e => setComp("instagram", e.target.value)} placeholder="https://instagram.com/yourhandle"/>
                      </div>
                      <div className="bk-field">
                        <label><span className="company-social-icon" style={{background:"#000"}}>X</span> X (Twitter)</label>
                        <input className="bk-input" value={company.twitter} onChange={e => setComp("twitter", e.target.value)} placeholder="https://x.com/yourhandle"/>
                      </div>
                      <div className="bk-field">
                        <label><span className="company-social-icon" style={{background:"#0A66C2"}}>in</span> LinkedIn</label>
                        <input className="bk-input" value={company.linkedin} onChange={e => setComp("linkedin", e.target.value)} placeholder="https://linkedin.com/company/..."/>
                      </div>
                    </div>
                  </div>
                </div>

                {/* ── Right column ── */}
                <div style={{display:"flex", flexDirection:"column", gap:20}}>
                  <div className="card settings-card">
                    <h4 className="company-section-h">Address visibility</h4>
                    <div style={{display:"flex", flexDirection:"column", gap:12}}>
                      <label className="mini-check">
                        <input type="checkbox" checked={!!company.hideEmail} onChange={() => setComp("hideEmail", !company.hideEmail)}/>
                        Don't show email on booking page
                      </label>
                      <label className="mini-check">
                        <input type="checkbox" checked={!!company.hideAddress} onChange={() => setComp("hideAddress", !company.hideAddress)}/>
                        Don't show address on booking page or in emails
                      </label>
                    </div>
                  </div>

                  <div className="card settings-card">
                    <h4 className="company-section-h">Location on map</h4>
                    <p className="section-sub" style={{marginTop:0, marginBottom:12}}>Search your address to pin your location for guests.</p>
                    <div className="map-search-row">
                      <input className="bk-input" placeholder="Search address…" value={mapQuery}
                        onChange={e => setMapQuery(e.target.value)}
                        onKeyDown={e => e.key === "Enter" && searchMap()}/>
                      <button className="btn primary" onClick={searchMap} disabled={mapBusy}>
                        {mapBusy ? "…" : <><I.location size={13}/> Search</>}
                      </button>
                    </div>
                    {mapErr && <div className="login-msg is-error" style={{marginTop:8, marginBottom:0}}>{mapErr}</div>}
                    <div className="map-frame-wrap">
                      <iframe className="map-frame" title="Location map" src={mapSrc} frameBorder="0" scrolling="no"/>
                    </div>
                    {company.companyLat && (
                      <div style={{fontSize:11, color:"var(--text-muted)", marginTop:8}}>
                        <I.check size={11}/> Location pinned · {Number(company.companyLat).toFixed(5)}, {Number(company.companyLon).toFixed(5)}
                      </div>
                    )}
                  </div>

                  <div style={{display:"flex", justifyContent:"flex-end"}}>
                    <button className="btn primary" onClick={saveCompany}>Save company information</button>
                  </div>
                </div>

              </div>
            </div>
          )}

          {tab === "notifications" && (
            <div className="settings-section">
              <h3 className="section-h">Notifications</h3>
              <p className="section-sub">Decide what reaches you and your guests.</p>
              <div className="card settings-card">
                {[
                  ["bookEmail",   "Email me on new bookings",      "Get an email the moment a guest books."],
                  ["bookSms",     "SMS me on new bookings",        "Quick alerts to your phone for each booking."],
                  ["cancelEmail", "Email me on cancellations",     "Know when a guest cancels or reschedules."],
                  ["reviews",     "Ask guests for a review",       "Lets you send a review request from each booking."],
                  ["marketing",   "Marketing tips & product news", "Occasional updates from Nexus Booking."],
                ].map(([k, t, d]) => (
                  <div key={k} className="notif-row">
                    <div>
                      <div className="title">{t}</div>
                      <div className="desc">{d}</div>
                    </div>
                    <label className="switch">
                      <input type="checkbox" checked={notifs[k]}
                        onChange={() => {
                          const next = {...notifs, [k]: !notifs[k]};
                          setNotifs(next);
                          actions.updateNotifications(next);
                        }}/>
                      <span className="track"><span className="knob"/></span>
                    </label>
                  </div>
                ))}

                {/* Reminders row with expandable config */}
                <div className="notif-row" style={{flexDirection:"column", alignItems:"stretch", gap:0}}>
                  <div style={{display:"flex", alignItems:"center", justifyContent:"space-between"}}>
                    <div>
                      <div className="title">Send reminders to guests</div>
                      <div className="desc">Automated appointment reminders sent before each booking.</div>
                    </div>
                    <label className="switch">
                      <input type="checkbox" checked={!!notifs.reminders}
                        onChange={() => {
                          const next = {...notifs, reminders: !notifs.reminders};
                          setNotifs(next);
                          actions.updateNotifications(next);
                        }}/>
                      <span className="track"><span className="knob"/></span>
                    </label>
                  </div>

                  {notifs.reminders && (
                    <div style={{marginTop:16, paddingTop:16, borderTop:"1px solid var(--border)", display:"flex", flexDirection:"column", gap:18}}>

                      {/* Timing */}
                      <div>
                        <div style={{fontSize:12, fontWeight:600, textTransform:"uppercase", letterSpacing:"0.05em", color:"var(--text-muted)", marginBottom:8}}>Reminder timing</div>
                        <div style={{display:"flex", gap:8, flexWrap:"wrap"}}>
                          {[["24h","24 hours before"],["1h","1 hour before"],["both","Both (24h + 1h)"]].map(([v, label]) => (
                            <button key={v}
                              className={"chip " + (reminderTiming === v ? "is-active" : "")}
                              onClick={() => {
                                setReminderTiming(v);
                                const next = {...notifs, reminderTiming: v};
                                setNotifs(next); actions.updateNotifications(next);
                              }}>{label}</button>
                          ))}
                        </div>
                      </div>

                      {/* Channels */}
                      <div>
                        <div style={{fontSize:12, fontWeight:600, textTransform:"uppercase", letterSpacing:"0.05em", color:"var(--text-muted)", marginBottom:8}}>Send via</div>
                        <div style={{display:"flex", gap:8, flexWrap:"wrap"}}>
                          {[["email","Email only"],["sms","SMS only"],["both","Email + SMS"],["whatsapp","WhatsApp"]].map(([v, label]) => (
                            <button key={v}
                              className={"chip " + (reminderChannels === v ? "is-active" : "")}
                              onClick={() => {
                                setReminderChannels(v);
                                const next = {...notifs, reminderChannels: v};
                                setNotifs(next); actions.updateNotifications(next);
                              }}>{label}</button>
                          ))}
                        </div>
                      </div>

                      {/* Email template */}
                      {(reminderChannels === "email" || reminderChannels === "both") && (
                        <div>
                          <div style={{fontSize:12, fontWeight:600, textTransform:"uppercase", letterSpacing:"0.05em", color:"var(--text-muted)", marginBottom:8}}>Email template</div>
                          <div style={{fontSize:11, color:"var(--text-muted)", marginBottom:8}}>Available variables: <code style={{background:"var(--surface-2)",padding:"1px 4px",borderRadius:3}}>{"{{guest_name}}"}</code> <code style={{background:"var(--surface-2)",padding:"1px 4px",borderRadius:3}}>{"{{service_name}}"}</code> <code style={{background:"var(--surface-2)",padding:"1px 4px",borderRadius:3}}>{"{{date}}"}</code> <code style={{background:"var(--surface-2)",padding:"1px 4px",borderRadius:3}}>{"{{time}}"}</code> <code style={{background:"var(--surface-2)",padding:"1px 4px",borderRadius:3}}>{"{{business_name}}"}</code></div>
                          <div className="bk-field" style={{marginBottom:10}}>
                            <label>Subject</label>
                            <input className="bk-input" value={reminderEmailSubject} onChange={e => setReminderEmailSubject(e.target.value)} placeholder="Email subject line"/>
                          </div>
                          <div className="bk-field">
                            <label>Message body</label>
                            <textarea className="bk-input" rows={5} style={{resize:"vertical"}} value={reminderEmailBody} onChange={e => setReminderEmailBody(e.target.value)}/>
                          </div>
                          <div style={{display:"flex",justifyContent:"flex-end",marginTop:8}}>
                            <button className="btn primary" style={{fontSize:12}} onClick={() => {
                              const next = {...notifs, reminderEmailSubject, reminderEmailBody};
                              setNotifs(next); actions.updateNotifications(next);
                            }}>Save email template</button>
                          </div>
                        </div>
                      )}

                      {/* SMS template */}
                      {(reminderChannels === "sms" || reminderChannels === "both") && (
                        <div>
                          <div style={{fontSize:12, fontWeight:600, textTransform:"uppercase", letterSpacing:"0.05em", color:"var(--text-muted)", marginBottom:8}}>SMS template</div>
                          <div style={{fontSize:11, color:"var(--text-muted)", marginBottom:8}}>Keep under 160 characters to send as a single SMS. Same variables as above.</div>
                          <div className="bk-field">
                            <label>SMS message <span style={{fontWeight:400, color:reminderSmsBody.length > 160 ? "var(--danger)" : "var(--text-faint)"}}>({reminderSmsBody.length} chars)</span></label>
                            <textarea className="bk-input" rows={3} style={{resize:"vertical"}} value={reminderSmsBody} onChange={e => setReminderSmsBody(e.target.value)}/>
                          </div>
                          <div style={{display:"flex",justifyContent:"flex-end",marginTop:8}}>
                            <button className="btn primary" style={{fontSize:12}} onClick={() => {
                              const next = {...notifs, reminderSmsBody};
                              setNotifs(next); actions.updateNotifications(next);
                            }}>Save SMS template</button>
                          </div>
                        </div>
                      )}
                    </div>
                  )}
                </div>
              </div>

              {/* Booking confirmation email template */}
              <div className="card settings-card" style={{marginTop:16}}>
                <h4 className="company-section-h">Booking confirmation</h4>
                <p className="section-sub" style={{marginTop:0,marginBottom:12}}>
                  Sent to guests immediately when they complete a booking. Use these variables: <code style={{fontSize:11}}>{"{{guest_name}}"}</code>, <code style={{fontSize:11}}>{"{{service_name}}"}</code>, <code style={{fontSize:11}}>{"{{date}}"}</code>, <code style={{fontSize:11}}>{"{{time}}"}</code>, <code style={{fontSize:11}}>{"{{business_name}}"}</code>.
                </p>
                <div style={{fontWeight:600, fontSize:13, marginBottom:10}}>Email</div>
                <div className="bk-field" style={{marginBottom:10}}>
                  <label>Subject</label>
                  <input className="bk-input" value={confirmEmailSubject} onChange={e => setConfirmEmailSubject(e.target.value)} placeholder="Email subject line"/>
                </div>
                <div className="bk-field">
                  <label>Message body</label>
                  <textarea className="bk-input" rows={6} style={{resize:"vertical"}} value={confirmEmailBody} onChange={e => setConfirmEmailBody(e.target.value)}/>
                </div>
                <div style={{display:"flex",justifyContent:"flex-end",marginTop:8,marginBottom:16}}>
                  <button className="btn primary" style={{fontSize:12}} onClick={() => {
                    const next = {...notifs, confirmEmailSubject, confirmEmailBody};
                    setNotifs(next); actions.updateNotifications(next);
                  }}>Save confirmation template</button>
                </div>
                <div style={{fontWeight:600, fontSize:13, marginBottom:10}}>SMS</div>
                <div style={{fontSize:11, color:"var(--text-muted)", marginBottom:8}}>Keep under 160 characters. Same variables as above.</div>
                <div className="bk-field">
                  <label>SMS message <span style={{fontWeight:400, color:confirmSmsBody.length > 160 ? "var(--danger)" : "var(--text-faint)"}}>({confirmSmsBody.length} chars)</span></label>
                  <textarea className="bk-input" rows={3} style={{resize:"vertical"}} value={confirmSmsBody} onChange={e => setConfirmSmsBody(e.target.value)}/>
                </div>
                <div style={{display:"flex",justifyContent:"flex-end",marginTop:8}}>
                  <button className="btn primary" style={{fontSize:12}} onClick={() => {
                    const next = {...notifs, confirmEmailSubject, confirmEmailBody, confirmSmsBody};
                    setNotifs(next); actions.updateNotifications(next);
                  }}>Save confirmation template</button>
                </div>
              </div>

              {/* Review link — shown when review notifications are enabled */}
              {notifs.reviews && (
                <div className="card settings-card" style={{marginTop:16}}>
                  <h4 className="company-section-h">Review link</h4>
                  <p className="section-sub" style={{marginTop:0,marginBottom:12}}>
                    Paste your Google Business or Trustpilot review URL. It will be included in review request emails you send from the Bookings view.
                  </p>
                  <div className="bk-field">
                    <label>Review URL</label>
                    <input className="bk-input" type="url" placeholder="https://g.page/r/... or https://www.trustpilot.com/review/..."
                      value={profileDraft.reviewLink || ""}
                      onChange={e => setProfile("reviewLink", e.target.value)}/>
                  </div>
                  <div style={{display:"flex",justifyContent:"flex-end",marginTop:4}}>
                    <button className="btn primary" onClick={() => actions.updateProfile({ ...profileDraft })}>Save</button>
                  </div>
                </div>
              )}
            </div>
          )}

          {tab === "policies" && (
            <div className="settings-section">
              <h3 className="section-h">Policies</h3>
              <p className="section-sub">Cancellation rules and booking page policy text shown to guests.</p>

              {/* Cancellation policy */}
              <div className="card settings-card" style={{marginBottom:24}}>
                <h4 className="company-section-h">Cancellation policy</h4>

                <div className="bk-field" style={{marginBottom:12}}>
                  <label>Minimum cancellation notice</label>
                  <div style={{display:"flex", gap:8, flexWrap:"wrap", marginBottom:8}}>
                    {[["None",0],["2h",2],["4h",4],["12h",12],["24h",24],["48h",48]].map(([label, val]) => (
                      <button key={val} className={"chip " + ((policy.minNoticeHours || 0) === val ? "is-active" : "")}
                        onClick={() => setPolicy("minNoticeHours", val)}>{label}</button>
                    ))}
                  </div>
                  <input className="bk-input" type="number" min={0} placeholder="Hours (0 = no restriction)"
                    value={policy.minNoticeHours ?? 0}
                    onChange={e => setPolicy("minNoticeHours", Number(e.target.value))}/>
                </div>

                <div className="bk-field" style={{marginBottom:12}}>
                  <label>Cancellation policy message</label>
                  <div style={{fontSize:11, color:"var(--text-muted)", marginBottom:6}}>Displayed on the booking page for guests to read.</div>
                  <textarea className="bk-input" rows={3} style={{resize:"vertical"}}
                    value={policy.cancellationMessage ?? "Cancellations must be made at least 24 hours in advance."}
                    onChange={e => setPolicy("cancellationMessage", e.target.value)}/>
                </div>

                <div className="bk-field" style={{marginBottom:12}}>
                  <div style={{display:"flex", alignItems:"center", justifyContent:"space-between"}}>
                    <label style={{marginBottom:0}}>Deposit is refundable on cancellation</label>
                    <button className={"toggle-btn " + (policy.depositRefundable ? "is-on" : "")}
                      onClick={() => setPolicy("depositRefundable", !policy.depositRefundable)}>
                      <span className="toggle-thumb"/>
                    </button>
                  </div>
                </div>

                <div className="bk-field" style={{marginBottom:16}}>
                  <label>No-show fee (if applicable)</label>
                  <input className="bk-input" type="number" min={0} placeholder="0.00"
                    value={policy.noShowFee ?? ""}
                    onChange={e => setPolicy("noShowFee", e.target.value ? Number(e.target.value) : "")}/>
                </div>

                <div style={{display:"flex", justifyContent:"flex-end"}}>
                  <button className="btn primary" onClick={() => actions.updateProfile({ ...data.profile, policy: { ...policy } })}>Save cancellation policy</button>
                </div>
              </div>

              {/* Booking page policies */}
              <div className="card settings-card">
                <h4 className="company-section-h">Booking page</h4>

                <div className="bk-field" style={{marginBottom:12}}>
                  <div style={{display:"flex", alignItems:"center", justifyContent:"space-between"}}>
                    <label style={{marginBottom:0}}>Require phone number at booking</label>
                    <button className={"toggle-btn " + (policy.requirePhone ? "is-on" : "")}
                      onClick={() => setPolicy("requirePhone", !policy.requirePhone)}>
                      <span className="toggle-thumb"/>
                    </button>
                  </div>
                </div>

                <div className="bk-field" style={{marginBottom:16}}>
                  <label>Terms &amp; conditions / booking policy</label>
                  <div style={{fontSize:11, color:"var(--text-muted)", marginBottom:6}}>Guests will see this text before confirming their booking.</div>
                  <textarea className="bk-input" rows={5} style={{resize:"vertical"}}
                    value={policy.termsText ?? ""}
                    onChange={e => setPolicy("termsText", e.target.value)}
                    placeholder="Enter your terms and conditions or booking policy…"/>
                </div>

                <div style={{display:"flex", justifyContent:"flex-end"}}>
                  <button className="btn primary" onClick={() => actions.updateProfile({ ...data.profile, policy: { ...policy } })}>Save booking page policies</button>
                </div>
              </div>
            </div>
          )}

          {tab === "security" && (
            <div className="settings-section">
              <h3 className="section-h">Security</h3>
              <p className="section-sub">Password, sessions, and two-factor authentication.</p>

              {/* ── Password ── */}
              <div className="card settings-card" style={{marginBottom:24}}>
                <div className="field-grid single">
                  <div className="bk-field">
                    <label>Current password</label>
                    <input className="bk-input" type="password" placeholder="Enter current password"
                      value={pwCurrent} onChange={e => { setPwCurrent(e.target.value); setPwMsg(null); }}/>
                  </div>
                  <div className="bk-field">
                    <label>New password</label>
                    <input className="bk-input" type="password" placeholder="At least 12 characters"
                      value={pwNew} onChange={e => { setPwNew(e.target.value); setPwMsg(null); }}
                      onKeyDown={e => e.key === "Enter" && updatePassword()}/>
                  </div>
                </div>
                {pwMsg && (
                  <div style={{
                    marginTop:10, fontSize:12, padding:"8px 12px", borderRadius:7,
                    background: pwMsg.type === "success" ? "rgba(16,185,129,.1)" : "rgba(208,39,44,.08)",
                    color:      pwMsg.type === "success" ? "#10b981"             : "#d0272c",
                    border:     `1px solid ${pwMsg.type === "success" ? "rgba(16,185,129,.25)" : "rgba(208,39,44,.2)"}`,
                  }}>
                    {pwMsg.text}
                  </div>
                )}
                <div style={{display:"flex", justifyContent:"flex-end", marginTop:12}}>
                  <button className="btn primary" style={{minWidth:140}} disabled={pwBusy} onClick={updatePassword}>
                    {pwBusy ? "Updating…" : "Update password"}
                  </button>
                </div>
              </div>

              {/* ── Two-factor authentication ── */}
              <h3 className="section-h" style={{marginBottom:4}}>Two-factor authentication</h3>
              <p className="section-sub" style={{marginBottom:16}}>Add a second verification step each time you sign in.</p>
              <div style={{display:"grid", gridTemplateColumns:"1fr 1fr", gap:16, marginBottom:24}}>

                {/* TOTP card */}
                {(() => {
                  const active = tfState.enabled && tfState.method === "totp";
                  return (
                    <div className="card settings-card" style={{display:"flex", flexDirection:"column", gap:12}}>
                      <div style={{display:"flex", alignItems:"flex-start", gap:12}}>
                        <div style={{width:38, height:38, borderRadius:10, background:"var(--surface-2)", display:"grid", placeItems:"center", flexShrink:0}}>
                          <I.cog size={18} style={{color:"var(--text-muted)"}}/>
                        </div>
                        <div style={{flex:1}}>
                          <div style={{display:"flex", alignItems:"center", gap:8, marginBottom:2}}>
                            <span style={{fontWeight:600, fontSize:14}}>Authenticator app</span>
                            {active && <span style={{fontSize:11, fontWeight:600, background:"var(--accent)", color:"#fff", padding:"1px 7px", borderRadius:20}}>Active</span>}
                          </div>
                          <div style={{fontSize:12, color:"var(--text-muted)", lineHeight:1.5}}>
                            Use Google Authenticator, Authy, or any TOTP app to generate a code.
                          </div>
                        </div>
                      </div>
                      <div style={{display:"flex", gap:8, justifyContent:"flex-end"}}>
                        {active
                          ? <button className="btn disconnect" style={{fontSize:12}} onClick={() => openMfa("disable")}>Remove</button>
                          : <button className="btn primary"    style={{fontSize:12}} onClick={() => openMfa("totp")}>Set up</button>
                        }
                      </div>
                    </div>
                  );
                })()}

                {/* Email OTP card */}
                {(() => {
                  const active = tfState.enabled && tfState.method === "email";
                  return (
                    <div className="card settings-card" style={{display:"flex", flexDirection:"column", gap:12}}>
                      <div style={{display:"flex", alignItems:"flex-start", gap:12}}>
                        <div style={{width:38, height:38, borderRadius:10, background:"var(--surface-2)", display:"grid", placeItems:"center", flexShrink:0}}>
                          <I.mail size={18} style={{color:"var(--text-muted)"}}/>
                        </div>
                        <div style={{flex:1}}>
                          <div style={{display:"flex", alignItems:"center", gap:8, marginBottom:2}}>
                            <span style={{fontWeight:600, fontSize:14}}>Email code</span>
                            {active && <span style={{fontSize:11, fontWeight:600, background:"var(--accent)", color:"#fff", padding:"1px 7px", borderRadius:20}}>Active</span>}
                          </div>
                          <div style={{fontSize:12, color:"var(--text-muted)", lineHeight:1.5}}>
                            We'll email a 6-digit code to {data.profile.email} each time you sign in.
                          </div>
                        </div>
                      </div>
                      <div style={{display:"flex", gap:8, justifyContent:"flex-end"}}>
                        {active
                          ? <button className="btn disconnect" style={{fontSize:12}} onClick={() => openMfa("disable")}>Remove</button>
                          : <button className="btn primary"    style={{fontSize:12}} onClick={() => openMfa("email")}>Set up</button>
                        }
                      </div>
                    </div>
                  );
                })()}
              </div>

              {/* ── Active sessions ── */}
              <div className="card settings-card">
                <div className="notif-row">
                  <div>
                    <div className="title">Active sessions</div>
                    <div className="desc">2 devices currently signed in.</div>
                  </div>
                  <button className="btn danger" onClick={actions.resetDemoData}>Reset demo data</button>
                </div>
              </div>

              {/* ── TOTP Setup Modal ── */}
              {mfaModal === "totp" && (
                <div className="modal-backdrop" onClick={e => e.target === e.currentTarget && closeMfa()}>
                  <div className="modal" style={{width:420}}>
                    <div className="modal-head">
                      <span className="modal-title">Set up authenticator app</span>
                      <button className="icon-btn" onClick={closeMfa}><I.x size={16}/></button>
                    </div>
                    <div className="modal-body">
                      {mfaStep === 1 && (<>
                        <p style={{fontSize:13, color:"var(--text-muted)", marginBottom:20, lineHeight:1.6}}>
                          Open your authenticator app (Google Authenticator, Authy, etc.) and scan the QR code below. Then enter the 6-digit code it shows.
                        </p>
                        {/* QR code placeholder */}
                        <div style={{display:"flex", justifyContent:"center", marginBottom:20}}>
                          <div style={{padding:12, background:"#fff", borderRadius:10, border:"1px solid var(--border)", display:"inline-block"}}>
                            <svg width="140" height="140" viewBox="0 0 29 29" xmlns="http://www.w3.org/2000/svg" shapeRendering="crispEdges">
                              {/* top-left finder */}
                              <rect x="0" y="0" width="7" height="7" fill="#111"/><rect x="1" y="1" width="5" height="5" fill="#fff"/><rect x="2" y="2" width="3" height="3" fill="#111"/>
                              {/* top-right finder */}
                              <rect x="22" y="0" width="7" height="7" fill="#111"/><rect x="23" y="1" width="5" height="5" fill="#fff"/><rect x="24" y="2" width="3" height="3" fill="#111"/>
                              {/* bottom-left finder */}
                              <rect x="0" y="22" width="7" height="7" fill="#111"/><rect x="1" y="23" width="5" height="5" fill="#fff"/><rect x="2" y="24" width="3" height="3" fill="#111"/>
                              {/* timing strips */}
                              <rect x="8" y="6" width="1" height="1" fill="#111"/><rect x="10" y="6" width="1" height="1" fill="#111"/><rect x="12" y="6" width="1" height="1" fill="#111"/>
                              <rect x="6" y="8" width="1" height="1" fill="#111"/><rect x="6" y="10" width="1" height="1" fill="#111"/><rect x="6" y="12" width="1" height="1" fill="#111"/>
                              {/* data modules (pseudo-random pattern) */}
                              <rect x="8"  y="8"  width="1" height="1" fill="#111"/><rect x="10" y="8"  width="1" height="1" fill="#111"/><rect x="13" y="8"  width="2" height="1" fill="#111"/>
                              <rect x="9"  y="9"  width="1" height="1" fill="#111"/><rect x="11" y="9"  width="2" height="1" fill="#111"/><rect x="15" y="9"  width="1" height="1" fill="#111"/>
                              <rect x="8"  y="10" width="2" height="1" fill="#111"/><rect x="12" y="10" width="1" height="1" fill="#111"/><rect x="14" y="10" width="2" height="1" fill="#111"/>
                              <rect x="9"  y="11" width="1" height="1" fill="#111"/><rect x="11" y="11" width="3" height="1" fill="#111"/><rect x="15" y="11" width="1" height="1" fill="#111"/>
                              <rect x="8"  y="12" width="1" height="1" fill="#111"/><rect x="10" y="12" width="2" height="1" fill="#111"/><rect x="13" y="12" width="3" height="1" fill="#111"/>
                              <rect x="16" y="8"  width="3" height="1" fill="#111"/><rect x="20" y="8"  width="1" height="1" fill="#111"/>
                              <rect x="17" y="9"  width="1" height="1" fill="#111"/><rect x="19" y="9"  width="2" height="1" fill="#111"/>
                              <rect x="16" y="10" width="2" height="1" fill="#111"/><rect x="20" y="10" width="1" height="1" fill="#111"/>
                              <rect x="17" y="11" width="3" height="1" fill="#111"/><rect x="21" y="11" width="1" height="1" fill="#111"/>
                              <rect x="16" y="12" width="1" height="1" fill="#111"/><rect x="18" y="12" width="2" height="1" fill="#111"/>
                              <rect x="8"  y="16" width="2" height="1" fill="#111"/><rect x="11" y="16" width="1" height="1" fill="#111"/><rect x="13" y="16" width="3" height="1" fill="#111"/>
                              <rect x="9"  y="17" width="1" height="1" fill="#111"/><rect x="12" y="17" width="2" height="1" fill="#111"/><rect x="15" y="17" width="1" height="1" fill="#111"/>
                              <rect x="8"  y="18" width="1" height="1" fill="#111"/><rect x="10" y="18" width="3" height="1" fill="#111"/><rect x="14" y="18" width="2" height="1" fill="#111"/>
                              <rect x="16" y="16" width="1" height="1" fill="#111"/><rect x="18" y="16" width="2" height="1" fill="#111"/><rect x="21" y="16" width="1" height="1" fill="#111"/>
                              <rect x="17" y="17" width="3" height="1" fill="#111"/><rect x="20" y="17" width="2" height="1" fill="#111"/>
                              <rect x="16" y="18" width="2" height="1" fill="#111"/><rect x="19" y="18" width="1" height="1" fill="#111"/><rect x="21" y="18" width="1" height="1" fill="#111"/>
                              <rect x="8"  y="20" width="3" height="1" fill="#111"/><rect x="12" y="20" width="1" height="1" fill="#111"/><rect x="14" y="20" width="2" height="1" fill="#111"/>
                              <rect x="9"  y="21" width="1" height="1" fill="#111"/><rect x="11" y="21" width="2" height="1" fill="#111"/><rect x="16" y="20" width="2" height="1" fill="#111"/>
                              <rect x="18" y="21" width="3" height="1" fill="#111"/><rect x="20" y="20" width="1" height="1" fill="#111"/>
                            </svg>
                          </div>
                        </div>
                        <p style={{fontSize:11, color:"var(--text-muted)", textAlign:"center", marginBottom:20}}>
                          Can't scan? Enter this key manually: <strong style={{fontFamily:"monospace", letterSpacing:2}}>NXUS BOOK DEMO KEY1</strong>
                        </p>
                        <div className="bk-field" style={{marginBottom:mfaErr ? 8 : 0}}>
                          <label>Verification code</label>
                          <input className="bk-input" placeholder="Enter the 6-digit code" maxLength={6}
                            value={mfaCode} onChange={e => { setMfaCode(e.target.value.replace(/\D/g,"")); setMfaErr(""); }}
                            onKeyDown={e => e.key === "Enter" && simulateVerify(() => enableTwoFactor("totp"))}
                          />
                        </div>
                        {mfaErr && <p style={{fontSize:12, color:"#d0272c", marginBottom:8}}>{mfaErr}</p>}
                      </>)}
                      {mfaStep === 3 && (
                        <div style={{textAlign:"center", padding:"16px 0 8px"}}>
                          <div style={{width:52, height:52, borderRadius:"50%", background:"#10b981", display:"grid", placeItems:"center", margin:"0 auto 16px"}}>
                            <I.check size={24} style={{color:"#fff"}}/>
                          </div>
                          <div style={{fontWeight:600, fontSize:15, marginBottom:6}}>Authenticator app enabled</div>
                          <div style={{fontSize:13, color:"var(--text-muted)"}}>You'll need your app each time you sign in.</div>
                        </div>
                      )}
                    </div>
                    <div className="modal-foot">
                      {mfaStep === 1 && <>
                        <button className="btn ghost" onClick={closeMfa}>Cancel</button>
                        <button className="btn primary" disabled={mfaCode.length < 6 || mfaBusy}
                          onClick={() => simulateVerify(() => enableTwoFactor("totp"))}>
                          {mfaBusy ? "Verifying…" : "Verify & enable"}
                        </button>
                      </>}
                      {mfaStep === 3 && <button className="btn primary" style={{marginLeft:"auto"}} onClick={closeMfa}>Done</button>}
                    </div>
                  </div>
                </div>
              )}

              {/* ── Email OTP Setup Modal ── */}
              {mfaModal === "email" && (
                <div className="modal-backdrop" onClick={e => e.target === e.currentTarget && closeMfa()}>
                  <div className="modal" style={{width:400}}>
                    <div className="modal-head">
                      <span className="modal-title">Set up email verification</span>
                      <button className="icon-btn" onClick={closeMfa}><I.x size={16}/></button>
                    </div>
                    <div className="modal-body">
                      {mfaStep === 1 && (
                        <div style={{textAlign:"center", padding:"8px 0 4px"}}>
                          <div style={{width:48, height:48, borderRadius:12, background:"var(--surface-2)", display:"grid", placeItems:"center", margin:"0 auto 16px"}}>
                            <I.mail size={22} style={{color:"var(--accent)"}}/>
                          </div>
                          <div style={{fontWeight:600, fontSize:14, marginBottom:8}}>Send a verification code</div>
                          <p style={{fontSize:13, color:"var(--text-muted)", lineHeight:1.6, marginBottom:0}}>
                            We'll send a 6-digit code to <strong>{data.profile.email}</strong>. Enter it on the next step to confirm your email and enable this method.
                          </p>
                        </div>
                      )}
                      {mfaStep === 2 && (<>
                        <p style={{fontSize:13, color:"var(--text-muted)", marginBottom:20, lineHeight:1.6}}>
                          A code was sent to <strong>{data.profile.email}</strong>. Enter it below. It expires in 10 minutes.
                        </p>
                        <div className="bk-field" style={{marginBottom: mfaErr ? 8 : 0}}>
                          <label>Verification code</label>
                          <input className="bk-input" placeholder="Enter the 6-digit code" maxLength={6}
                            value={mfaCode} onChange={e => { setMfaCode(e.target.value.replace(/\D/g,"")); setMfaErr(""); }}
                            onKeyDown={e => e.key === "Enter" && simulateVerify(() => enableTwoFactor("email"))}
                            autoFocus
                          />
                        </div>
                        {mfaErr && <p style={{fontSize:12, color:"#d0272c", marginBottom:0}}>{mfaErr}</p>}
                        <p style={{fontSize:12, color:"var(--text-muted)", marginTop:10, marginBottom:0}}>
                          Didn't receive it?{" "}
                          <span style={{color:"var(--accent)", cursor:"pointer", textDecoration:"underline"}}
                            onClick={() => { setEmailSent(false); setMfaStep(1); }}>
                            Resend
                          </span>
                        </p>
                      </>)}
                      {mfaStep === 3 && (
                        <div style={{textAlign:"center", padding:"16px 0 8px"}}>
                          <div style={{width:52, height:52, borderRadius:"50%", background:"#10b981", display:"grid", placeItems:"center", margin:"0 auto 16px"}}>
                            <I.check size={24} style={{color:"#fff"}}/>
                          </div>
                          <div style={{fontWeight:600, fontSize:15, marginBottom:6}}>Email verification enabled</div>
                          <div style={{fontSize:13, color:"var(--text-muted)"}}>A code will be sent to your email each time you sign in.</div>
                        </div>
                      )}
                    </div>
                    <div className="modal-foot">
                      {mfaStep === 1 && <>
                        <button className="btn ghost" onClick={closeMfa}>Cancel</button>
                        <button className="btn primary" disabled={mfaBusy} onClick={() => { setMfaBusy(true); setTimeout(() => { setMfaBusy(false); setEmailSent(true); setMfaStep(2); }, 800); }}>
                          {mfaBusy ? "Sending…" : "Send code"}
                        </button>
                      </>}
                      {mfaStep === 2 && <>
                        <button className="btn ghost" onClick={closeMfa}>Cancel</button>
                        <button className="btn primary" disabled={mfaCode.length < 6 || mfaBusy}
                          onClick={() => simulateVerify(() => enableTwoFactor("email"))}>
                          {mfaBusy ? "Verifying…" : "Verify & enable"}
                        </button>
                      </>}
                      {mfaStep === 3 && <button className="btn primary" style={{marginLeft:"auto"}} onClick={closeMfa}>Done</button>}
                    </div>
                  </div>
                </div>
              )}

              {/* ── Disable Confirm Modal ── */}
              {mfaModal === "disable" && (
                <div className="modal-backdrop" onClick={e => e.target === e.currentTarget && closeMfa()}>
                  <div className="modal" style={{width:380}}>
                    <div className="modal-head">
                      <span className="modal-title">Remove two-factor authentication</span>
                      <button className="icon-btn" onClick={closeMfa}><I.x size={16}/></button>
                    </div>
                    <div className="modal-body">
                      <p style={{fontSize:13, color:"var(--text-muted)", lineHeight:1.6, margin:0}}>
                        This will remove your current 2FA method. Your account will only be protected by your password. Are you sure?
                      </p>
                    </div>
                    <div className="modal-foot">
                      <button className="btn ghost" onClick={closeMfa}>Cancel</button>
                      <button className="btn disconnect" onClick={disableTwoFactor}>Remove</button>
                    </div>
                  </div>
                </div>
              )}
            </div>
          )}

          {tab === "embed" && (() => {
            const slug = data.profile.bookingUrl || "";
            const accent = data.profile.accent || "#006e78";
            const snippets = {
              floating: `<script src="https://book.nexusbookings.app/embed.js"\n  data-user="${slug}"\n  data-color="${accent}"\n  data-text="Book now"\n  data-position="bottom-right">\n</script>`,
              inline:   `<!-- Add this attribute to any button on your page -->\n<button data-nexus-open>Book appointment</button>\n\n<!-- Then add this once, anywhere in the page -->\n<script src="https://book.nexusbookings.app/embed.js" data-user="${slug}"></script>`,
              link:     `https://book.nexusbookings.app/${slug}`,
              calendar: `<div style="display:flex;gap:16px;max-width:1100px;height:620px">\n  <iframe\n    src="https://book.nexusbookings.app/${slug}?embed=calendar"\n    style="flex:2;height:100%;border:none;border-radius:12px;box-shadow:0 2px 12px rgba(0,0,0,.08)"\n    frameborder="0" loading="lazy">\n  </iframe>\n  <iframe\n    src="https://book.nexusbookings.app/${slug}?embed=events"\n    style="flex:1;height:100%;border:none;border-radius:12px;box-shadow:0 2px 12px rgba(0,0,0,.08)"\n    frameborder="0" loading="lazy">\n  </iframe>\n</div>`,
            };

            // ── Inline SVG previews ────────────────────────────────────────
            const PreviewFloating = () => (
              <svg viewBox="0 0 320 180" xmlns="http://www.w3.org/2000/svg" style={{width:"100%",height:"100%"}}>
                {/* Browser chrome */}
                <rect width="320" height="180" rx="8" fill="#f4f4f5"/>
                <rect width="320" height="28" rx="8" fill="#e4e4e7"/>
                <rect x="8" y="9" width="10" height="10" rx="5" fill="#ef4444" opacity=".7"/>
                <rect x="24" y="9" width="10" height="10" rx="5" fill="#f59e0b" opacity=".7"/>
                <rect x="40" y="9" width="10" height="10" rx="5" fill="#22c55e" opacity=".7"/>
                <rect x="60" y="6" width="200" height="16" rx="4" fill="#d4d4d8"/>
                {/* Page content lines */}
                <rect x="16" y="44" width="120" height="8" rx="3" fill="#d4d4d8" opacity=".6"/>
                <rect x="16" y="58" width="80" height="6" rx="3" fill="#d4d4d8" opacity=".4"/>
                <rect x="16" y="78" width="288" height="5" rx="2" fill="#d4d4d8" opacity=".3"/>
                <rect x="16" y="88" width="260" height="5" rx="2" fill="#d4d4d8" opacity=".3"/>
                <rect x="16" y="98" width="272" height="5" rx="2" fill="#d4d4d8" opacity=".3"/>
                {/* Floating button bottom-right */}
                <rect x="218" y="142" width="86" height="28" rx="14" fill={accent}/>
                <text x="261" y="160" textAnchor="middle" fill="white" fontSize="9" fontWeight="600" fontFamily="sans-serif">Book now</text>
                {/* Popup shadow hint */}
                <rect x="180" y="48" width="124" height="86" rx="8" fill="white" opacity=".95" stroke="#d4d4d8" strokeWidth=".8"/>
                <rect x="192" y="58" width="60" height="6" rx="2" fill="#d4d4d8" opacity=".6"/>
                <rect x="192" y="70" width="100" height="5" rx="2" fill="#d4d4d8" opacity=".4"/>
                <rect x="192" y="80" width="80" height="5" rx="2" fill="#d4d4d8" opacity=".4"/>
                <rect x="192" y="100" width="70" height="18" rx="5" fill={accent} opacity=".9"/>
                <text x="227" y="113" textAnchor="middle" fill="white" fontSize="7.5" fontFamily="sans-serif">Book →</text>
              </svg>
            );
            const PreviewInline = () => (
              <svg viewBox="0 0 320 180" xmlns="http://www.w3.org/2000/svg" style={{width:"100%",height:"100%"}}>
                <rect width="320" height="180" rx="8" fill="#f4f4f5"/>
                <rect width="320" height="28" rx="8" fill="#e4e4e7"/>
                <rect x="8" y="9" width="10" height="10" rx="5" fill="#ef4444" opacity=".7"/>
                <rect x="24" y="9" width="10" height="10" rx="5" fill="#f59e0b" opacity=".7"/>
                <rect x="40" y="9" width="10" height="10" rx="5" fill="#22c55e" opacity=".7"/>
                <rect x="60" y="6" width="200" height="16" rx="4" fill="#d4d4d8"/>
                {/* Hero text */}
                <rect x="80" y="42" width="160" height="12" rx="4" fill="#3f3f46" opacity=".7"/>
                <rect x="100" y="60" width="120" height="7" rx="3" fill="#d4d4d8" opacity=".5"/>
                <rect x="110" y="72" width="100" height="7" rx="3" fill="#d4d4d8" opacity=".4"/>
                {/* CTA button inline */}
                <rect x="108" y="94" width="104" height="30" rx="8" fill={accent}/>
                <text x="160" y="113" textAnchor="middle" fill="white" fontSize="9.5" fontWeight="600" fontFamily="sans-serif">Book appointment</text>
                {/* Body lines below */}
                <rect x="16" y="140" width="288" height="5" rx="2" fill="#d4d4d8" opacity=".3"/>
                <rect x="16" y="150" width="240" height="5" rx="2" fill="#d4d4d8" opacity=".3"/>
                <rect x="16" y="160" width="260" height="5" rx="2" fill="#d4d4d8" opacity=".3"/>
              </svg>
            );
            const PreviewLink = () => (
              <svg viewBox="0 0 320 180" xmlns="http://www.w3.org/2000/svg" style={{width:"100%",height:"100%"}}>
                <rect width="320" height="180" rx="8" fill="#f4f4f5"/>
                <rect width="320" height="28" rx="8" fill="#e4e4e7"/>
                <rect x="8" y="9" width="10" height="10" rx="5" fill="#ef4444" opacity=".7"/>
                <rect x="24" y="9" width="10" height="10" rx="5" fill="#f59e0b" opacity=".7"/>
                <rect x="40" y="9" width="10" height="10" rx="5" fill="#22c55e" opacity=".7"/>
                {/* URL bar with link */}
                <rect x="56" y="5" width="248" height="18" rx="4" fill="white" stroke="#d4d4d8" strokeWidth=".8"/>
                <text x="68" y="17" fill={accent} fontSize="8.5" fontFamily="monospace">book.nexusbookings.app/{slug||"your-slug"}</text>
                {/* Full booking page */}
                <rect x="8" y="36" width="304" height="136" rx="6" fill="white" stroke="#e4e4e7" strokeWidth=".8"/>
                {/* Page header */}
                <rect x="20" y="46" width="90" height="10" rx="3" fill="#3f3f46" opacity=".6"/>
                <rect x="20" y="62" width="60" height="6" rx="2" fill="#d4d4d8" opacity=".5"/>
                {/* Calendar grid mock */}
                <rect x="20" y="76" width="180" height="88" rx="5" fill="#f9f9fb" stroke="#e4e4e7" strokeWidth=".6"/>
                {[0,1,2,3,4,5,6].map(col => [0,1,2,3,4].map(row => {
                  const x = 26 + col*24, y = 82 + row*16;
                  const isAccent = (col===2&&row===1)||(col===4&&row===2)||(col===1&&row===3);
                  return <rect key={`${col}-${row}`} x={x} y={y} width="18" height="12" rx="3" fill={isAccent?accent:"#ececec"} opacity={isAccent?1:.6}/>;
                }))}
                {/* Services list mock */}
                <rect x="212" y="76" width="92" height="88" rx="5" fill="#f9f9fb" stroke="#e4e4e7" strokeWidth=".6"/>
                {[0,1,2].map(i => (
                  <React.Fragment key={i}>
                    <rect x="220" y={86+i*26} width="76" height="18" rx="4" fill="white" stroke="#e4e4e7" strokeWidth=".6"/>
                    <rect x="226" y={90+i*26} width="40" height="5" rx="2" fill="#3f3f46" opacity=".5"/>
                    <rect x="226" y={99+i*26} width="28" height="3" rx="1" fill="#d4d4d8" opacity=".5"/>
                  </React.Fragment>
                ))}
              </svg>
            );
            const PreviewCalendar = () => (
              <svg viewBox="0 0 320 180" xmlns="http://www.w3.org/2000/svg" style={{width:"100%",height:"100%"}}>
                <rect width="320" height="180" rx="8" fill="#f4f4f5"/>
                <rect width="320" height="28" rx="8" fill="#e4e4e7"/>
                <rect x="8" y="9" width="10" height="10" rx="5" fill="#ef4444" opacity=".7"/>
                <rect x="24" y="9" width="10" height="10" rx="5" fill="#f59e0b" opacity=".7"/>
                <rect x="40" y="9" width="10" height="10" rx="5" fill="#22c55e" opacity=".7"/>
                <rect x="60" y="6" width="200" height="16" rx="4" fill="#d4d4d8"/>
                {/* Left panel — calendar (2/3) */}
                <rect x="8" y="36" width="196" height="136" rx="7" fill="white" stroke="#e4e4e7" strokeWidth=".8"/>
                {/* Cal header */}
                <rect x="16" y="44" width="60" height="8" rx="3" fill="#3f3f46" opacity=".55"/>
                <rect x="170" y="43" width="16" height="10" rx="3" fill="#e4e4e7"/>
                <rect x="152" y="43" width="16" height="10" rx="3" fill="#e4e4e7"/>
                {/* Day labels */}
                {["M","T","W","T","F","S","S"].map((d,i) => (
                  <text key={i} x={18+i*26} y={64} fontSize="6.5" fill="#a1a1aa" fontFamily="sans-serif" fontWeight="600">{d}</text>
                ))}
                {/* Calendar cells */}
                {[0,1,2,3,4].map(row => [0,1,2,3,4,5,6].map(col => {
                  const x = 14+col*26, y = 68+row*18;
                  const isToday = col===2&&row===1;
                  const hasDot  = (col===0&&row===2)||(col===4&&row===0)||(col===6&&row===3);
                  return (
                    <React.Fragment key={`${col}-${row}`}>
                      <rect x={x} y={y} width="20" height="14" rx="3" fill={isToday?accent:"transparent"}/>
                      <text x={x+10} y={y+9.5} textAnchor="middle" fontSize="6" fill={isToday?"white":"#52525b"} fontFamily="sans-serif">{row*7+col+1}</text>
                      {hasDot && <circle cx={x+10} cy={y+13} r="1.5" fill={accent} opacity=".7"/>}
                    </React.Fragment>
                  );
                }))}
                {/* Right panel — events (1/3) */}
                <rect x="212" y="36" width="100" height="136" rx="7" fill="white" stroke="#e4e4e7" strokeWidth=".8"/>
                <rect x="220" y="44" width="60" height="7" rx="2" fill="#3f3f46" opacity=".55"/>
                <rect x="220" y="55" width="40" height="4" rx="1" fill="#d4d4d8" opacity=".5"/>
                {[0,1,2,3,4].map(i => (
                  <React.Fragment key={i}>
                    <rect x="218" y={68+i*20} width="86" height="16" rx="4" fill="#f4f4f5" stroke="#e4e4e7" strokeWidth=".5"/>
                    <rect x="222" y={72+i*20} width="3" height="8" rx="1" fill={accent}/>
                    <rect x="228" y={72+i*20} width="38" height="4" rx="1" fill="#3f3f46" opacity=".5"/>
                    <rect x="228" y={79+i*20} width="26" height="3" rx="1" fill="#a1a1aa" opacity=".6"/>
                  </React.Fragment>
                ))}
              </svg>
            );

            const copy = () => {
              navigator.clipboard?.writeText(snippets[activeSnippet]).catch(() => {});
              setEmbedCopied(true);
              setTimeout(() => setEmbedCopied(false), 2000);
            };

            const TABS = [
              { id: "floating", label: "Floating button" },
              { id: "inline",   label: "Custom button"  },
              { id: "link",     label: "Direct link"    },
              { id: "calendar", label: "Calendar widget"},
            ];
            const DESCRIPTIONS = {
              floating: `A "Book now" button appears fixed to the bottom-right corner of your page. Clicking it opens the booking flow in a smooth popup.`,
              inline:   `Attach the booking popup to any existing button or link on your site using the data-nexus-open attribute.`,
              link:     `Link directly to your public booking page. Open it in a new tab, share in an email, or drop it anywhere.`,
              calendar: `Embeds a full calendar on the left (2/3 width) alongside your 5 upcoming services stacked on the right (1/3 width). Great for service pages.`,
            };
            const PREVIEWS = { floating: PreviewFloating, inline: PreviewInline, link: PreviewLink, calendar: PreviewCalendar };
            const Preview  = PREVIEWS[activeSnippet];

            return (
              <div className="settings-section">
                <h3 className="section-h">Embed on your website</h3>
                <p className="section-sub">Add your booking widget to any website — WordPress, Squarespace, Wix, Webflow, or a custom site. Paste a single snippet and you're live.</p>

                <div className="card settings-card" style={{padding:0,overflow:"hidden"}}>
                  {/* Tab selector */}
                  <div style={{display:"flex",borderBottom:"1px solid var(--border)"}}>
                    {TABS.map(t => (
                      <button key={t.id}
                        onClick={() => { setActiveSnippet(t.id); setEmbedCopied(false); }}
                        style={{
                          flex:1, padding:"12px 12px", fontSize:12.5, fontWeight:500,
                          background: activeSnippet===t.id ? "var(--surface-2)" : "transparent",
                          color: activeSnippet===t.id ? "var(--text)" : "var(--text-muted)",
                          border:"none", borderBottom: activeSnippet===t.id ? "2px solid var(--accent)" : "2px solid transparent",
                          cursor:"pointer", transition:"all .15s",
                        }}>
                        {t.label}
                      </button>
                    ))}
                  </div>

                  <div style={{padding:"20px 24px", display:"flex", flexDirection:"column", gap:16}}>
                    {/* Preview + description row */}
                    <div style={{display:"flex", gap:20, alignItems:"flex-start"}}>
                      {/* Visual preview */}
                      <div style={{flex:"0 0 260px", border:"1px solid var(--border)", borderRadius:10, overflow:"hidden", background:"var(--surface-2)", aspectRatio:"16/9", display:"flex", alignItems:"stretch"}}>
                        <Preview/>
                      </div>
                      {/* Description */}
                      <div style={{flex:1, display:"flex", flexDirection:"column", gap:10, paddingTop:4}}>
                        <p style={{margin:0, fontSize:13, color:"var(--text)", lineHeight:1.6}}>
                          {DESCRIPTIONS[activeSnippet]}
                        </p>
                        {activeSnippet === "floating" && (
                          <div style={{fontSize:12, color:"var(--text-muted)", lineHeight:1.7}}>
                            Customise with:<br/>
                            <code style={{fontSize:11}}>data-position="bottom-left"</code><br/>
                            <code style={{fontSize:11}}>data-text="Schedule a call"</code><br/>
                            <code style={{fontSize:11}}>data-color="#your-hex"</code>
                          </div>
                        )}
                        {activeSnippet === "calendar" && (
                          <div style={{fontSize:12, color:"var(--text-muted)", lineHeight:1.7}}>
                            Adjust height by changing <code style={{fontSize:11}}>height:620px</code> on the wrapper div. Works on any site that accepts HTML blocks.
                          </div>
                        )}
                        {activeSnippet === "link" && (
                          <a href={`https://book.nexusbookings.app/${slug}`} target="_blank" rel="noopener noreferrer"
                            style={{fontSize:12, color:"var(--accent)", display:"inline-flex", alignItems:"center", gap:4, textDecoration:"none"}}>
                            <I.arrow size={11} style={{transform:"rotate(-45deg)"}}/>
                            Open your booking page
                          </a>
                        )}
                      </div>
                    </div>

                    {/* Code block */}
                    <div style={{position:"relative",background:"var(--surface-2)",borderRadius:10,border:"1px solid var(--border)"}}>
                      <pre style={{margin:0,padding:"16px 20px",fontSize:12,fontFamily:"'SF Mono','Fira Mono','Consolas',monospace",color:"var(--text)",overflowX:"auto",whiteSpace:"pre-wrap",wordBreak:"break-all",lineHeight:1.6}}>
                        {snippets[activeSnippet]}
                      </pre>
                      <button
                        onClick={copy}
                        style={{position:"absolute",top:10,right:10,padding:"5px 12px",fontSize:12,fontWeight:500,background:embedCopied?"rgba(34,197,94,.15)":"var(--surface)",color:embedCopied?"#22c55e":"var(--text-muted)",border:"1px solid var(--border)",borderRadius:6,cursor:"pointer",display:"flex",alignItems:"center",gap:5}}>
                        {embedCopied ? <><I.check size={12}/> Copied!</> : <><I.copy size={12}/> Copy</>}
                      </button>
                    </div>

                    {/* Paste instruction */}
                    {activeSnippet !== "link" && (
                      <div style={{display:"flex",alignItems:"flex-start",gap:10,padding:"12px 14px",background:"var(--accent-soft)",borderRadius:8,border:"1px solid var(--accent)",fontSize:12.5,color:"var(--text)"}}>
                        <I.bolt size={14} style={{color:"var(--accent)",flexShrink:0,marginTop:1}}/>
                        <span>
                          {activeSnippet === "calendar"
                            ? "Paste this HTML block wherever you want the widget to appear on your page."
                            : <>Paste this snippet before the <code style={{fontSize:11,background:"rgba(0,0,0,.08)",padding:"1px 4px",borderRadius:3}}>{"</body>"}</code> tag. Works on any platform that allows custom HTML.</>
                          }
                        </span>
                      </div>
                    )}
                  </div>
                </div>
              </div>
            );
          })()}
        </div>
      </div>
    </>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Block Time Modal
// ──────────────────────────────────────────────────────────────────────────
const BLOCK_TIME_SLOTS = ["07:00","07:30","08:00","08:30","09:00","09:30","10:00","10:30","11:00","11:30","12:00","12:30","13:00","13:30","14:00","14:30","15:00","15:30","16:00","16:30","17:00","17:30","18:00","18:30","19:00","19:30","20:00"];

function BlockTimeModal({ onClose, onSave }) {
  const today = new Date().toISOString().slice(0, 10);
  const [date,      setDate]      = React.useState(today);
  const [startTime, setStartTime] = React.useState("09:00");
  const [endTime,   setEndTime]   = React.useState("10:00");
  const [label,     setLabel]     = React.useState("");
  const [saving,    setSaving]    = React.useState(false);

  const handleSave = async () => {
    if (!date || !startTime || !endTime) return;
    setSaving(true);
    const id = typeof uid === "function" ? uid("blk") : "blk-" + Math.random().toString(36).slice(2);
    await onSave({ id, date, startTime, endTime, label });
    setSaving(false);
    onClose();
  };

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal-card" style={{maxWidth:420}} onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <div>
            <h3 style={{margin:0}}>Block time</h3>
            <span className="sub" style={{fontSize:12}}>Mark a period as unavailable for bookings</span>
          </div>
          <button className="modal-close" onClick={onClose}><I.x size={14}/></button>
        </div>
        <div className="modal-body">
          <div className="field-grid">
            <div className="bk-field" style={{gridColumn:"1 / -1"}}>
              <label>Date</label>
              <input type="date" className="bk-input" value={date} onChange={e => setDate(e.target.value)}/>
            </div>
            <div className="bk-field">
              <label>Start time</label>
              <select className="bk-input" value={startTime} onChange={e => setStartTime(e.target.value)}>
                {BLOCK_TIME_SLOTS.map(t => <option key={t} value={t}>{t}</option>)}
              </select>
            </div>
            <div className="bk-field">
              <label>End time</label>
              <select className="bk-input" value={endTime} onChange={e => setEndTime(e.target.value)}>
                {BLOCK_TIME_SLOTS.map(t => <option key={t} value={t}>{t}</option>)}
              </select>
            </div>
            <div className="bk-field" style={{gridColumn:"1 / -1"}}>
              <label>Label</label>
              <input className="bk-input" value={label} onChange={e => setLabel(e.target.value)} placeholder="e.g. Lunch break, Holiday"/>
            </div>
          </div>
        </div>
        <div className="modal-foot">
          <button className="btn ghost" onClick={onClose}>Cancel</button>
          <button className="btn primary" onClick={handleSave} disabled={saving || !date || !startTime || !endTime}>
            {saving ? "Saving…" : "Block time"}
          </button>
        </div>
      </div>
    </div>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Calendar
// ──────────────────────────────────────────────────────────────────────────
function ViewCalendar({ data }) {
  const today = todayIso();
  const [current, setCurrent] = React.useState(() => {
    const d = new Date();
    return { year: d.getFullYear(), month: d.getMonth() };
  });
  const [selected,       setSelected]       = React.useState(today);
  const [showBlockModal, setShowBlockModal] = React.useState(false);
  const [blockedTimes,   setBlockedTimes]   = React.useState(data.blockedTimes || []);

  const firstDay   = new Date(current.year, current.month, 1);
  const daysInMonth = new Date(current.year, current.month + 1, 0).getDate();
  const startDow   = (firstDay.getDay() + 6) % 7; // 0 = Monday

  const bookingsByDate = React.useMemo(() => {
    const map = {};
    data.bookings.forEach(b => {
      if (!b.date) return;
      if (!map[b.date]) map[b.date] = [];
      map[b.date].push(b);
    });
    return map;
  }, [data.bookings]);

  const blockedByDate = React.useMemo(() => {
    const map = {};
    blockedTimes.forEach(b => {
      if (!b.date) return;
      if (!map[b.date]) map[b.date] = [];
      map[b.date].push(b);
    });
    return map;
  }, [blockedTimes]);

  const cells = [];
  for (let i = 0; i < startDow; i++) cells.push(null);
  for (let d = 1; d <= daysInMonth; d++) {
    cells.push(`${current.year}-${String(current.month + 1).padStart(2, "0")}-${String(d).padStart(2, "0")}`);
  }

  const monthLabel = new Date(current.year, current.month).toLocaleDateString("en-GB", { month: "long", year: "numeric" });
  const prev = () => setCurrent(c => c.month === 0  ? { year: c.year - 1, month: 11 } : { ...c, month: c.month - 1 });
  const next = () => setCurrent(c => c.month === 11 ? { year: c.year + 1, month: 0  } : { ...c, month: c.month + 1 });
  const goToday = () => { const d = new Date(); setCurrent({ year: d.getFullYear(), month: d.getMonth() }); setSelected(today); };

  const selectedBookings = (bookingsByDate[selected] || [])
    .filter(b => b.status !== "Cancelled")
    .sort((a, b) => a.time.localeCompare(b.time));
  const selectedBlocks = (blockedByDate[selected] || []).sort((a, b) => a.startTime.localeCompare(b.startTime));

  const getEventColor = (bk) => {
    const ev = data.events.find(e => e.id === bk.eventId || e.name === bk.eventName);
    return ev?.color || "var(--accent)";
  };

  return (
    <>
      <div className="view-h">
        <div>
          <h1>Calendar</h1>
          <div className="sub">All classes and bookings by day.</div>
        </div>
        <div className="view-actions">
          <button className="btn ghost" onClick={goToday}>Today</button>
          <button className="btn primary" style={{gap:6}} onClick={() => setShowBlockModal(true)}><I.lock size={13}/> Block time</button>
        </div>
      </div>

      {showBlockModal && (
        <BlockTimeModal
          onClose={() => setShowBlockModal(false)}
          onSave={async (block) => {
            setBlockedTimes(bt => [...bt, block]);
          }}
        />
      )}

      <div className="cal-layout">
        {/* ── Month grid ── */}
        <div className="card cal-card">
          <div className="cal-nav">
            <button className="icon-btn" onClick={prev}><I.chevL size={14}/></button>
            <h3 className="cal-month-label">{monthLabel}</h3>
            <button className="icon-btn" onClick={next}><I.chev size={14}/></button>
          </div>
          <div className="cal-dow">
            {["Mon","Tue","Wed","Thu","Fri","Sat","Sun"].map(d => <div key={d}>{d}</div>)}
          </div>
          <div className="cal-grid">
            {cells.map((iso, i) => {
              if (!iso) return <div key={i} className="cal-cell is-empty"/>;
              const bks = (bookingsByDate[iso] || []).filter(b => b.status !== "Cancelled");
              const blocks = blockedByDate[iso] || [];
              // Collect unique event colors (up to 3 dots)
              const seen = {};
              const dots = [];
              bks.forEach(b => {
                const ev = data.events.find(e => e.id === b.eventId || e.name === b.eventName);
                const key = ev?.id || b.eventName;
                if (!seen[key]) { seen[key] = true; dots.push(ev?.color || "var(--accent)"); }
              });
              return (
                <button
                  key={iso}
                  className={["cal-cell", iso === today ? "is-today" : "", iso === selected ? "is-selected" : "", bks.length ? "has-bookings" : ""].filter(Boolean).join(" ")}
                  onClick={() => setSelected(iso)}>
                  <span className="cal-day-num">{Number(iso.slice(8))}</span>
                  {dots.length > 0 && (
                    <div className="cal-dots">
                      {dots.slice(0, 3).map((color, ci) => (
                        <span key={ci} className="cal-dot" style={{background: color}}/>
                      ))}
                      {dots.length > 3 && <span className="cal-dot-extra">+{dots.length - 3}</span>}
                    </div>
                  )}
                  {blocks.length > 0 && (
                    <div style={{display:"flex", alignItems:"center", gap:2, marginTop:2, background:"rgba(245,158,11,0.15)", borderRadius:3, padding:"1px 4px", fontSize:10, color:"#b45309", maxWidth:"100%", overflow:"hidden"}}>
                      <I.lock size={9}/>
                      <span style={{overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap"}}>{blocks.length > 1 ? `${blocks.length} blocks` : (blocks[0].label || "Blocked")}</span>
                    </div>
                  )}
                </button>
              );
            })}
          </div>
        </div>

        {/* ── Day detail ── */}
        <div className="card cal-detail">
          <div className="cal-detail-h">
            <div>
              <div className="cal-detail-date">{selected ? formatIsoDate(selected, { weekday: "long", year: true }) : "Select a day"}</div>
              <div className="sub">{selectedBookings.length === 0 ? "No bookings" : `${selectedBookings.length} booking${selectedBookings.length !== 1 ? "s" : ""}`}{selectedBlocks.length > 0 ? ` · ${selectedBlocks.length} block${selectedBlocks.length !== 1 ? "s" : ""}` : ""}</div>
            </div>
          </div>
          {selectedBlocks.length > 0 && (
            <div style={{padding:"0 0 8px"}}>
              {selectedBlocks.map(bl => (
                <div key={bl.id} style={{display:"flex", alignItems:"center", gap:10, padding:"8px 12px", background:"rgba(245,158,11,0.08)", border:"1px solid rgba(245,158,11,0.2)", borderRadius:8, marginBottom:6}}>
                  <div style={{width:3, alignSelf:"stretch", background:"#f59e0b", borderRadius:2, flexShrink:0}}/>
                  <I.lock size={13} style={{color:"#b45309", flexShrink:0}}/>
                  <div style={{flex:1}}>
                    <div style={{fontSize:13, fontWeight:500, color:"#92400e"}}>{bl.label || "Blocked"}</div>
                    <div style={{fontSize:11, color:"#b45309"}}>{bl.startTime} – {bl.endTime}</div>
                  </div>
                  <button className="btn ghost" style={{fontSize:11, padding:"2px 8px"}}
                    onClick={() => setBlockedTimes(bt => bt.filter(b => b.id !== bl.id))}>Remove</button>
                </div>
              ))}
            </div>
          )}
          {selectedBookings.length === 0 ? (
            <div className="cal-empty">
              <I.cal size={28}/>
              <p>No bookings on this day</p>
            </div>
          ) : (
            <div className="cal-booking-list">
              {selectedBookings.map(bk => (
                <div key={bk.id} className="cal-booking-row">
                  <div className="cal-booking-bar" style={{background: getEventColor(bk)}}/>
                  <div className="cal-booking-body">
                    <div className="cal-booking-time">{bk.time}</div>
                    <div className="cal-booking-name">{bk.guestName}</div>
                    <div className="cal-booking-event">{bk.eventName}</div>
                  </div>
                  <span className={"pill " + bk.status.toLowerCase()}>{bk.status}</span>
                </div>
              ))}
            </div>
          )}
        </div>
      </div>
    </>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Router
// ──────────────────────────────────────────────────────────────────────────
// ──────────────────────────────────────────────────────────────────────────
// Platform (super admin) — tabbed: Accounts / Coupons / Announcements / Activity
// ──────────────────────────────────────────────────────────────────────────

const PLAN_OPTIONS = ["starter","professional","business"];
const PLAN_COLORS  = { starter:"#7aa7ff", professional:"var(--accent)", business:"#6ee7a3" };
const PLAN_PRICES  = { starter:19, professional:39, business:79 };

function PlanBadge({ plan }) {
  const p = plan || "starter";
  return (
    <span className="plan-badge" style={{color: PLAN_COLORS[p] || "var(--text-muted)", borderColor: PLAN_COLORS[p] || "var(--border)"}}>
      {p.charAt(0).toUpperCase() + p.slice(1)}
    </span>
  );
}

// ── Notes modal ───────────────────────────────────────────────
function NotesModal({ accountId, accountName, onClose }) {
  const [notes, setNotes]   = React.useState(null);
  const [draft, setDraft]   = React.useState("");
  const [saving, setSaving] = React.useState(false);

  React.useEffect(() => {
    fetchPlatformNotes(accountId).then(setNotes);
  }, [accountId]);

  const handleAdd = async () => {
    if (!draft.trim()) return;
    setSaving(true);
    const row = await addPlatformNote(accountId, draft.trim());
    setNotes(n => [{ id: row.id, note: row.note, createdAt: row.created_at || new Date().toISOString() }, ...(n || [])]);
    setDraft("");
    setSaving(false);
  };

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal-card" style={{maxWidth:520}} onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <div>
            <h3 style={{margin:0}}>Internal notes</h3>
            <span className="sub" style={{fontSize:12}}>{accountName}</span>
          </div>
          <button className="modal-close" onClick={onClose}><I.x size={14}/></button>
        </div>
        <div className="modal-body">
          <div style={{display:"flex", gap:8, marginBottom:16}}>
            <textarea className="bk-textarea" rows={2} style={{flex:1, marginTop:0}}
              value={draft} onChange={e => setDraft(e.target.value)}
              placeholder="Add an internal note about this account…"/>
            <button className="btn primary" style={{alignSelf:"flex-end"}} onClick={handleAdd} disabled={saving || !draft.trim()}>
              {saving ? "…" : "Add"}
            </button>
          </div>
          <div className="platform-notes-list">
            {notes === null && <div style={{color:"var(--text-muted)",fontSize:13}}>Loading…</div>}
            {notes && notes.length === 0 && <div style={{color:"var(--text-muted)",fontSize:13}}>No notes yet.</div>}
            {(notes || []).map(n => (
              <div key={n.id} className="platform-note-row">
                <div className="platform-note-text">{n.note}</div>
                <div className="platform-note-date">{n.createdAt ? new Date(n.createdAt).toLocaleDateString("en-GB",{day:"numeric",month:"short",year:"numeric",hour:"2-digit",minute:"2-digit"}) : ""}</div>
              </div>
            ))}
          </div>
        </div>
      </div>
    </div>
  );
}

// ── Accounts tab ──────────────────────────────────────────────
function PlatformAccounts({ accounts, onAccountsChange, onViewAccount }) {
  const [notesFor,   setNotesFor]   = React.useState(null);
  const [search,     setSearch]     = React.useState("");
  const [planFilter, setPlanFilter] = React.useState("all");

  const handlePlan = async (id, plan) => {
    onAccountsChange(a => a.map(x => x.id === id ? { ...x, plan } : x));
    await updateAccountPlan(id, plan);
  };

  const handleSuspend = async (id, suspended) => {
    onAccountsChange(a => a.map(x => x.id === id ? { ...x, suspended } : x));
    await updateAccountSuspended(id, suspended);
  };

  if (!accounts) return <div style={{display:"flex",alignItems:"center",justifyContent:"center",height:300}}><div className="loading-dots"><span/><span/><span/></div></div>;

  const totalBookings = accounts.reduce((s, a) => s + a.bookingCount, 0);
  const totalEvents   = accounts.reduce((s, a) => s + a.eventCount, 0);
  const active        = accounts.filter(a => a.setupComplete).length;
  const suspended     = accounts.filter(a => a.suspended).length;
  const mrr           = accounts.reduce((s, a) => s + (PLAN_PRICES[a.plan || "free"] || 0), 0);

  const filtered = accounts.filter(a => {
    const q = search.toLowerCase();
    const matchSearch = !q || (a.brandName||"").toLowerCase().includes(q) || (a.email||"").toLowerCase().includes(q);
    const matchPlan   = planFilter === "all" || (a.plan || "starter") === planFilter;
    return matchSearch && matchPlan;
  });

  return (
    <>
      {/* Search + filter */}
      <div style={{display:"flex", gap:10, marginBottom:16, alignItems:"center"}}>
        <input className="bk-input" style={{flex:1, maxWidth:340}}
          placeholder="Search by business name or email…"
          value={search} onChange={e => setSearch(e.target.value)}/>
        <select className="bk-input" style={{width:170}}
          value={planFilter} onChange={e => setPlanFilter(e.target.value)}>
          <option value="all">All plans</option>
          {PLAN_OPTIONS.map(p => (
            <option key={p} value={p}>{p.charAt(0).toUpperCase()+p.slice(1)}</option>
          ))}
        </select>
        {(search || planFilter !== "all") && (
          <button className="btn ghost" style={{fontSize:12, whiteSpace:"nowrap"}}
            onClick={() => { setSearch(""); setPlanFilter("all"); }}>Clear</button>
        )}
        <span style={{fontSize:12, color:"var(--text-muted)", whiteSpace:"nowrap", marginLeft:"auto"}}>
          {filtered.length !== accounts.length ? `${filtered.length} of ${accounts.length}` : `${accounts.length} accounts`}
        </span>
      </div>

      {/* Stats */}
      <div className="platform-stats">
        <div className="platform-stat"><div className="platform-stat-n">{accounts.length}</div><div className="platform-stat-l">Businesses</div></div>
        <div className="platform-stat"><div className="platform-stat-n">{active}</div><div className="platform-stat-l">Active setups</div></div>
        <div className="platform-stat"><div className="platform-stat-n">{totalEvents}</div><div className="platform-stat-l">Total services</div></div>
        <div className="platform-stat"><div className="platform-stat-n">{totalBookings}</div><div className="platform-stat-l">Total bookings</div></div>
        <div className="platform-stat"><div className="platform-stat-n" style={{color:suspended?"var(--danger)":"inherit"}}>{suspended}</div><div className="platform-stat-l">Suspended</div></div>
        <div className="platform-stat"><div className="platform-stat-n" style={{color:"var(--accent)"}}>£{mrr.toLocaleString()}</div><div className="platform-stat-l">Est. MRR</div></div>
      </div>

      {/* Table */}
      <div className="card">
        <table className="table">
          <thead>
            <tr>
              <th>Business</th>
              <th>Plan</th>
              <th>Booking URL</th>
              <th>Services</th>
              <th>Bookings</th>
              <th>Joined</th>
              <th>2FA</th>
              <th>Status</th>
              <th></th>
            </tr>
          </thead>
          <tbody>
            {filtered.length === 0 && (
              <tr><td colSpan="9" style={{padding:"40px 20px",textAlign:"center",color:"var(--text-muted)"}}>
                {accounts.length === 0 ? "No accounts yet." : "No accounts match your search."}
              </td></tr>
            )}
            {filtered.map(a => (
              <tr key={a.id} style={{opacity: a.suspended ? 0.6 : 1}}>
                <td>
                  <div style={{fontWeight:600}}>{a.brandName || "—"}</div>
                  <div style={{fontSize:12,color:"var(--text-muted)"}}>{a.email}</div>
                </td>
                <td>
                  <select className="status-select"
                    value={a.plan || "starter"}
                    onChange={e => handlePlan(a.id, e.target.value)}
                    style={{color: PLAN_COLORS[a.plan || "starter"]}}>
                    {PLAN_OPTIONS.map(p => <option key={p} value={p}>{p === "professional" ? "Professional" : p.charAt(0).toUpperCase()+p.slice(1)}</option>)}
                  </select>
                </td>
                <td><span style={{fontSize:12,color:"var(--text-muted)"}}>{a.bookingUrl || "—"}</span></td>
                <td>{a.eventCount}</td>
                <td>{a.bookingCount}</td>
                <td style={{fontSize:12,color:"var(--text-muted)"}}>{a.createdAt ? new Date(a.createdAt).toLocaleDateString("en-GB",{day:"numeric",month:"short",year:"numeric"}) : "—"}</td>
                <td>
                  {a.twoFactor?.enabled
                    ? <span style={{fontSize:11,fontWeight:600,color:"#10b981",background:"rgba(16,185,129,.1)",padding:"2px 8px",borderRadius:20,whiteSpace:"nowrap"}}>
                        {a.twoFactor.method === "totp" ? "App" : "Email"}
                      </span>
                    : <span style={{fontSize:11,color:"var(--text-muted)"}}>Off</span>
                  }
                </td>
                <td>
                  <label className="switch" title={a.suspended ? "Suspended — click to restore" : "Active — click to suspend"}>
                    <input type="checkbox" checked={!a.suspended} onChange={e => handleSuspend(a.id, !e.target.checked)}/>
                    <span className="track"><span className="knob"/></span>
                  </label>
                </td>
                <td style={{textAlign:"right"}}>
                  <div style={{display:"flex",gap:4,justifyContent:"flex-end"}}>
                    <button className="btn ghost" style={{fontSize:11,padding:"3px 8px"}}
                      onClick={() => setNotesFor({ id: a.id, name: a.brandName || a.email || "Account" })}>
                      Notes
                    </button>
                    {a.bookingUrl && (
                      <button className="btn ghost" style={{fontSize:11,padding:"3px 8px"}}
                        onClick={() => window.open(getBookingUrl(a.bookingUrl), "_blank")}>
                        Page
                      </button>
                    )}
                    <button className="btn primary" style={{fontSize:11,padding:"3px 8px"}}
                      onClick={() => onViewAccount(a.id)}>
                      View
                    </button>
                  </div>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      {notesFor && (
        <NotesModal accountId={notesFor.id} accountName={notesFor.name} onClose={() => setNotesFor(null)}/>
      )}
    </>
  );
}

// ── Coupon modal ──────────────────────────────────────────────
function CouponModal({ coupon, onClose, onSave }) {
  const blank = { code:"", description:"", discountType:"percent", discountValue:"", trialDays:"", maxUses:"", timesUsed:0, active:true, expiresAt:"" };
  const [draft, setDraft] = React.useState(coupon || blank);
  const [saving, setSaving] = React.useState(false);
  const set = (k, v) => setDraft(d => ({ ...d, [k]: v }));

  const genCode = () => {
    const chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
    let code = "";
    for (let i = 0; i < 8; i++) code += chars[Math.floor(Math.random() * chars.length)];
    set("code", code);
  };

  const handleSave = async () => {
    setSaving(true);
    await onSave(draft);
    setSaving(false);
    onClose();
  };

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal-card" style={{maxWidth:500}} onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <h3 style={{margin:0}}>{coupon?.id ? "Edit coupon" : "New coupon"}</h3>
          <button className="modal-close" onClick={onClose}><I.x size={14}/></button>
        </div>
        <div className="modal-body">
          <div className="field-grid">
            <div className="bk-field" style={{gridColumn:"1 / -1"}}>
              <label>Coupon code</label>
              <div style={{display:"flex",gap:8}}>
                <input className="bk-input" style={{flex:1,textTransform:"uppercase",letterSpacing:"0.1em",fontWeight:600}}
                  value={draft.code} onChange={e => set("code", e.target.value.toUpperCase())}
                  placeholder="e.g. SUMMER25"/>
                <button className="btn ghost" onClick={genCode} title="Generate random code">Generate</button>
              </div>
            </div>
            <div className="bk-field" style={{gridColumn:"1 / -1"}}>
              <label>Description <span className="opt">(internal)</span></label>
              <input className="bk-input" value={draft.description} onChange={e => set("description", e.target.value)} placeholder="e.g. Summer campaign 2026"/>
            </div>
            <div className="bk-field">
              <label>Discount type</label>
              <select className="bk-input" value={draft.discountType} onChange={e => set("discountType", e.target.value)}>
                <option value="percent">% off</option>
                <option value="fixed">Fixed amount off</option>
                <option value="trial">Extended trial (days)</option>
              </select>
            </div>
            {(draft.discountType === "percent" || draft.discountType === "fixed") && (
              <div className="bk-field">
                <label>{draft.discountType === "percent" ? "Discount %" : "Amount off"}</label>
                <input className="bk-input" type="number" min="0" value={draft.discountValue}
                  onChange={e => set("discountValue", e.target.value)} placeholder={draft.discountType === "percent" ? "25" : "10.00"}/>
              </div>
            )}
            {draft.discountType === "trial" && (
              <div className="bk-field">
                <label>Trial days</label>
                <input className="bk-input" type="number" min="0" value={draft.trialDays}
                  onChange={e => set("trialDays", e.target.value)} placeholder="30"/>
              </div>
            )}
            <div className="bk-field">
              <label>Max uses <span className="opt">(0 = unlimited)</span></label>
              <input className="bk-input" type="number" min="0" value={draft.maxUses}
                onChange={e => set("maxUses", e.target.value)} placeholder="0"/>
            </div>
            <div className="bk-field">
              <label>Expires on <span className="opt">(optional)</span></label>
              <input className="bk-input" type="date" value={draft.expiresAt}
                onChange={e => set("expiresAt", e.target.value)}/>
            </div>
            <div className="bk-field" style={{gridColumn:"1 / -1", display:"flex", alignItems:"center", gap:10}}>
              <label className="switch">
                <input type="checkbox" checked={draft.active} onChange={e => set("active", e.target.checked)}/>
                <span className="track"><span className="knob"/></span>
              </label>
              <span style={{fontSize:13}}>Coupon is active</span>
            </div>
          </div>
        </div>
        <div className="modal-foot">
          <button className="btn ghost" onClick={onClose}>Cancel</button>
          <button className="btn primary" onClick={handleSave} disabled={saving || !draft.code.trim()}>
            {saving ? "Saving…" : "Save coupon"}
          </button>
        </div>
      </div>
    </div>
  );
}

// ── Coupons tab ───────────────────────────────────────────────
function PlatformCoupons() {
  const [coupons, setCoupons] = React.useState(null);
  const [editing, setEditing] = React.useState(null); // null | {} (new) | coupon obj

  React.useEffect(() => { fetchCoupons().then(setCoupons); }, []);

  const handleSave = async (draft) => {
    const id = await saveCoupon(draft);
    fetchCoupons().then(setCoupons);
  };

  const handleDelete = async (id) => {
    if (!confirm("Delete this coupon?")) return;
    await deleteCoupon(id);
    setCoupons(c => c.filter(x => x.id !== id));
  };

  const discountLabel = (c) => {
    if (c.discountType === "percent") return `${c.discountValue}% off`;
    if (c.discountType === "fixed")   return `£${c.discountValue} off`;
    if (c.discountType === "trial")   return `${c.trialDays}-day trial`;
    return "—";
  };

  if (!coupons) return <div style={{display:"flex",alignItems:"center",justifyContent:"center",height:300}}><div className="loading-dots"><span/><span/><span/></div></div>;

  return (
    <>
      <div style={{display:"flex", justifyContent:"flex-end", marginBottom:16}}>
        <button className="btn primary" onClick={() => setEditing({})}>+ New coupon</button>
      </div>
      <div className="card">
        <table className="table">
          <thead>
            <tr>
              <th>Code</th>
              <th>Description</th>
              <th>Discount</th>
              <th>Uses</th>
              <th>Expires</th>
              <th>Status</th>
              <th></th>
            </tr>
          </thead>
          <tbody>
            {coupons.length === 0 && (
              <tr><td colSpan="7" style={{padding:"40px 20px",textAlign:"center",color:"var(--text-muted)"}}>No coupons yet. Create one above.</td></tr>
            )}
            {coupons.map(c => (
              <tr key={c.id}>
                <td>
                  <code className="coupon-code">{c.code}</code>
                </td>
                <td style={{color:"var(--text-muted)",fontSize:13}}>{c.description || "—"}</td>
                <td><span className="coupon-discount">{discountLabel(c)}</span></td>
                <td>
                  <span style={{fontSize:13}}>
                    {c.timesUsed}
                    {c.maxUses > 0 ? ` / ${c.maxUses}` : " / ∞"}
                  </span>
                </td>
                <td style={{fontSize:12,color:"var(--text-muted)"}}>
                  {c.expiresAt ? new Date(c.expiresAt).toLocaleDateString("en-GB",{day:"numeric",month:"short",year:"numeric"}) : "Never"}
                </td>
                <td>
                  <span className={"pill " + (c.active ? "confirmed" : "cancelled")}>{c.active ? "Active" : "Inactive"}</span>
                </td>
                <td style={{textAlign:"right"}}>
                  <div style={{display:"flex",gap:4,justifyContent:"flex-end"}}>
                    <button className="btn ghost" style={{fontSize:11,padding:"3px 8px"}} onClick={() => setEditing(c)}>Edit</button>
                    <button className="btn ghost" style={{fontSize:11,padding:"3px 8px",color:"var(--danger)"}} onClick={() => handleDelete(c.id)}>Delete</button>
                  </div>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
      {editing !== null && (
        <CouponModal
          coupon={Object.keys(editing).length === 0 ? null : editing}
          onClose={() => setEditing(null)}
          onSave={handleSave}
        />
      )}
    </>
  );
}

// ── Announcement modal ────────────────────────────────────────
function AnnouncementModal({ ann, onClose, onSave }) {
  const blank = { title:"", message:"", type:"info", targetPlan:"all", active:true, expiresAt:"" };
  const [draft, setDraft] = React.useState(ann || blank);
  const [saving, setSaving] = React.useState(false);
  const set = (k, v) => setDraft(d => ({ ...d, [k]: v }));

  const handleSave = async () => {
    setSaving(true);
    await onSave(draft);
    setSaving(false);
    onClose();
  };

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal-card" style={{maxWidth:500}} onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <h3 style={{margin:0}}>{ann?.id ? "Edit announcement" : "New announcement"}</h3>
          <button className="modal-close" onClick={onClose}><I.x size={14}/></button>
        </div>
        <div className="modal-body">
          <div className="field-grid">
            <div className="bk-field" style={{gridColumn:"1 / -1"}}>
              <label>Title</label>
              <input className="bk-input" value={draft.title} onChange={e => set("title", e.target.value)} placeholder="e.g. Scheduled maintenance"/>
            </div>
            <div className="bk-field" style={{gridColumn:"1 / -1"}}>
              <label>Message</label>
              <textarea className="bk-textarea" rows={3} value={draft.message}
                onChange={e => set("message", e.target.value)} placeholder="Shown to all users in their dashboard…"/>
            </div>
            <div className="bk-field">
              <label>Type</label>
              <select className="bk-input" value={draft.type} onChange={e => set("type", e.target.value)}>
                <option value="info">Info</option>
                <option value="warning">Warning</option>
                <option value="success">Success</option>
              </select>
            </div>
            <div className="bk-field">
              <label>Target audience</label>
              <select className="bk-input" value={draft.targetPlan || "all"} onChange={e => set("targetPlan", e.target.value)}>
                <option value="all">All accounts</option>
                <option value="starter">Starter only</option>
                <option value="professional">Professional only</option>
                <option value="business">Business only</option>
              </select>
            </div>
            <div className="bk-field">
              <label>Expires on <span className="opt">(optional)</span></label>
              <input className="bk-input" type="date" value={draft.expiresAt}
                onChange={e => set("expiresAt", e.target.value)}/>
            </div>
            <div className="bk-field" style={{gridColumn:"1 / -1", display:"flex", alignItems:"center", gap:10}}>
              <label className="switch">
                <input type="checkbox" checked={draft.active} onChange={e => set("active", e.target.checked)}/>
                <span className="track"><span className="knob"/></span>
              </label>
              <span style={{fontSize:13}}>Announcement is live</span>
            </div>
          </div>
        </div>
        <div className="modal-foot">
          <button className="btn ghost" onClick={onClose}>Cancel</button>
          <button className="btn primary" onClick={handleSave} disabled={saving || !draft.title.trim() || !draft.message.trim()}>
            {saving ? "Saving…" : "Save announcement"}
          </button>
        </div>
      </div>
    </div>
  );
}

// ── Announcements tab ─────────────────────────────────────────
function PlatformAnnouncements() {
  const [anns, setAnns]     = React.useState(null);
  const [editing, setEditing] = React.useState(null);

  React.useEffect(() => { fetchAnnouncements().then(setAnns); }, []);

  const handleSave = async (draft) => {
    await saveAnnouncement(draft);
    fetchAnnouncements().then(setAnns);
  };

  const handleDelete = async (id) => {
    if (!confirm("Delete this announcement?")) return;
    await deleteAnnouncement(id);
    setAnns(a => a.filter(x => x.id !== id));
  };

  const TYPE_LABELS = { info:"Info", warning:"Warning", success:"Success" };
  const TYPE_COLORS = { info:"#7aa7ff", warning:"var(--accent)", success:"#6ee7a3" };

  if (!anns) return <div style={{display:"flex",alignItems:"center",justifyContent:"center",height:300}}><div className="loading-dots"><span/><span/><span/></div></div>;

  return (
    <>
      <div style={{display:"flex", justifyContent:"flex-end", marginBottom:16}}>
        <button className="btn primary" onClick={() => setEditing({})}>+ New announcement</button>
      </div>
      <div className="card">
        <table className="table">
          <thead>
            <tr>
              <th>Title</th>
              <th>Type</th>
              <th>Audience</th>
              <th>Expires</th>
              <th>Status</th>
              <th></th>
            </tr>
          </thead>
          <tbody>
            {anns.length === 0 && (
              <tr><td colSpan="6" style={{padding:"40px 20px",textAlign:"center",color:"var(--text-muted)"}}>No announcements. Create one above.</td></tr>
            )}
            {anns.map(a => (
              <tr key={a.id}>
                <td>
                  <div style={{fontWeight:600}}>{a.title}</div>
                  <div style={{fontSize:12,color:"var(--text-muted)",maxWidth:300,whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"}}>{a.message}</div>
                </td>
                <td>
                  <span style={{fontSize:12,fontWeight:500,color:TYPE_COLORS[a.type]||"var(--text-muted)"}}>
                    {TYPE_LABELS[a.type]||a.type}
                  </span>
                </td>
                <td style={{fontSize:12,color:"var(--text-muted)"}}>
                  {!a.targetPlan || a.targetPlan === "all"
                    ? "All accounts"
                    : <span style={{color:PLAN_COLORS[a.targetPlan]||"var(--text-muted)",fontWeight:500}}>
                        {a.targetPlan.charAt(0).toUpperCase()+a.targetPlan.slice(1)} only
                      </span>
                  }
                </td>
                <td style={{fontSize:12,color:"var(--text-muted)"}}>
                  {a.expiresAt ? new Date(a.expiresAt).toLocaleDateString("en-GB",{day:"numeric",month:"short",year:"numeric"}) : "Never"}
                </td>
                <td>
                  <span className={"pill " + (a.active ? "confirmed" : "cancelled")}>{a.active ? "Live" : "Inactive"}</span>
                </td>
                <td style={{textAlign:"right"}}>
                  <div style={{display:"flex",gap:4,justifyContent:"flex-end"}}>
                    <button className="btn ghost" style={{fontSize:11,padding:"3px 8px"}} onClick={() => setEditing(a)}>Edit</button>
                    <button className="btn ghost" style={{fontSize:11,padding:"3px 8px",color:"var(--danger)"}} onClick={() => handleDelete(a.id)}>Delete</button>
                  </div>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
      {editing !== null && (
        <AnnouncementModal
          ann={Object.keys(editing).length === 0 ? null : editing}
          onClose={() => setEditing(null)}
          onSave={handleSave}
        />
      )}
    </>
  );
}

// ── Activity tab ──────────────────────────────────────────────
function PlatformActivity() {
  const [items, setItems] = React.useState(null);

  React.useEffect(() => { fetchPlatformActivity().then(setItems); }, []);

  if (!items) return <div style={{display:"flex",alignItems:"center",justifyContent:"center",height:300}}><div className="loading-dots"><span/><span/><span/></div></div>;

  return (
    <div className="card">
      <div className="card-h">
        <h3>Platform Activity Log</h3>
        <span className="sub">Last 100 events across all accounts</span>
      </div>
      <div className="platform-activity-list">
        {items.length === 0 && <div style={{padding:"40px 20px",textAlign:"center",color:"var(--text-muted)"}}>No activity recorded yet.</div>}
        {items.map(item => (
          <div key={item.id} className="platform-activity-row">
            <div className="platform-activity-dot"/>
            <div className="platform-activity-text">{item.text}</div>
            <div className="platform-activity-meta">
              <span className="platform-activity-id">{(item.userId || "").slice(0, 8)}</span>
              <span className="platform-activity-time">
                {item.createdAt ? new Date(item.createdAt).toLocaleDateString("en-GB",{day:"numeric",month:"short",hour:"2-digit",minute:"2-digit"}) : ""}
              </span>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

// ── Revenue tab ───────────────────────────────────────────────
function PlatformRevenue({ accounts }) {
  if (!accounts) return <div style={{display:"flex",alignItems:"center",justifyContent:"center",height:300}}><div className="loading-dots"><span/><span/><span/></div></div>;

  const mrr     = accounts.reduce((s, a) => s + (PLAN_PRICES[a.plan||"starter"]||0), 0);
  const arr     = mrr * 12;
  const paying  = accounts.filter(a => (a.plan||"starter") !== "starter" || (PLAN_PRICES[a.plan||"starter"]||0) > 0).length;
  const avgRev  = paying > 0 ? Math.round(mrr / paying) : 0;
  const convPct = accounts.length > 0 ? Math.round((paying / accounts.length) * 100) : 0;

  const planDist = PLAN_OPTIONS.map(p => ({
    plan: p, color: PLAN_COLORS[p],
    count:   accounts.filter(a => (a.plan||"starter") === p).length,
    revenue: accounts.filter(a => (a.plan||"starter") === p).length * (PLAN_PRICES[p]||0),
  }));
  const maxCount = Math.max(...planDist.map(d => d.count), 1);

  // Monthly signups — last 6 months
  const now = new Date();
  const months = Array.from({ length: 6 }, (_, i) => {
    const d = new Date(now.getFullYear(), now.getMonth() - 5 + i, 1);
    return { label: d.toLocaleString("en-GB", { month: "short" }), year: d.getFullYear(), month: d.getMonth(), count: 0 };
  });
  accounts.forEach(a => {
    if (!a.createdAt) return;
    const d = new Date(a.createdAt);
    const m = months.find(x => x.year === d.getFullYear() && x.month === d.getMonth());
    if (m) m.count++;
  });
  const maxSignups = Math.max(...months.map(m => m.count), 1);

  return (
    <>
      {/* Key metrics */}
      <div className="platform-stats" style={{marginBottom:24}}>
        <div className="platform-stat">
          <div className="platform-stat-n" style={{color:"var(--accent)"}}>£{mrr.toLocaleString()}</div>
          <div className="platform-stat-l">Monthly revenue</div>
        </div>
        <div className="platform-stat">
          <div className="platform-stat-n">£{arr.toLocaleString()}</div>
          <div className="platform-stat-l">Annual run rate</div>
        </div>
        <div className="platform-stat">
          <div className="platform-stat-n">{paying}</div>
          <div className="platform-stat-l">Paying accounts</div>
        </div>
        <div className="platform-stat">
          <div className="platform-stat-n">£{avgRev}</div>
          <div className="platform-stat-l">Avg. per account</div>
        </div>
        <div className="platform-stat">
          <div className="platform-stat-n">{convPct}%</div>
          <div className="platform-stat-l">Conversion rate</div>
        </div>
      </div>

      <div style={{display:"grid", gridTemplateColumns:"1fr 1fr", gap:20}}>
        {/* Plan distribution */}
        <div className="card" style={{padding:"20px 24px"}}>
          <h3 style={{margin:"0 0 20px", fontSize:15, fontWeight:600}}>Plan distribution</h3>
          <div style={{display:"flex", flexDirection:"column", gap:16}}>
            {planDist.map(d => (
              <div key={d.plan}>
                <div style={{display:"flex", justifyContent:"space-between", marginBottom:6, fontSize:13}}>
                  <span style={{fontWeight:500, display:"flex", alignItems:"center", gap:7}}>
                    <span style={{width:10, height:10, borderRadius:3, background:d.color, display:"inline-block", flexShrink:0}}/>
                    {d.plan.charAt(0).toUpperCase()+d.plan.slice(1)}
                  </span>
                  <span style={{color:"var(--text-muted)"}}>
                    {d.count} account{d.count!==1?"s":""}
                    {d.revenue > 0 ? <> · <span style={{color:"var(--text)"}}>£{d.revenue.toLocaleString()}/mo</span></> : ""}
                  </span>
                </div>
                <div style={{height:8, background:"var(--surface-2)", borderRadius:4, overflow:"hidden"}}>
                  <div style={{height:"100%", width:`${(d.count/maxCount)*100}%`, background:d.color, borderRadius:4, transition:"width .4s ease"}}/>
                </div>
              </div>
            ))}
          </div>
        </div>

        {/* Monthly signups chart */}
        <div className="card" style={{padding:"20px 24px"}}>
          <h3 style={{margin:"0 0 20px", fontSize:15, fontWeight:600}}>Monthly signups</h3>
          <div style={{display:"flex", alignItems:"flex-end", gap:8, height:130, paddingTop:24}}>
            {months.map(m => (
              <div key={`${m.year}-${m.month}`} style={{flex:1, display:"flex", flexDirection:"column", alignItems:"center", gap:5, height:"100%"}}>
                <div style={{flex:1, width:"100%", display:"flex", alignItems:"flex-end", position:"relative"}}>
                  {m.count > 0 && (
                    <div style={{position:"absolute", top:-20, left:"50%", transform:"translateX(-50%)", fontSize:11, fontWeight:600, color:"var(--text)", whiteSpace:"nowrap"}}>
                      {m.count}
                    </div>
                  )}
                  <div style={{
                    width:"100%",
                    height:`${Math.max(3, (m.count/maxSignups)*100)}%`,
                    background:"var(--accent)",
                    borderRadius:"4px 4px 0 0",
                    opacity:0.85,
                    minHeight:3,
                    transition:"height .4s ease",
                  }}/>
                </div>
                <div style={{fontSize:11, color:"var(--text-muted)", fontWeight:500}}>{m.label}</div>
              </div>
            ))}
          </div>
        </div>
      </div>
    </>
  );
}

// ── ViewPlatform (tabbed shell) ───────────────────────────────
function ViewPlatform({ onViewAccount }) {
  const [tab,      setTab]      = React.useState("accounts");
  const [accounts, setAccounts] = React.useState(null);

  React.useEffect(() => { fetchAllProfiles().then(setAccounts); }, []);

  const TABS = [
    { id: "accounts",      label: "Accounts" },
    { id: "revenue",       label: "Revenue" },
    { id: "coupons",       label: "Coupons" },
    { id: "announcements", label: "Announcements" },
    { id: "activity",      label: "Activity" },
  ];

  return (
    <>
      <div className="view-h">
        <div>
          <h1>Platform</h1>
          <div className="sub">Super admin — manage all accounts, coupons, and announcements.</div>
        </div>
      </div>

      <div className="platform-tabs">
        {TABS.map(t => (
          <button key={t.id}
            className={"platform-tab " + (tab === t.id ? "is-active" : "")}
            onClick={() => setTab(t.id)}>
            {t.label}
          </button>
        ))}
      </div>

      {tab === "accounts"      && <PlatformAccounts accounts={accounts} onAccountsChange={setAccounts} onViewAccount={onViewAccount}/>}
      {tab === "revenue"       && <PlatformRevenue accounts={accounts}/>}
      {tab === "coupons"       && <PlatformCoupons/>}
      {tab === "announcements" && <PlatformAnnouncements/>}
      {tab === "activity"      && <PlatformActivity/>}
    </>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Analytics
// ──────────────────────────────────────────────────────────────────────────
function MiniBarChart({ bars, color, showMoney, currency }) {
  const max = Math.max(...bars.map(b => b.value), 1);
  return (
    <div className="mini-bar-chart">
      {bars.map((b, i) => {
        const pct = Math.round((b.value / max) * 100);
        return (
          <div key={i} className="mini-bar-col">
            <div className="mini-bar-wrap">
              <div className="mini-bar" style={{ height: `${pct}%`, background: color }}/>
            </div>
            {b.value > 0 && (
              <div className="mini-bar-tip">
                {showMoney ? formatMoney(b.value, currency) : b.value}
              </div>
            )}
            <div className="mini-bar-label">{b.label}</div>
          </div>
        );
      })}
    </div>
  );
}

// ── Owner discount codes view ─────────────────────────────────
function ViewCoupons({ data }) {
  const [coupons, setCoupons] = React.useState(null);
  const [editing, setEditing] = React.useState(null); // null | {} (new) | coupon obj
  const userId = data.userId;

  React.useEffect(() => { fetchOwnerCoupons(userId).then(setCoupons); }, [userId]);

  const handleSave = async (draft) => {
    await saveCoupon(draft, userId);
    fetchOwnerCoupons(userId).then(setCoupons);
  };

  const handleDelete = async (id) => {
    if (!confirm("Delete this coupon? This can't be undone.")) return;
    await deleteCoupon(id);
    setCoupons(c => c.filter(x => x.id !== id));
  };

  const handleToggle = async (coupon) => {
    await saveCoupon({ ...coupon, active: !coupon.active }, userId);
    setCoupons(cs => cs.map(c => c.id === coupon.id ? { ...c, active: !c.active } : c));
  };

  const discountLabel = (c) => {
    const currency = data.profile.currency || "GBP";
    const sym = { GBP:"£", USD:"$", EUR:"€" }[currency] || currency + " ";
    if (c.discountType === "percent") return `${c.discountValue}% off`;
    if (c.discountType === "fixed")   return `${sym}${c.discountValue} off`;
    if (c.discountType === "trial")   return `${c.trialDays}-day trial`;
    if (c.discountType === "free")    return "Free access";
    return "—";
  };

  if (!coupons) return <div style={{display:"flex",alignItems:"center",justifyContent:"center",height:300}}><div className="loading-dots"><span/><span/><span/></div></div>;

  return (
    <>
      <div className="view-h">
        <div>
          <h1>Discount codes</h1>
          <div className="sub">Create and manage coupon codes for your booking page.</div>
        </div>
        <div className="view-actions">
          <button className="btn primary" onClick={() => setEditing({})}>+ New coupon</button>
        </div>
      </div>

      {coupons.length === 0 ? (
        <div className="empty-state">
          <I.tag size={28} style={{color:"var(--text-faint)",marginBottom:12}}/>
          <h3>No coupons yet</h3>
          <p>Create a coupon code and share it with clients for a percentage or fixed-amount discount on their bookings.</p>
          <button className="btn primary" style={{marginTop:16}} onClick={() => setEditing({})}>Create your first coupon</button>
        </div>
      ) : (
        <div className="card">
          <table className="table">
            <thead>
              <tr>
                <th>Code</th>
                <th>Description</th>
                <th>Discount</th>
                <th>Uses</th>
                <th>Expires</th>
                <th>Active</th>
                <th></th>
              </tr>
            </thead>
            <tbody>
              {coupons.map(c => (
                <tr key={c.id}>
                  <td><code className="coupon-code">{c.code}</code></td>
                  <td style={{color:"var(--text-muted)",fontSize:13}}>{c.description || "—"}</td>
                  <td><span className="coupon-discount">{discountLabel(c)}</span></td>
                  <td style={{fontSize:13}}>
                    {c.timesUsed}{c.maxUses > 0 ? ` / ${c.maxUses}` : " / ∞"}
                  </td>
                  <td style={{fontSize:12,color:"var(--text-muted)"}}>
                    {c.expiresAt ? new Date(c.expiresAt).toLocaleDateString("en-GB",{day:"numeric",month:"short",year:"numeric"}) : "Never"}
                  </td>
                  <td>
                    <label className="switch" title={c.active ? "Click to disable" : "Click to enable"}>
                      <input type="checkbox" checked={c.active} onChange={() => handleToggle(c)}/>
                      <span className="track"><span className="knob"/></span>
                    </label>
                  </td>
                  <td style={{textAlign:"right"}}>
                    <div style={{display:"flex",gap:4,justifyContent:"flex-end"}}>
                      <button className="btn ghost" style={{fontSize:11,padding:"3px 8px"}} onClick={() => setEditing(c)}>Edit</button>
                      <button className="btn ghost" style={{fontSize:11,padding:"3px 8px",color:"var(--danger)"}} onClick={() => handleDelete(c.id)}>Delete</button>
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}

      {editing !== null && (
        <CouponModal
          coupon={Object.keys(editing).length === 0 ? null : editing}
          onClose={() => setEditing(null)}
          onSave={handleSave}
        />
      )}
    </>
  );
}

// ── Static star display helper ────────────────────────────────
function StarDisplay({ rating, size = 14 }) {
  return (
    <span className="star-display">
      {[1,2,3,4,5].map(n => (
        <svg key={n} width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinejoin="round">
          <polygon points="12,2.5 15.09,8.75 22,9.75 17,14.6 18.18,21.5 12,18.25 5.82,21.5 7,14.6 2,9.75 8.91,8.75"
            className={n <= rating ? "full" : "empty"}/>
        </svg>
      ))}
    </span>
  );
}

function ViewReviews({ data }) {
  const [reviews, setReviews] = React.useState(null);

  React.useEffect(() => {
    fetchOwnerReviews(data.userId).then(setReviews);
  }, [data.userId]);

  const approved = (reviews || []);
  const total    = approved.length;
  const avg      = total > 0
    ? Math.round((approved.reduce((s, r) => s + r.rating, 0) / total) * 10) / 10
    : 0;

  // Count per star
  const counts = [5,4,3,2,1].map(s => ({
    star: s,
    count: approved.filter(r => r.rating === s).length,
  }));

  const formatDate = (iso) => {
    if (!iso) return "";
    return new Date(iso).toLocaleDateString("en-GB", { day:"numeric", month:"short", year:"numeric" });
  };

  return (
    <div className="dash-section">
      <div className="dash-section-h">
        <div>
          <h2 className="dash-section-title">Reviews</h2>
          <p className="dash-section-sub">Guest feedback collected after appointments.</p>
        </div>
      </div>

      {reviews === null ? (
        <div style={{textAlign:"center",padding:"60px 0"}}>
          <div className="loading-dots"><span/><span/><span/></div>
        </div>
      ) : total === 0 ? (
        <div className="empty-state">
          <I.star size={28} style={{color:"var(--text-faint)",marginBottom:12}}/>
          <h3>No reviews yet</h3>
          <p>Review requests are emailed automatically at 6 PM on the day of each appointment. Once guests leave reviews, they'll appear here.</p>
        </div>
      ) : (
        <>
          <div className="reviews-summary">
            <div className="reviews-avg">
              <div className="reviews-avg-num">{avg.toFixed(1)}</div>
              <div className="reviews-avg-stars">
                {[1,2,3,4,5].map(n => (
                  <svg key={n} width={16} height={16} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinejoin="round">
                    <polygon points="12,2.5 15.09,8.75 22,9.75 17,14.6 18.18,21.5 12,18.25 5.82,21.5 7,14.6 2,9.75 8.91,8.75"
                      style={{fill: n <= Math.round(avg) ? "#f59e0b" : "none", stroke: n <= Math.round(avg) ? "#f59e0b" : "var(--text-faint)"}}/>
                  </svg>
                ))}
              </div>
              <div className="reviews-avg-count">{total} review{total !== 1 ? "s" : ""}</div>
            </div>
            <div className="reviews-breakdown">
              {counts.map(({ star, count }) => (
                <div key={star} className="reviews-bar-row">
                  <span style={{minWidth:14, color:"var(--text-muted)"}}>{star}</span>
                  <svg width={12} height={12} viewBox="0 0 24 24" style={{flexShrink:0}}>
                    <polygon points="12,2.5 15.09,8.75 22,9.75 17,14.6 18.18,21.5 12,18.25 5.82,21.5 7,14.6 2,9.75 8.91,8.75"
                      fill={count > 0 ? "#f59e0b" : "none"} stroke="#f59e0b" strokeWidth="1.6" strokeLinejoin="round"/>
                  </svg>
                  <div className="reviews-bar-track">
                    <div className="reviews-bar-fill" style={{width: total > 0 ? `${(count/total)*100}%` : "0%"}}/>
                  </div>
                  <span className="reviews-bar-count">{count}</span>
                </div>
              ))}
            </div>
          </div>

          <div>
            {approved.map(r => (
              <div key={r.id} className="review-item">
                <div className="review-item-h">
                  <div className="review-item-meta">
                    <div className="review-item-name">{r.guestName}</div>
                    <div className="review-item-service">{r.eventName}</div>
                  </div>
                  <div style={{display:"flex",flexDirection:"column",alignItems:"flex-end",gap:4}}>
                    <StarDisplay rating={r.rating}/>
                    <div className="review-item-date">{formatDate(r.createdAt)}</div>
                  </div>
                </div>
                {r.comment && <div className="review-item-comment">"{r.comment}"</div>}
              </div>
            ))}
          </div>
        </>
      )}
    </div>
  );
}

function ViewAnalytics({ data }) {
  const currency    = data.profile.currency;
  const allBk       = data.bookings;
  const confirmed   = allBk.filter(b => b.status !== "Cancelled");

  // ── Year selector ────────────────────────────────────────────
  const now      = new Date();
  const curYear  = now.getFullYear();
  const [viewYear, setViewYear] = React.useState(curYear);

  // Bookings for selected year
  const yearConfirmed = confirmed.filter(b => b.date && Number(b.date.slice(0, 4)) === viewYear);
  const yearAll       = allBk.filter(b => b.date && Number(b.date.slice(0, 4)) === viewYear);

  // ── Key metrics (for selected year) ─────────────────────────
  const totalRevenue  = yearConfirmed.reduce((s, b) => s + Number(b.paymentAmount || 0), 0);
  const totalBookings = yearConfirmed.length;
  const avgValue      = totalBookings > 0 ? totalRevenue / totalBookings : 0;
  const showRate      = yearAll.length > 0
    ? Math.round((yearConfirmed.filter(b => b.status === "Confirmed").length / yearAll.length) * 100)
    : 100;
  const totalDiscount = yearConfirmed.reduce((s, b) => s + Number(b.discountApplied || 0), 0);

  // ── Month-over-month trend (current vs previous calendar month) ──
  const curMo  = now.getMonth();
  const curYr  = now.getFullYear();
  const prevMoY = curMo === 0 ? curYr - 1 : curYr;
  const prevMo  = curMo === 0 ? 11 : curMo - 1;
  const bkCur  = confirmed.filter(b => { if (!b.date) return false; const [y,m] = b.date.split("-").map(Number); return y === curYr  && m-1 === curMo; });
  const bkPrev = confirmed.filter(b => { if (!b.date) return false; const [y,m] = b.date.split("-").map(Number); return y === prevMoY && m-1 === prevMo; });
  const revCur  = bkCur.reduce((s, b) => s + Number(b.paymentAmount || 0), 0);
  const revPrev = bkPrev.reduce((s, b) => s + Number(b.paymentAmount || 0), 0);
  const momRevTrend = prevRevStr => {
    if (revPrev === 0) return null;
    const pct = Math.round(((revCur - revPrev) / revPrev) * 100);
    return { pct, up: pct >= 0 };
  };
  const momBkTrend = (() => {
    if (bkPrev.length === 0) return null;
    const pct = Math.round(((bkCur.length - bkPrev.length) / bkPrev.length) * 100);
    return { pct, up: pct >= 0 };
  })();
  const momRevT = momRevTrend();

  // ── All 12 months of selected year ──────────────────────────
  const MONTH_LABELS = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
  const monthData = MONTH_LABELS.map((label, mo) => {
    const slice = confirmed.filter(b => {
      if (!b.date) return false;
      const [by, bm] = b.date.split("-").map(Number);
      return by === viewYear && bm - 1 === mo;
    });
    return {
      label,
      revenue: slice.reduce((s, b) => s + Number(b.paymentAmount || 0), 0),
      count:   slice.length,
    };
  });

  // ── Bookings + revenue by service (selected year) ───────────
  const bySvc = {};
  yearConfirmed.forEach(b => {
    const key = b.eventName || "Unknown";
    if (!bySvc[key]) bySvc[key] = { count: 0, revenue: 0 };
    bySvc[key].count++;
    bySvc[key].revenue += Number(b.paymentAmount || 0);
  });
  const svcData   = Object.entries(bySvc).sort((a, b) => b[1].count - a[1].count).slice(0, 7);
  const svcColors = ["var(--accent)", "#7aa7ff", "#a78bfa", "#6ee7a3", "#f59e9e", "#94a3b8", "#fbbf24"];
  const svcMax    = svcData[0]?.[1]?.count || 1;
  const svcRevMax = Math.max(...svcData.map(([,v]) => v.revenue), 1);

  // ── Revenue + bookings by staff (selected year) ──────────────
  const byStaff = {};
  yearConfirmed.forEach(b => {
    if (!b.staffName) return;
    const key = b.staffName;
    if (!byStaff[key]) byStaff[key] = { count: 0, revenue: 0 };
    byStaff[key].count++;
    byStaff[key].revenue += Number(b.paymentAmount || 0);
  });
  const staffData    = Object.entries(byStaff).sort((a, b) => b[1].count - a[1].count).slice(0, 7);
  const hasStaffData = staffData.length > 0;
  const staffColors  = ["#7aa7ff", "var(--accent)", "#a78bfa", "#6ee7a3", "#f59e9e", "#94a3b8", "#fbbf24"];

  // ── By day of week (selected year) ───────────────────────────
  const DOW_LABELS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
  const byDow = Array(7).fill(0);
  yearConfirmed.forEach(b => {
    if (!b.date) return;
    byDow[new Date(b.date + "T12:00:00").getDay()]++;
  });

  // ── By hour (selected year) ───────────────────────────────────
  const byHour = {};
  yearConfirmed.forEach(b => {
    if (!b.time) return;
    const match = b.time.match(/(\d+):\d+\s*(AM|PM)/i);
    if (!match) { const m24 = b.time.match(/^(\d{1,2}):/); if (m24) { byHour[Number(m24[1])] = (byHour[Number(m24[1])] || 0) + 1; } return; }
    let h = Number(match[1]);
    const ampm = match[2].toUpperCase();
    if (ampm === "PM" && h !== 12) h += 12;
    if (ampm === "AM" && h === 12) h = 0;
    byHour[h] = (byHour[h] || 0) + 1;
  });
  const hourEntries = Object.entries(byHour).sort((a, b) => Number(b[1]) - Number(a[1])).slice(0, 3);

  // ── Trend badge helper ────────────────────────────────────────
  const TrendBadge = ({ trend }) => {
    if (!trend) return null;
    const color = trend.up ? "#10b981" : "#ef4444";
    return (
      <span style={{ fontSize: 11, fontWeight: 700, color, marginLeft: 6 }}>
        {trend.up ? "▲" : "▼"} {Math.abs(trend.pct)}% MoM
      </span>
    );
  };

  const KPI_DATA = [
    { label: "Total revenue",      value: formatMoney(totalRevenue,  currency), sub: `${viewYear} confirmed bookings`, trend: viewYear === curYear ? momRevT : null },
    { label: "Confirmed bookings",  value: String(totalBookings),               sub: `${yearAll.length} total incl. cancelled`, trend: viewYear === curYear ? momBkTrend : null },
    { label: "Avg booking value",   value: formatMoney(avgValue,      currency), sub: "per confirmed booking" },
    { label: "Show rate",           value: `${showRate}%`,                      sub: "confirmed vs total" },
    { label: "Coupon savings given",value: formatMoney(totalDiscount, currency), sub: "total discount applied" },
  ];

  return (
    <>
      <div className="view-h">
        <div>
          <h1>Analytics</h1>
          <div className="sub">Performance overview derived from your booking history.</div>
        </div>
        <div className="view-actions" style={{alignItems:"center", gap:10}}>
          {/* Year navigator */}
          <div style={{display:"flex", alignItems:"center", gap:6, background:"var(--surface-2)", border:"1px solid var(--border)", borderRadius:8, padding:"4px 8px"}}>
            <button className="btn ghost" style={{padding:"2px 6px", minWidth:"unset", fontSize:14}} onClick={() => setViewYear(y => y - 1)}>‹</button>
            <span style={{fontSize:13, fontWeight:600, minWidth:40, textAlign:"center"}}>{viewYear}</span>
            <button className="btn ghost" style={{padding:"2px 6px", minWidth:"unset", fontSize:14, opacity: viewYear >= curYear ? 0.35 : 1}} disabled={viewYear >= curYear} onClick={() => setViewYear(y => y + 1)}>›</button>
          </div>
          <button className="btn ghost" onClick={() => downloadCsv(`nexus-analytics-${viewYear}.csv`, [
            ["Month", "Revenue", "Bookings"],
            ...monthData.map(m => [m.label, m.revenue, m.count]),
          ])}><I.arrow size={13}/> Export CSV</button>
        </div>
      </div>

      {/* KPI strip */}
      <div className="analytics-kpi-strip">
        {KPI_DATA.map(k => (
          <div key={k.label} className="analytics-kpi">
            <div className="analytics-kpi-v" style={{display:"flex", alignItems:"center", flexWrap:"wrap", gap:4}}>
              {k.value}
              {k.trend && <TrendBadge trend={k.trend}/>}
            </div>
            <div className="analytics-kpi-l">{k.label}</div>
            <div className="analytics-kpi-sub">{k.sub}</div>
          </div>
        ))}
      </div>

      {/* Revenue + count charts */}
      <div className="analytics-row">
        <div className="card analytics-card-lg">
          <div className="card-h"><h3>Revenue by month</h3><span className="sub">{viewYear} — all 12 months</span></div>
          {totalRevenue === 0
            ? <div className="analytics-empty">No revenue data for {viewYear}.</div>
            : <MiniBarChart bars={monthData.map(m => ({ label: m.label, value: m.revenue }))} color="var(--accent)" showMoney currency={currency}/>
          }
        </div>
        <div className="card analytics-card-sm">
          <div className="card-h"><h3>Bookings by month</h3><span className="sub">{viewYear}</span></div>
          {totalBookings === 0
            ? <div className="analytics-empty">No bookings for {viewYear}.</div>
            : <MiniBarChart bars={monthData.map(m => ({ label: m.label, value: m.count }))} color="#7aa7ff"/>
          }
        </div>
      </div>

      {/* Revenue by service + revenue by staff */}
      {totalRevenue > 0 && (
        <div className="analytics-row">
          <div className="card analytics-card-lg">
            <div className="card-h"><h3>Revenue by service</h3></div>
            <div className="svc-breakdown">
              {svcData.map(([name, vals], i) => (
                <div key={name} className="svc-row">
                  <div className="svc-name">{name}</div>
                  <div className="svc-bar-wrap">
                    <div className="svc-bar" style={{ width: `${Math.round((vals.revenue / svcRevMax) * 100)}%`, background: svcColors[i % svcColors.length] }}/>
                  </div>
                  <div className="svc-count">{formatMoney(vals.revenue, currency)}</div>
                </div>
              ))}
            </div>
          </div>
          <div className="card analytics-card-sm">
            {hasStaffData ? (
              <>
                <div className="card-h"><h3>Revenue by staff</h3></div>
                <div className="svc-breakdown">
                  {staffData.map(([name, vals], i) => (
                    <div key={name} className="svc-row">
                      <div className="svc-name">{name}</div>
                      <div className="svc-bar-wrap">
                        <div className="svc-bar" style={{ width: `${Math.round((vals.count / (staffData[0]?.[1]?.count || 1)) * 100)}%`, background: staffColors[i % staffColors.length] }}/>
                      </div>
                      <div className="svc-count" style={{fontSize:12}}>{vals.count}×<br/><span style={{fontSize:11,color:"var(--text-muted)"}}>{formatMoney(vals.revenue, currency)}</span></div>
                    </div>
                  ))}
                </div>
              </>
            ) : (
              <>
                <div className="card-h"><h3>Staff breakdown</h3></div>
                <div className="analytics-empty" style={{fontSize:13}}>Assign staff to bookings to see breakdown.</div>
              </>
            )}
          </div>
        </div>
      )}

      {/* Service + day breakdown */}
      <div className="analytics-row">
        <div className="card analytics-card-lg">
          <div className="card-h"><h3>Bookings by service</h3></div>
          {svcData.length === 0
            ? <div className="analytics-empty">No booking data yet.</div>
            : (
              <div className="svc-breakdown">
                {svcData.map(([name, vals], i) => (
                  <div key={name} className="svc-row">
                    <div className="svc-name">{name}</div>
                    <div className="svc-bar-wrap">
                      <div className="svc-bar" style={{ width: `${Math.round((vals.count / svcMax) * 100)}%`, background: svcColors[i % svcColors.length] }}/>
                    </div>
                    <div className="svc-count">{vals.count}</div>
                  </div>
                ))}
              </div>
            )
          }
        </div>
        <div className="card analytics-card-sm">
          <div className="card-h"><h3>Busiest days</h3></div>
          <MiniBarChart bars={byDow.map((v, i) => ({ label: DOW_LABELS[i], value: v }))} color="#a78bfa"/>
          {hourEntries.length > 0 && (
            <div style={{ marginTop: 16, paddingTop: 14, borderTop: "1px solid var(--border)" }}>
              <div style={{ fontSize: 11, fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.06em", color: "var(--text-muted)", marginBottom: 8 }}>
                Peak hours
              </div>
              {hourEntries.map(([h, count]) => {
                const hr = Number(h);
                const label = hr === 0 ? "12:00 AM" : hr < 12 ? `${hr}:00 AM` : hr === 12 ? "12:00 PM" : `${hr - 12}:00 PM`;
                return (
                  <div key={h} className="peak-hour-row">
                    <span className="peak-hour-label">{label}</span>
                    <span className="peak-hour-count">{count} booking{count !== 1 ? "s" : ""}</span>
                  </div>
                );
              })}
            </div>
          )}
        </div>
      </div>
    </>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Setup Guide
// ──────────────────────────────────────────────────────────────────────────

function SetupIcon({ name, size = 18, color = "#006e78" }) {
  const ic = {
    bolt:      <path d="M13 3 5 14h6l-1 7 8-11h-6z"/>,
    brand:     <><circle cx="12" cy="8" r="4"/><path d="M4 20c0-3.3 3.6-6 8-6s8 2.7 8 6"/></>,
    events:    <><rect x="5" y="3" width="14" height="18" rx="2"/><path d="M9 8h6M9 12h6M9 16h4"/></>,
    clock:     <><circle cx="12" cy="12" r="8.5"/><path d="M12 7.5V12l3 2"/></>,
    card:      <><rect x="3.5" y="6" width="17" height="13" rx="2"/><path d="M3.5 10.5h17"/></>,
    calendar:  <><rect x="3.5" y="5" width="17" height="15.5" rx="2"/><path d="M3.5 9.5h17M8 3v4M16 3v4"/></>,
    users:     <><circle cx="9" cy="9" r="3.2"/><path d="M3.5 19c.6-3 2.9-4.6 5.5-4.6s4.9 1.6 5.5 4.6"/><circle cx="17" cy="8.5" r="2.6"/><path d="M16 14.5c2 0 4.1 1.2 4.5 4"/></>,
    link:      <><path d="M10 14a3.5 3.5 0 0 1 0-5l3-3a3.5 3.5 0 0 1 5 5l-1.5 1.5"/><path d="M14 10a3.5 3.5 0 0 1 0 5l-3 3a3.5 3.5 0 0 1-5-5l1.5-1.5"/></>,
    image:     <><rect x="3" y="5" width="18" height="14" rx="2"/><circle cx="8.5" cy="10" r="1.5"/><path d="m21 15-5-5-4.5 5-3-3-5.5 6"/></>,
    mail:      <><rect x="3" y="5" width="18" height="14" rx="2"/><path d="m3 7 9 6 9-6"/></>,
    phone:     <path d="M6.5 4h3l1.5 4-2 1.5a11 11 0 0 0 5.5 5.5L16 13l4 1.5v3a1.5 1.5 0 0 1-1.5 1.5A16.5 16.5 0 0 1 5 5.5 1.5 1.5 0 0 1 6.5 4z"/>,
    compass:   <><circle cx="12" cy="12" r="8.5"/><path d="m16.2 7.8-2.3 6.4-6.1 2.1 2-6.1 6.4-2.4z"/></>,
    info:      <><circle cx="12" cy="12" r="8.5"/><path d="M12 8v.5M12 11v5"/></>,
    target:    <><circle cx="12" cy="12" r="9"/><circle cx="12" cy="12" r="5"/><circle cx="12" cy="12" r="1.5"/></>,
    rotate:    <><path d="M21 2v6h-6"/><path d="M3 12a9 9 0 0 1 15-6.7L21 8"/><path d="M3 22v-6h6"/><path d="M21 12a9 9 0 0 1-15 6.7L3 16"/></>,
    clipboard: <><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/><rect x="8" y="2" width="8" height="4" rx="1"/><path d="M9 12h6M9 16h4"/></>,
    camera:    <><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></>,
    thumbs:    <><path d="M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.3a2 2 0 0 0 2-1.7l1.4-9a2 2 0 0 0-2-2.3H14z"/><path d="M7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3"/></>,
    briefcase: <><rect x="2" y="7" width="20" height="14" rx="2"/><path d="M16 7V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v2M12 12v4M10 14h4"/></>,
    twitter:   <path d="M4 4 20 20M20 4 4 20"/>,
    globe:     <><circle cx="12" cy="12" r="8.5"/><path d="M3.5 12h17M12 3.5c2.5 3 2.5 14 0 17M12 3.5c-2.5 3-2.5 14 0 17"/></>,
    color:     <><path d="M12 21a9 9 0 0 0 9-9c0-5-9-13-9-13S3 7 3 12a9 9 0 0 0 9 9z"/></>,
    share:     <><circle cx="18" cy="5" r="2.5"/><circle cx="6" cy="12" r="2.5"/><circle cx="18" cy="19" r="2.5"/><path d="m8.3 13.2 7.4 4.3M15.7 6.5 8.3 10.8"/></>,
  };
  return (
    <svg viewBox="0 0 24 24" width={size} height={size}
      fill="none" stroke={color} strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round">
      {ic[name] || null}
    </svg>
  );
}

function SetupExternalLink({ href, children }) {
  return (
    <a href={href} target="_blank" rel="noopener noreferrer" className="setup-link">
      {children}
    </a>
  );
}

function SetupNavHint({ children }) {
  return (
    <div className="setup-nav-hint">
      <SetupIcon name="compass" size={16}/>
      <span>{children}</span>
    </div>
  );
}

function SetupTip({ children }) {
  return (
    <div className="setup-tip" style={{display:"flex", alignItems:"flex-start", gap:8}}>
      <SetupIcon name="info" size={15} style={{marginTop:1, flexShrink:0}}/>
      <span><strong>Tip: </strong>{children}</span>
    </div>
  );
}

function SetupStep({ num, title, children }) {
  return (
    <div className="setup-step">
      <div className="setup-step-num">{num}</div>
      <div className="setup-step-body">
        <strong>{title}</strong>
        <p>{children}</p>
      </div>
    </div>
  );
}

// ── Getting Started ───────────────────────────────────────────
function SetupStart() {
  const STEPS = [
    { icon:"brand",    label:"Profile & Branding",      desc:"Add your business name, logo, and brand colour" },
    { icon:"events",   label:"Event Types",             desc:"Create the services or sessions you offer" },
    { icon:"clock",    label:"Availability",            desc:"Set your working hours and block time off" },
    { icon:"card",     label:"Payments",                desc:"Connect Stripe or PayPal to take payments" },
    { icon:"calendar", label:"Calendar & Integrations", desc:"Sync with Google Calendar, Apple Calendar, Twilio & WhatsApp" },
    { icon:"users",    label:"Team Members",            desc:"Invite staff and assign them to services" },
    { icon:"link",     label:"Booking Page",            desc:"Share your unique booking link with clients" },
  ];
  const NEED = [
    { icon:"image",    label:"Logo image",              desc:"PNG or JPG, square format, at least 200×200px" },
    { icon:"color",    label:"Brand colour",            desc:"Your brand hex code, e.g. #006e78" },
    { icon:"card",     label:"Stripe or PayPal account", desc:"Free to create at stripe.com or paypal.com" },
    { icon:"mail",     label:"Business email",          desc:"Used for client booking confirmations" },
    { icon:"phone",    label:"Phone / WhatsApp number", desc:"Optional — used for client SMS reminders" },
    { icon:"calendar", label:"Google account",          desc:"For two-way calendar sync (optional)" },
  ];
  return (
    <div>
      <div className="setup-card-full" style={{background:"linear-gradient(135deg, var(--surface) 0%, rgba(239,164,3,0.05) 100%)"}}>
        <div style={{display:"flex", alignItems:"center", gap:18, marginBottom:24}}>
          <img src="icon/nexus-bookings-icon.png" alt="" style={{width:56, height:56, borderRadius:14, flexShrink:0}}/>
          <div>
            <h2 style={{margin:"0 0 4px", fontSize:20, fontWeight:600}}>Welcome to Nexus Booking</h2>
            <p style={{margin:0, color:"var(--text-muted)", fontSize:13.5, lineHeight:1.5}}>Follow the tabs above to configure your booking system. It typically takes under 10 minutes.</p>
          </div>
        </div>
        <div style={{display:"grid", gridTemplateColumns:"repeat(auto-fill, minmax(210px, 1fr))", gap:10}}>
          {STEPS.map((s, i) => (
            <div key={i} style={{padding:"13px 14px", background:"var(--surface)", borderRadius:10, border:"1px solid var(--border)", display:"flex", alignItems:"flex-start", gap:10}}>
              <span style={{minWidth:24, paddingTop:1, flexShrink:0}}><SetupIcon name={s.icon} size={20}/></span>
              <div>
                <div style={{fontWeight:600, fontSize:13, marginBottom:3}}>{s.label}</div>
                <div style={{fontSize:12, color:"var(--text-muted)", lineHeight:1.5}}>{s.desc}</div>
              </div>
            </div>
          ))}
        </div>
      </div>
      <div className="setup-card-full">
        <h3 style={{margin:"0 0 4px"}}>Before you begin — what you'll need</h3>
        <p style={{margin:"0 0 18px", color:"var(--text-muted)", fontSize:13}}>Gather these things before going through the setup tabs.</p>
        <div style={{display:"grid", gridTemplateColumns:"repeat(auto-fill, minmax(240px, 1fr))", gap:10}}>
          {NEED.map((item, i) => (
            <div key={i} style={{display:"flex", gap:12, alignItems:"flex-start", padding:"12px 14px", background:"var(--surface-2)", borderRadius:10, border:"1px solid var(--border)"}}>
              <span style={{paddingTop:1, flexShrink:0}}><SetupIcon name={item.icon} size={20}/></span>
              <div>
                <div style={{fontWeight:600, fontSize:13}}>{item.label}</div>
                <div style={{fontSize:12.5, color:"var(--text-muted)", marginTop:2, lineHeight:1.5}}>{item.desc}</div>
              </div>
            </div>
          ))}
        </div>
        <div style={{marginTop:20, padding:"14px 18px", background:"var(--accent-soft)", border:"1px solid rgba(239,164,3,0.25)", borderRadius:10, fontSize:13, color:"var(--text)", lineHeight:1.6}}>
          <strong style={{color:"var(--accent)"}}>→ Ready to go?</strong> Start with <strong>Profile & Branding</strong> and work your way through each tab. Use the sidebar links to jump straight to each section as you set it up.
        </div>
      </div>
    </div>
  );
}

// ── Profile & Branding ────────────────────────────────────────
function SetupProfile() {
  return (
    <div>
      <div className="setup-grid">
        <div className="setup-card">
          <h3 style={{margin:"0 0 4px"}}>Profile & Branding</h3>
          <p style={{margin:"0 0 20px", color:"var(--text-muted)", fontSize:13}}>Your business identity — appears on your booking page and client emails.</p>
          <div className="setup-steps">
            <SetupStep num={1} title="Open Settings → Profile">
              Click <strong>Settings</strong> in the left sidebar, then select the <strong>Profile</strong> tab at the top of the page.
            </SetupStep>
            <SetupStep num={2} title="Enter your business name">
              Type your brand or company name in the <em>Brand Name</em> field. This is the name displayed prominently on your booking page.
            </SetupStep>
            <SetupStep num={3} title="Upload a logo">
              Paste a publicly accessible URL to your logo image. PNG or JPG format recommended — square images look best. You can host images free at{" "}
              <SetupExternalLink href="https://imgur.com">imgur.com ↗</SetupExternalLink> or{" "}
              <SetupExternalLink href="https://cloudinary.com">Cloudinary ↗</SetupExternalLink>.
            </SetupStep>
            <SetupStep num={4} title="Pick your brand colour">
              Select one of the colour swatches or enter a custom hex code. This accent colour tints buttons, links, and highlights on your booking page.
            </SetupStep>
            <SetupStep num={5} title="Set your currency and timezone">
              Choose the currency shown on all prices and invoices. Set your timezone so slots display in the correct local time for your clients.
            </SetupStep>
            <SetupStep num={6} title="Save your changes">
              Click <strong>Save profile</strong>. Changes are applied immediately — refresh your booking page to see them live.
            </SetupStep>
          </div>
          <SetupNavHint>Go to: <strong>Settings → Profile tab</strong></SetupNavHint>
        </div>
        <div style={{display:"flex", flexDirection:"column", gap:16}}>
          <div className="setup-card">
            <h3 style={{margin:"0 0 4px"}}>Company Information</h3>
            <p style={{margin:"0 0 20px", color:"var(--text-muted)", fontSize:13}}>Display your address, contact details, and social links on the booking page.</p>
            <div className="setup-steps">
              <SetupStep num={1} title="Open Settings → Company tab">
                Enter your business address, phone number, VAT or company number, and website URL.
              </SetupStep>
              <SetupStep num={2} title="Add social media links">
                Paste in links to Instagram, Facebook, Twitter/X, and LinkedIn. These appear as clickable icons on your public booking page.
              </SetupStep>
              <SetupStep num={3} title="Pin your location on the map">
                Search for your address using the built-in map tool to pin your exact location. Clients will see a map on your booking page showing where you are.
              </SetupStep>
            </div>
            <SetupNavHint>Go to: <strong>Settings → Company tab</strong></SetupNavHint>
          </div>
          <div className="setup-card">
            <h3 style={{margin:"0 0 4px"}}>Booking Page Customisation</h3>
            <p style={{margin:"0 0 20px", color:"var(--text-muted)", fontSize:13}}>Personalise what clients see when they visit your booking link.</p>
            <div className="setup-steps">
              <SetupStep num={1} title="Open Settings → Booking Page tab">
                Write a welcome message shown at the top of your booking page and a custom message sent after a booking is confirmed.
              </SetupStep>
              <SetupStep num={2} title="Set booking preferences">
                Choose minimum notice time (e.g. 2 hours), maximum advance booking window (e.g. 60 days), and whether clients must create an account before booking.
              </SetupStep>
            </div>
            <SetupTip>A minimum notice of 2–4 hours prevents last-minute bookings you may not be prepared for.</SetupTip>
            <SetupNavHint>Go to: <strong>Settings → Booking Page tab</strong></SetupNavHint>
          </div>
        </div>
      </div>
    </div>
  );
}

// ── Event Types ───────────────────────────────────────────────
function SetupEvents() {
  return (
    <div>
      <div className="setup-grid">
        <div className="setup-card">
          <h3 style={{margin:"0 0 4px"}}>Creating Your First Event Type</h3>
          <p style={{margin:"0 0 20px", color:"var(--text-muted)", fontSize:13}}>Event types are the services or sessions clients can book. You need at least one to start accepting bookings.</p>
          <div className="setup-steps">
            <SetupStep num={1} title="Go to Event Types">
              Click <strong>Event Types</strong> in the left sidebar to open the services manager.
            </SetupStep>
            <SetupStep num={2} title='Click "+ Add service"'>
              Click the <strong>+ Add service</strong> button in the top-right corner. A form will appear to define the new service.
            </SetupStep>
            <SetupStep num={3} title="Fill in the details">
              Enter a clear service name (e.g. "60-min Consultation"), a description clients will see, the duration in minutes, and the price.
            </SetupStep>
            <SetupStep num={4} title="Choose a colour">
              Pick a colour for this service. It appears on your calendar to make different services easy to distinguish at a glance.
            </SetupStep>
            <SetupStep num={5} title="Set capacity">
              Leave capacity at 1 for 1-to-1 appointments. Increase it for group classes or workshops where multiple clients share the same slot.
            </SetupStep>
            <SetupStep num={6} title="Enable and save">
              Toggle the service <em>on</em> and click <strong>Save</strong>. It immediately appears on your booking page for clients to select.
            </SetupStep>
          </div>
          <SetupNavHint>Go to: <strong>Event Types</strong> in the sidebar</SetupNavHint>
        </div>
        <div style={{display:"flex", flexDirection:"column", gap:16}}>
          <div className="setup-card">
            <h3 style={{margin:"0 0 4px"}}>Buffer Time & Add-ons</h3>
            <p style={{margin:"0 0 20px", color:"var(--text-muted)", fontSize:13}}>Prevent back-to-back bookings and offer optional paid extras.</p>
            <div className="setup-steps">
              <SetupStep num={1} title="Add buffer time">
                Set a buffer (e.g. 15 min) before or after each booking. This automatically blocks that time so you can prepare, travel, or reset between appointments.
              </SetupStep>
              <SetupStep num={2} title="Create add-ons">
                Add optional paid extras that clients can select at checkout — for example "Extended session +£20" or "Premium materials +£10".
              </SetupStep>
            </div>
            <SetupTip>A 10–15 min buffer dramatically reduces the stress of back-to-back appointments and helps keep your schedule on track.</SetupTip>
          </div>
          <div className="setup-card">
            <h3 style={{margin:"0 0 4px"}}>Custom Availability per Service</h3>
            <p style={{margin:"0 0 20px", color:"var(--text-muted)", fontSize:13}}>Some services may only run on certain days or at different hours.</p>
            <div className="setup-steps">
              <SetupStep num={1} title="Enable custom availability">
                When editing an event type, toggle on <em>Use custom availability</em> to override your global schedule for this service only.
              </SetupStep>
              <SetupStep num={2} title="Set specific days and hours">
                Choose which days and time ranges this service is available, completely independently of your general working hours.
              </SetupStep>
            </div>
            <div style={{marginTop:16, padding:"14px 16px", background:"var(--surface-2)", borderRadius:10, border:"1px solid var(--border)"}}>
              <div style={{fontWeight:600, fontSize:13, marginBottom:6}}>Example use cases</div>
              <div style={{display:"flex", flexDirection:"column", gap:6}}>
                {[
                  "Yoga class only on Monday evenings",
                  "Consultations only Tuesday – Thursday",
                  "Weekend sessions with different hours",
                ].map((ex, i) => (
                  <div key={i} style={{display:"flex", gap:8, fontSize:12.5, color:"var(--text-muted)"}}>
                    <span style={{color:"var(--accent)"}}>→</span>
                    <span>{ex}</span>
                  </div>
                ))}
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

// ── Availability ──────────────────────────────────────────────
function SetupAvailability() {
  const DAYS = ["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"];
  return (
    <div>
      <div className="setup-grid">
        <div className="setup-card">
          <h3 style={{margin:"0 0 4px"}}>Setting Your Working Hours</h3>
          <p style={{margin:"0 0 20px", color:"var(--text-muted)", fontSize:13}}>Tell Nexus Booking when you're available so clients can only book during those times.</p>
          <div className="setup-steps">
            <SetupStep num={1} title="Go to Availability">
              Click <strong>Availability</strong> in the left sidebar.
            </SetupStep>
            <SetupStep num={2} title="Toggle your working days">
              Use the toggle switches to turn each day on or off. Days switched off show as unavailable — clients won't see any slots on those days.
            </SetupStep>
            <SetupStep num={3} title="Set start and end times">
              For each active day, set when you start and finish. For example, 9:00 AM – 5:30 PM. Use the dropdowns or type directly.
            </SetupStep>
            <SetupStep num={4} title="Save your schedule">
              Click <strong>Save availability</strong>. Your booking page immediately reflects your updated hours.
            </SetupStep>
          </div>
          <SetupNavHint>Go to: <strong>Availability</strong> in the sidebar</SetupNavHint>
        </div>
        <div style={{display:"flex", flexDirection:"column", gap:16}}>
          <div className="setup-card">
            <h3 style={{margin:"0 0 4px"}}>Visual: Weekly Schedule Example</h3>
            <p style={{margin:"0 0 14px", color:"var(--text-muted)", fontSize:13}}>A typical Mon–Fri working week with weekends off.</p>
            <div style={{display:"flex", flexDirection:"column", gap:6}}>
              {DAYS.map((day, i) => (
                <div key={day} style={{display:"flex", alignItems:"center", gap:10, padding:"9px 12px", background:"var(--surface-2)", borderRadius:8, border:"1px solid var(--border)"}}>
                  <div style={{width:8, height:8, borderRadius:"50%", background: i >= 5 ? "var(--border-strong)" : "#6ee7a3", flexShrink:0}}/>
                  <span style={{minWidth:90, fontWeight:500, fontSize:13}}>{day}</span>
                  <span style={{fontSize:13, color: i >= 5 ? "var(--text-faint)" : "var(--text-muted)"}}>
                    {i >= 5 ? "Unavailable" : "9:00 AM – 5:30 PM"}
                  </span>
                </div>
              ))}
            </div>
          </div>
          <div className="setup-card">
            <h3 style={{margin:"0 0 4px"}}>Blocking Specific Dates</h3>
            <p style={{margin:"0 0 20px", color:"var(--text-muted)", fontSize:13}}>Block individual dates for holidays, training, or any time off.</p>
            <div className="setup-steps">
              <SetupStep num={1} title="Find the Blocked Dates section">
                Scroll down on the Availability page to the <em>Block a specific date</em> section.
              </SetupStep>
              <SetupStep num={2} title="Select the date and reason">
                Pick the date, optionally add a reason for your own records, and click <strong>Add blocked date</strong>.
              </SetupStep>
              <SetupStep num={3} title="Remove blocked dates">
                Blocked dates appear in a list. Click the <strong>✕</strong> icon next to any date to make it available again.
              </SetupStep>
            </div>
            <SetupTip>Existing bookings on a blocked date are not automatically cancelled — you'll need to reschedule those clients manually from the Bookings tab.</SetupTip>
            <SetupNavHint>Go to: <strong>Availability</strong> in the sidebar</SetupNavHint>
          </div>
        </div>
      </div>
    </div>
  );
}

// ── Payments ──────────────────────────────────────────────────
function SetupPayments() {
  return (
    <div>
      <div className="setup-card-full">
        <h3 style={{margin:"0 0 4px"}}>Accepting Payments Online</h3>
        <p style={{margin:"0 0 16px", color:"var(--text-muted)", fontSize:13}}>Connect a payment provider so clients can pay at the time of booking. Both Stripe and PayPal are supported — you can enable one or both.</p>
        <div style={{display:"grid", gridTemplateColumns:"repeat(auto-fill, minmax(200px, 1fr))", gap:10}}>
          {[
            { icon:Bl.stripe, name:"Stripe", note:"Cards, Apple Pay, Google Pay. Best for UK/EU businesses." },
            { icon:Bl.paypal, name:"PayPal",  note:"Widely trusted globally. Clients can pay without entering card details." },
          ].map((p, i) => (
            <div key={i} style={{display:"flex", gap:12, alignItems:"center", padding:"14px 16px", background:"var(--surface-2)", borderRadius:10, border:"1px solid var(--border)"}}>
              <div style={{width:40, height:40, minWidth:40, borderRadius:10, overflow:"hidden", flexShrink:0}}>{p.icon}</div>
              <div>
                <div style={{fontWeight:600, fontSize:13}}>{p.name}</div>
                <div style={{fontSize:12, color:"var(--text-muted)", marginTop:2, lineHeight:1.5}}>{p.note}</div>
              </div>
            </div>
          ))}
        </div>
      </div>
      <div className="setup-grid">
        <div className="setup-card">
          <div style={{display:"flex", alignItems:"center", gap:12, padding:"14px 16px", background:"var(--surface-2)", borderRadius:10, border:"1px solid var(--border)", marginBottom:20}}>
            <div style={{width:44, height:44, minWidth:44, borderRadius:10, overflow:"hidden", flexShrink:0}}>{Bl.stripe}</div>
            <div>
              <div style={{fontWeight:600, fontSize:14}}>Stripe</div>
              <div style={{fontSize:12.5, color:"var(--text-muted)", marginBottom:6}}>Industry-leading payment platform. ~1.4% + 20p per UK card transaction.</div>
              <SetupExternalLink href="https://stripe.com/gb">Create a free Stripe account ↗</SetupExternalLink>
            </div>
          </div>
          <div className="setup-steps">
            <SetupStep num={1} title="Create a Stripe account">
              Visit <SetupExternalLink href="https://stripe.com/gb">stripe.com/gb ↗</SetupExternalLink> and sign up. You'll verify your identity and bank details during onboarding — this usually takes 5–10 minutes.
            </SetupStep>
            <SetupStep num={2} title="Get your API keys">
              In your Stripe Dashboard, go to <strong>Developers → API keys</strong>. Copy both your <em>Publishable key</em> (starts with <code style={{background:"var(--surface-3)",padding:"1px 5px",borderRadius:4,fontFamily:"monospace",fontSize:11.5}}>pk_</code>) and your <em>Secret key</em> (starts with <code style={{background:"var(--surface-3)",padding:"1px 5px",borderRadius:4,fontFamily:"monospace",fontSize:11.5}}>sk_</code>).
            </SetupStep>
            <SetupStep num={3} title="Connect in Nexus Booking">
              Go to <strong>Integrations</strong> in the sidebar, find the Stripe card, click <strong>Connect Stripe</strong>, and paste both API keys into the fields provided.
            </SetupStep>
            <SetupStep num={4} title="Test a payment">
              Use Stripe's test card <code style={{background:"var(--surface-3)",padding:"2px 6px",borderRadius:4,fontFamily:"monospace",fontSize:11.5}}>4242 4242 4242 4242</code> with any future expiry and any 3-digit CVC to make a test booking without charging anyone.
            </SetupStep>
          </div>
          <SetupTip>Use <strong>test mode</strong> in Stripe (the toggle at the top of your Stripe Dashboard) until you're happy everything works, then switch to live mode.</SetupTip>
          <SetupNavHint>Go to: <strong>Integrations → Stripe</strong></SetupNavHint>
        </div>
        <div className="setup-card">
          <div style={{display:"flex", alignItems:"center", gap:12, padding:"14px 16px", background:"var(--surface-2)", borderRadius:10, border:"1px solid var(--border)", marginBottom:20}}>
            <div style={{width:44, height:44, minWidth:44, borderRadius:10, overflow:"hidden", flexShrink:0}}>{Bl.paypal}</div>
            <div>
              <div style={{fontWeight:600, fontSize:14}}>PayPal</div>
              <div style={{fontSize:12.5, color:"var(--text-muted)", marginBottom:6}}>Trusted globally. Clients pay without entering card details.</div>
              <SetupExternalLink href="https://www.paypal.com/gb/webapps/mpp/merchant">Create a PayPal Business account ↗</SetupExternalLink>
            </div>
          </div>
          <div className="setup-steps">
            <SetupStep num={1} title="Create a PayPal Business account">
              Visit <SetupExternalLink href="https://www.paypal.com/gb/webapps/mpp/merchant">paypal.com/gb ↗</SetupExternalLink> and sign up for or upgrade to a Business account. Personal accounts cannot accept business payments.
            </SetupStep>
            <SetupStep num={2} title="Get your Client ID">
              Go to the PayPal Developer Dashboard at <SetupExternalLink href="https://developer.paypal.com/dashboard/">developer.paypal.com ↗</SetupExternalLink>, create a new App, and copy the <em>Client ID</em> shown.
            </SetupStep>
            <SetupStep num={3} title="Connect in Nexus Booking">
              Go to <strong>Integrations</strong> in the sidebar, find the PayPal card, and enter your Client ID to activate PayPal checkout on your booking page.
            </SetupStep>
          </div>
          <div style={{marginTop:16, padding:"13px 15px", background:"rgba(110,231,163,0.1)", border:"1px solid rgba(110,231,163,0.25)", borderRadius:10, fontSize:13, lineHeight:1.6}}>
            <strong style={{color:"#15803d"}}>✓ Use both</strong> — you can have Stripe and PayPal active at the same time, giving clients their preferred way to pay.
          </div>
          <SetupNavHint>Go to: <strong>Integrations → PayPal</strong></SetupNavHint>
        </div>
      </div>
    </div>
  );
}

// ── Calendar & Integrations ───────────────────────────────────
function SetupCalendar() {
  const APPS = [
    {
      icon: Bl.gcal, name:"Google Calendar",
      desc:"Two-way sync — bookings appear in Google Calendar and existing events automatically block time in Nexus.",
      link:"https://calendar.google.com", linkLabel:"Open Google Calendar ↗",
      steps:[
        { t:"Go to Integrations", d:'Click Integrations in the left sidebar and find the Google Calendar card.' },
        { t:'Click "Connect Google Calendar"', d:"Sign in to your Google account and grant Nexus read/write access to your calendar." },
        { t:"Verify the sync", d:"Create a test booking and confirm it appears in Google Calendar within a few seconds." },
      ],
      tip:"If you share your Google Calendar with a team, all new bookings also appear on their calendars automatically.",
    },
    {
      icon: Bl.apple, name:"Apple Calendar",
      desc:"Sync bookings to your iCloud calendar both ways via CalDAV. Works with the Calendar app on all your Apple devices.",
      link:"https://appleid.apple.com", linkLabel:"Manage your Apple ID ↗",
      steps:[
        { t:"Generate an app-specific password", d:'Go to appleid.apple.com → Sign In → App-Specific Passwords, then click the + button. Name it "Nexus Booking" and copy the generated password.' },
        { t:"Connect in Nexus", d:"Go to Integrations, find the Apple Calendar card, and enter your Apple ID email and the app-specific password." },
        { t:"Verify the sync", d:"Create a test booking and check it appears in your Apple Calendar app within a few seconds." },
      ],
      tip:"Apple Calendar uses an app-specific password rather than your main Apple ID password — this is more secure and can be revoked at any time from appleid.apple.com.",
    },
    {
      icon: Bl.twilio, name:"Twilio SMS",
      desc:"Send SMS booking confirmations and reminders directly to guests. Requires your own Twilio account.",
      link:"https://www.twilio.com/try-twilio", linkLabel:"Create a free Twilio account ↗",
      steps:[
        { t:"Create a Twilio account", d:'Go to twilio.com and sign up. Verify your email and phone number during onboarding.' },
        { t:"Get a Twilio phone number", d:'In your Twilio Console, go to Phone Numbers → Manage → Buy a number. Choose a UK (+44) number capable of sending SMS.' },
        { t:"Copy your credentials", d:'In the Twilio Console dashboard, copy your Account SID and Auth Token. Then copy your Twilio phone number.' },
        { t:"Connect in Nexus", d:"Go to Integrations, find the Twilio card, and paste your Account SID, Auth Token, and from number." },
      ],
      tip:"Twilio charges per SMS sent (typically 4–6p per message in the UK). Keep an eye on your Twilio usage dashboard to track costs.",
    },
    {
      icon: Bl.whatsapp, name:"WhatsApp Business",
      desc:"Send booking confirmations and reminders to guests via WhatsApp. Requires a WhatsApp Business account linked to a dedicated phone number.",
      link:"https://business.whatsapp.com", linkLabel:"Set up WhatsApp Business ↗",
      steps:[
        { t:"Set up WhatsApp Business", d:'Download the WhatsApp Business app (or use the WhatsApp Business API for higher volume). Register with a dedicated business phone number — this number cannot also be used on a personal WhatsApp account.' },
        { t:"Note your business phone number", d:'Make sure you have the full international format of your WhatsApp Business number ready (e.g. +441234567890).' },
        { t:"Connect in Nexus", d:"Go to Integrations, find the WhatsApp Business card, and enter your WhatsApp Business phone number." },
      ],
      tip:"Use a dedicated SIM or number for WhatsApp Business — you cannot use the same number on both WhatsApp and WhatsApp Business simultaneously.",
    },
  ];

  return (
    <div>
      <div className="setup-card-full">
        <h3 style={{margin:"0 0 4px"}}>Calendar & Messaging Integrations</h3>
        <p style={{margin:"0 0 16px", color:"var(--text-muted)", fontSize:13}}>Connect Nexus Booking to your calendar and messaging tools. Each integration is optional — set up only what you need.</p>
        <div style={{display:"grid", gridTemplateColumns:"repeat(auto-fill, minmax(180px,1fr))", gap:10}}>
          {APPS.map((app, i) => (
            <div key={i} style={{display:"flex", gap:10, alignItems:"center", padding:"11px 13px", background:"var(--surface-2)", borderRadius:10, border:"1px solid var(--border)"}}>
              <div style={{width:36, height:36, minWidth:36, borderRadius:8, overflow:"hidden", flexShrink:0}}>{app.icon}</div>
              <span style={{fontWeight:600, fontSize:13}}>{app.name}</span>
            </div>
          ))}
        </div>
      </div>
      {APPS.map((app, i) => (
        <div key={i} className="setup-card-full" style={{marginBottom:16}}>
          <div style={{display:"flex", alignItems:"flex-start", gap:14, marginBottom:20}}>
            <div style={{width:48, height:48, minWidth:48, borderRadius:12, overflow:"hidden", flexShrink:0}}>{app.icon}</div>
            <div>
              <div style={{fontWeight:700, fontSize:16, marginBottom:3}}>{app.name}</div>
              <div style={{fontSize:13, color:"var(--text-muted)", lineHeight:1.6, marginBottom:6}}>{app.desc}</div>
              <SetupExternalLink href={app.link}>{app.linkLabel}</SetupExternalLink>
            </div>
          </div>
          <div className="setup-grid" style={{marginBottom:0}}>
            <div className="setup-steps">
              {app.steps.map((s, j) => (
                <SetupStep key={j} num={j+1} title={s.t}>{s.d}</SetupStep>
              ))}
            </div>
            <div>
              {app.tip && <SetupTip>{app.tip}</SetupTip>}
              <SetupNavHint>Go to: <strong>Integrations → {app.name}</strong></SetupNavHint>
            </div>
          </div>
        </div>
      ))}
    </div>
  );
}

// ── Team Members ──────────────────────────────────────────────
function SetupTeam() {
  const ROUTING = [
    { icon:"target",    label:"Client chooses",  desc:"With staff selection enabled, clients pick their preferred team member at checkout — great for salons and studios." },
    { icon:"rotate",    label:"Round-robin",     desc:"Enable in Settings to distribute bookings equally across available staff, preventing anyone getting overloaded." },
    { icon:"clipboard", label:"Manual reassign", desc:"Any booking can be manually reassigned to a different team member from the Bookings tab at any time." },
  ];
  return (
    <div>
      <div className="setup-grid">
        <div className="setup-card">
          <h3 style={{margin:"0 0 4px"}}>Adding Team Members</h3>
          <p style={{margin:"0 0 20px", color:"var(--text-muted)", fontSize:13}}>Invite staff so bookings can be routed to the right person. Each member can have their own schedule and assigned services.</p>
          <div className="setup-steps">
            <SetupStep num={1} title="Go to Teams">
              Click <strong>Teams</strong> in the left sidebar to open the team manager.
            </SetupStep>
            <SetupStep num={2} title='Click "+ Add member"'>
              Enter the team member's full name, email address, and their role or job title (e.g. "Senior Stylist" or "Therapist").
            </SetupStep>
            <SetupStep num={3} title="Upload a profile photo (optional)">
              Paste a URL to their photo. Photos appear on your booking page and help clients choose who to book with — a professional headshot works best.
            </SetupStep>
            <SetupStep num={4} title="Assign to services">
              When editing an Event Type, select which team members can deliver that service. Clients will see a staff picker during the booking process.
            </SetupStep>
            <SetupStep num={5} title="Set individual availability">
              Each team member can have their own working hours. Edit their availability independently so their schedule is accurate.
            </SetupStep>
          </div>
          <SetupNavHint>Go to: <strong>Teams</strong> in the sidebar</SetupNavHint>
        </div>
        <div style={{display:"flex", flexDirection:"column", gap:16}}>
          <div className="setup-card">
            <h3 style={{margin:"0 0 4px"}}>How Booking Routing Works</h3>
            <p style={{margin:"0 0 14px", color:"var(--text-muted)", fontSize:13}}>Three ways bookings can be assigned to your team.</p>
            <div style={{display:"flex", flexDirection:"column", gap:10}}>
              {ROUTING.map((item, i) => (
                <div key={i} style={{display:"flex", gap:12, alignItems:"flex-start", padding:"12px 14px", background:"var(--surface-2)", borderRadius:10, border:"1px solid var(--border)"}}>
                  <span style={{paddingTop:1, flexShrink:0}}><SetupIcon name={item.icon} size={20}/></span>
                  <div>
                    <div style={{fontWeight:600, fontSize:13}}>{item.label}</div>
                    <div style={{fontSize:12.5, color:"var(--text-muted)", marginTop:3, lineHeight:1.5}}>{item.desc}</div>
                  </div>
                </div>
              ))}
            </div>
          </div>
          <div className="setup-card">
            <h3 style={{margin:"0 0 4px"}}>Staff Notifications</h3>
            <p style={{margin:"0 0 20px", color:"var(--text-muted)", fontSize:13}}>Make sure your team knows about their bookings.</p>
            <div className="setup-steps">
              <SetupStep num={1} title="Enable staff email notifications">
                Go to <strong>Settings → Notifications</strong> and toggle on <em>Staff email notifications</em>. Team members will receive an email each time a booking is made for them.
              </SetupStep>
              <SetupStep num={2} title="Enable reminder emails">
                Turn on <em>Staff reminders</em> to send a reminder email to staff the day before their appointments.
              </SetupStep>
            </div>
            <SetupNavHint>Go to: <strong>Settings → Notifications tab</strong></SetupNavHint>
          </div>
        </div>
      </div>
    </div>
  );
}

// ── Booking Page ──────────────────────────────────────────────
function SetupBookingPage() {
  const PLATFORMS = [
    { icon:"camera",    name:"Instagram",       tip:'Add to your bio link. In posts, write "Link in bio to book" and add to your Stories highlights.' },
    { icon:"thumbs",    name:"Facebook",        tip:"Add to your business Page's About section and pin a post with your booking link at the top of your feed." },
    { icon:"briefcase", name:"LinkedIn",        tip:"Great for professional services. Add to your profile's Featured section and post about your services regularly." },
    { icon:"twitter",   name:"X / Twitter",    tip:"Pin a tweet with your booking link at the top of your profile so every visitor sees it first." },
    { icon:"mail",      name:"Email Signature", tip:"Use a free tool like HubSpot's email signature generator to create a professional signature with a 'Book Now' button." },
    { icon:"globe",     name:"Your Website",    tip:'Add a "Book Now" button that links to your booking URL. Place it prominently in your header or hero section.' },
  ];
  return (
    <div>
      <div className="setup-grid">
        <div className="setup-card">
          <h3 style={{margin:"0 0 4px"}}>Your Booking Page Link</h3>
          <p style={{margin:"0 0 16px", color:"var(--text-muted)", fontSize:13}}>Every Nexus Booking account has a unique public booking page. Share this link anywhere to start receiving bookings.</p>
          <div style={{padding:"16px", background:"var(--accent-soft)", borderRadius:10, border:"1px solid rgba(239,164,3,0.3)", marginBottom:20, display:"flex", alignItems:"center", gap:12}}>
            <SetupIcon name="link" size={22}/>
            <div>
              <div style={{fontSize:12, color:"var(--text-muted)", marginBottom:2}}>Your booking URL</div>
              <div style={{fontSize:13, fontWeight:600, color:"var(--accent)"}}>nexusbooking.app/book/<em style={{opacity:0.7}}>your-brand-name</em></div>
            </div>
          </div>
          <div className="setup-steps">
            <SetupStep num={1} title="Find your link in the sidebar">
              Look at the bottom of the left sidebar under <em>Quick booking link</em>. Click <strong>Copy link</strong> to copy it to your clipboard instantly.
            </SetupStep>
            <SetupStep num={2} title="Add it to your website">
              Create a "Book Now" button on your website and paste your booking URL as the link destination. Most website builders (Wix, Squarespace, Webflow) support this in a few clicks.
            </SetupStep>
            <SetupStep num={3} title="Share on social media">
              Add the link to your Instagram bio, Facebook Page, and LinkedIn profile. Post about it regularly — many clients book directly from social media.
            </SetupStep>
            <SetupStep num={4} title="Add to your email signature">
              Include a "Book here:" line with your URL in every outgoing email. You can use a free signature builder to make it look professional.
            </SetupStep>
            <SetupStep num={5} title="Test a real booking">
              Open your booking link in a private/incognito browser window and go through the whole booking flow yourself to confirm everything works as expected.
            </SetupStep>
          </div>
          <SetupTip>Customise your booking page's welcome message and colours in Settings → Booking Page and Settings → Profile to make it feel on-brand.</SetupTip>
        </div>
        <div style={{display:"flex", flexDirection:"column", gap:16}}>
          <div className="setup-card">
            <h3 style={{margin:"0 0 4px"}}>Client Email Notifications</h3>
            <p style={{margin:"0 0 20px", color:"var(--text-muted)", fontSize:13}}>Configure what emails your clients receive at each stage.</p>
            <div className="setup-steps">
              <SetupStep num={1} title="Enable booking confirmation emails">
                Go to <strong>Settings → Notifications</strong> and turn on <em>Booking confirmation</em> — sent to the client the moment they complete a booking.
              </SetupStep>
              <SetupStep num={2} title="Set up reminder emails">
                Enable <em>Reminder email</em> to automatically email clients 24 hours before their appointment, reducing no-shows significantly.
              </SetupStep>
              <SetupStep num={3} title="Cancellation notifications">
                Enable <em>Cancellation email</em> so clients are informed immediately if a booking is cancelled or rescheduled from the admin side.
              </SetupStep>
            </div>
            <SetupNavHint>Go to: <strong>Settings → Notifications tab</strong></SetupNavHint>
          </div>
          <div className="setup-card">
            <h3 style={{margin:"0 0 4px"}}>Where to Share Your Link</h3>
            <p style={{margin:"0 0 14px", color:"var(--text-muted)", fontSize:13}}>The best places to promote your booking page.</p>
            <div style={{display:"flex", flexDirection:"column", gap:8}}>
              {PLATFORMS.map((p, i) => (
                <div key={i} style={{display:"flex", gap:10, alignItems:"flex-start", padding:"10px 12px", background:"var(--surface-2)", borderRadius:8, border:"1px solid var(--border)"}}>
                  <span style={{minWidth:22, paddingTop:1, flexShrink:0}}><SetupIcon name={p.icon} size={18}/></span>
                  <div>
                    <span style={{fontWeight:600, fontSize:13}}>{p.name}: </span>
                    <span style={{fontSize:12.5, color:"var(--text-muted)", lineHeight:1.5}}>{p.tip}</span>
                  </div>
                </div>
              ))}
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

// ── Industry Guides ───────────────────────────────────────────
const INDUSTRY_GUIDES = [
  {
    id: "swimming",
    icon: "grid",
    title: "Private Swimming Pool",
    tagline: "Whole pool hire by the hour for groups & families",
    color: "#0ea5e9",
    steps: [
      { title: "Create your session event type", desc: "Add one Event Type — e.g. 'Private Pool Hire (1 hour)'. Set the duration to 60 minutes and the price to your hourly rate. The whole pool is available for that slot." },
      { title: "Cap bookings at your group limit", desc: "Set Max Spaces to your maximum group size (e.g. 8). This prevents overbooking and makes it clear to guests how many can attend in one session." },
      { title: "Set your available hours", desc: "Under Availability, set the days and times your pool is open for hire. Nexus will only show slots within those windows to people booking online." },
      { title: "Add a safety intake form", desc: "On your Event Type, add intake questions: 'How many people are attending?', 'Are all attendees able to swim?', 'Will any children under 8 be present?', 'Do you agree to our safety rules?'. These arrive with every booking." },
      { title: "Block maintenance and personal time", desc: "Under Availability → Blocked Dates, add cleaning days, maintenance windows, and any dates the pool is unavailable. Clients can't book those slots — no manual managing needed." },
      { title: "Set a strict cancellation policy", desc: "Configure a 24-hour cancellation policy. Bookings cancelled within 24 hours can be set to non-refundable via Stripe — protecting your heating and preparation costs." },
      { title: "Offer regular weekly slots", desc: "For regular swimmers who take the same slot each week, create a recurring booking arrangement — or use Packages to let them pre-purchase a block of sessions at a slight discount." },
      { title: "Embed on your website", desc: "Go to Settings → Embed and copy the Calendar Widget snippet. Paste it into your website so visitors can see live availability and book and pay without needing to call you." },
    ],
    tips: [
      "Add your pool rules and safety requirements as a checkbox intake question — clients confirm they've read them at the time of booking, not when they arrive.",
      "Gift vouchers work brilliantly for private pool hire — birthday and Christmas gifts for families who want something memorable.",
      "Use blocked time slots to mark pool cleaning time between back-to-back sessions so the next group always arrives to a clean pool.",
    ],
  },
  {
    id: "beauty",
    icon: "star",
    title: "Beautician / Salon",
    tagline: "Treatments, deposits & client packages",
    color: "#ec4899",
    steps: [
      { title: "Create a service menu", desc: "Add each treatment as an Event Type — facial, manicure, pedicure, lash extensions etc. Set realistic durations including prep and cleanup time." },
      { title: "Add buffer time between clients", desc: "On each Event Type, set a slot interval longer than the duration (e.g. 75-min interval for a 60-min treatment) to give yourself turnaround time." },
      { title: "Collect a deposit", desc: "Set Payment Mode to 'Deposit' on treatments prone to no-shows. Require 20–50% upfront — this alone dramatically reduces cancellations." },
      { title: "Add intake form questions", desc: "For skin or nail treatments, add questions like 'Any allergies or sensitivities?', 'Have you had a patch test in the last 48 hours?', and 'Skin type'." },
      { title: "Create treatment packages", desc: "Under Packages, offer bundles like '6 facials — pay for 5' or a seasonal pamper package. Clients buy once and redeem sessions over time." },
      { title: "Issue gift vouchers", desc: "Go to Gift Vouchers and set up a voucher offering. These are perfect for Mother's Day, Valentine's Day, and birthdays — shareable link included." },
      { title: "Automate review requests", desc: "On each Event Type, set up a review request email. After the appointment, clients automatically receive a prompt to leave a Google or Facebook review." },
      { title: "Embed on your website", desc: "Use the Floating Button embed snippet to add a 'Book now' button to every page of your website without touching your theme." },
    ],
    tips: [
      "Use the cancellation policy settings to enforce 24–48 hour notice — pair this with deposits for maximum protection.",
      "The client portal lets returning clients reschedule themselves, reducing your admin messages.",
      "Add your Instagram link to your booking confirmation email via the email template settings.",
    ],
  },
  {
    id: "video",
    icon: "video",
    title: "Video Meetings & Consultations",
    tagline: "Zoom, Meet & Teams — fully automated",
    color: "#6366f1",
    steps: [
      { title: "Create your consultation event types", desc: "Add Event Types for each call type — Discovery Call (30 min), Strategy Session (60 min), Follow-up (20 min). Name them clearly so clients know what to book." },
      { title: "Set the meeting platform", desc: "On each Event Type, set Meeting Type to Google Meet, Zoom, or Microsoft Teams. The link is created automatically when someone books — no manual sharing needed." },
      { title: "Connect your calendar", desc: "Go to Integrations and connect Google Calendar. Your bookings sync both ways — new calls appear in your calendar and existing events block your availability automatically." },
      { title: "Add buffer time between calls", desc: "Set a slot interval 15–30 minutes longer than the call duration so you always have time to make notes or prepare before the next meeting." },
      { title: "Add intake form questions", desc: "Before a discovery call, ask 'Company name', 'What's your main challenge?' and 'How did you hear about us?' — this arrives with the booking notification so you're prepared." },
      { title: "Set focused availability windows", desc: "Use Availability to limit calls to specific days (e.g. Tuesday, Wednesday, Thursday) to protect your deep work days from being fragmented." },
      { title: "Use your booking link as a CTA", desc: "Go to Settings → Embed → Direct Link. Drop this into your email signature, LinkedIn profile, and website contact page instead of back-and-forth scheduling emails." },
      { title: "Enable the client portal", desc: "Clients can reschedule or cancel upcoming calls themselves — you get notified automatically and your calendar updates instantly." },
    ],
    tips: [
      "Zoom requires you to connect your Zoom account under Integrations. The OAuth connection takes under a minute.",
      "For paid consultations, use Stripe and set payment to 'Full payment upfront' — this pre-qualifies leads.",
      "The 'Custom button' embed lets you attach booking to any existing 'Schedule a call' button on your site with one attribute.",
    ],
  },
  {
    id: "spin",
    icon: "bolt",
    title: "Spin Classes & Fitness Studios",
    tagline: "Class capacity, memberships & waitlists",
    color: "#f97316",
    steps: [
      { title: "Create a class for each format", desc: "Add Event Types for Spin, HIIT, Yoga, Pilates etc. Set the duration and the start time interval to match your class timetable." },
      { title: "Set class capacity", desc: "Use Max Spaces on each class to match your studio capacity — e.g. 20 for a 20-bike spin room. Booking closes automatically when full." },
      { title: "Enable the waitlist", desc: "When a class is full, clients can join a waitlist. If a space opens up they're notified automatically — reducing empty bikes from last-minute cancellations." },
      { title: "Sell class credit packs", desc: "Go to Packages and create credit bundles — '10 classes', '20 classes'. Clients buy upfront at a discount and credits deduct at checkout." },
      { title: "Set up monthly memberships", desc: "Under Memberships, create an 'Unlimited Monthly' subscription. Stripe handles recurring billing; the client's session allowance resets each month automatically." },
      { title: "Add resources for studios", desc: "If you run classes across multiple rooms or locations, add them under Resources and assign each class to the right space to prevent double-booking." },
      { title: "Collect review requests", desc: "Set up automated review request emails after each class. Positive reviews on Google significantly increase walk-in and search traffic." },
      { title: "Embed your timetable", desc: "Use the Calendar Widget embed to show your live class schedule on your website — clients can see what's on and book directly without leaving your site." },
    ],
    tips: [
      "Use term-based payment for 6 or 8 week block courses — clients commit upfront and you get guaranteed revenue.",
      "The referral programme works brilliantly for fitness studios — offer a free class to anyone who brings a friend who joins.",
      "Block dates for instructor holidays via Availability so clients can't book sessions that can't run.",
    ],
  },
  {
    id: "pt",
    icon: "users",
    title: "Personal Trainer",
    tagline: "Session packages, retainers & client intake",
    color: "#10b981",
    steps: [
      { title: "Set up your session types", desc: "Create Event Types for 1-to-1 Training (60 min), Initial Assessment (30 min), and Group Session if applicable. Prices and durations differ so keep them separate." },
      { title: "Require payment upfront", desc: "Set Payment Mode to 'Full payment' to ensure clients pay when they book. This removes no-shows almost entirely and keeps your schedule reliable." },
      { title: "Create session packages", desc: "Under Packages, offer 6-session, 10-session, and 12-session blocks at a per-session discount. Serious clients prefer buying in bulk — it also increases retention." },
      { title: "Set up monthly retainer memberships", desc: "For premium clients, create a monthly membership (e.g. 4 sessions per month, recurring via Stripe). Sessions reset each billing cycle automatically." },
      { title: "Add a detailed intake form", desc: "On your Initial Assessment event, add questions: 'Current fitness level', 'Any injuries or medical conditions?', 'Primary goal (weight loss / muscle gain / performance)', 'Preferred training days'." },
      { title: "Enable the client portal", desc: "Let clients reschedule their own sessions (up to 24 hours before) via the client portal. This dramatically cuts the admin of WhatsApp messages asking to move sessions." },
      { title: "Automate review requests", desc: "After each session block completes, a review request email fires automatically. Google reviews are the single highest-impact thing for PT client acquisition." },
      { title: "Build a referral programme", desc: "Under Referrals, share your referral link with existing clients. When they refer a paying client, they earn a credit applied to their next package — zero manual work." },
    ],
    tips: [
      "Add your booking link to your Instagram bio and use it as the destination for all 'DM me to start' calls to action.",
      "Use the blocked time slots feature to protect your own training time, meal breaks, and admin hours.",
      "Gift vouchers for personal training are a growing market — especially around New Year and birthdays.",
    ],
  },
  {
    id: "tutor",
    icon: "bookings",
    title: "Tutor / Academic Coach",
    tagline: "Subjects, term billing & online lessons",
    color: "#8b5cf6",
    steps: [
      { title: "Create an event type per subject", desc: "Add a separate Event Type for each subject and level you teach — 'GCSE Maths', 'A-Level Chemistry', '11+ English' etc. This lets you set subject-specific availability and pricing." },
      { title: "Set the lesson location", desc: "For online tutoring, set Meeting Type to Zoom, Google Meet, or Teams. The link is sent automatically on booking. For in-person, leave it as 'In person' and enter your address." },
      { title: "Enable term-based billing", desc: "Set Payment Mode to 'Term Payment' and configure the number of weeks in your term. Parents pay the full term upfront — you get reliable income and clients commit." },
      { title: "Create lesson bundles", desc: "Under Packages, offer a '10-lesson bundle' at a slight discount. This is ideal for ad-hoc clients who aren't ready to commit to a full term." },
      { title: "Add intake form questions", desc: "Ask parents: 'Child's name and year group', 'Target grade or exam', 'Exam board (AQA, Edexcel, OCR)', 'Specific topics to focus on'. This saves 15 minutes of admin before every first session." },
      { title: "Set subject-specific availability", desc: "Enable Service-Specific Hours on each Event Type so your Maths availability can differ from your English slots. Useful if you have multiple tutors specialising in different subjects." },
      { title: "Share a parent booking portal", desc: "Parents can use the client portal to view upcoming lessons, download invoices, and reschedule if needed — without having to email or call you." },
      { title: "Embed on your tutor profile or website", desc: "Use the inline booking button or calendar widget embed to let parents book directly from your Tutorful profile, your school's website, or your own site." },
    ],
    tips: [
      "Block dates for school holidays in advance using Availability → Blocked Dates so parents can't accidentally book during your breaks.",
      "The invoice generator produces professional PDF invoices — useful for parents claiming tutoring through an employer's childcare benefit scheme.",
      "Review requests after exam results season (August/September) capture clients at peak motivation — schedule a review request trigger for this window.",
    ],
  },
];

function SetupIndustryGuides() {
  const [selected, setSelected] = React.useState(null);
  const guide = INDUSTRY_GUIDES.find(g => g.id === selected);

  return (
    <div>
      {/* Picker grid */}
      <div style={{display:"grid", gridTemplateColumns:"repeat(auto-fill, minmax(220px,1fr))", gap:12, marginBottom:24}}>
        {INDUSTRY_GUIDES.map(g => (
          <button key={g.id}
            onClick={() => setSelected(selected === g.id ? null : g.id)}
            style={{
              display:"flex", flexDirection:"column", alignItems:"flex-start",
              gap:8, padding:"16px 18px", textAlign:"left",
              background: selected === g.id ? `${g.color}12` : "var(--surface)",
              border: `1.5px solid ${selected === g.id ? g.color : "var(--border)"}`,
              borderRadius:12, cursor:"pointer", transition:"all .15s",
            }}>
            <span style={{color: selected === g.id ? g.color : "var(--text-muted)", transition:"color .15s"}}>
              {React.createElement(I[g.icon], { size: 22 })}
            </span>
            <div>
              <div style={{fontWeight:600, fontSize:13.5, color:"var(--text)", marginBottom:3}}>{g.title}</div>
              <div style={{fontSize:12, color:"var(--text-muted)", lineHeight:1.4}}>{g.tagline}</div>
            </div>
          </button>
        ))}
      </div>

      {/* Detail panel */}
      {guide && (
        <div className="setup-card-full" style={{borderColor: guide.color + "55"}}>
          {/* Header */}
          <div style={{display:"flex", alignItems:"center", gap:14, marginBottom:24, paddingBottom:20, borderBottom:"1px solid var(--border)"}}>
            <div style={{width:52, height:52, borderRadius:14, background:`${guide.color}18`, display:"flex", alignItems:"center", justifyContent:"center", color:guide.color, flexShrink:0}}>
              {React.createElement(I[guide.icon], { size: 24 })}
            </div>
            <div>
              <h2 style={{margin:"0 0 4px", fontSize:18, fontWeight:600}}>{guide.title}</h2>
              <div style={{fontSize:13, color:"var(--text-muted)"}}>{guide.tagline}</div>
            </div>
          </div>

          {/* Steps */}
          <h3 style={{margin:"0 0 16px", fontSize:14, fontWeight:600, color:"var(--text)"}}>Setup steps</h3>
          <div className="setup-steps" style={{marginBottom:28}}>
            {guide.steps.map((s, i) => (
              <div key={i} className="setup-step">
                <div className="setup-step-num" style={{background: guide.color, color:"#fff", borderColor: guide.color}}>{i + 1}</div>
                <div className="setup-step-body">
                  <strong>{s.title}</strong>
                  <p>{s.desc}</p>
                </div>
              </div>
            ))}
          </div>

          {/* Tips */}
          <div style={{background:`${guide.color}09`, border:`1px solid ${guide.color}33`, borderRadius:10, padding:"16px 18px"}}>
            <div style={{fontWeight:600, fontSize:13, color: guide.color, marginBottom:10, display:"flex", alignItems:"center", gap:6}}><I.bolt size={13}/> Pro tips for {guide.title.toLowerCase()} businesses</div>
            <div style={{display:"flex", flexDirection:"column", gap:8}}>
              {guide.tips.map((t, i) => (
                <div key={i} style={{display:"flex", gap:10, fontSize:13, color:"var(--text-muted)", lineHeight:1.5}}>
                  <span style={{color: guide.color, flexShrink:0, marginTop:1}}>→</span>
                  <span>{t}</span>
                </div>
              ))}
            </div>
          </div>
        </div>
      )}

      {!guide && (
        <div style={{padding:"32px 0", textAlign:"center", color:"var(--text-faint)", fontSize:13}}>
          Select a business type above to see a tailored setup guide.
        </div>
      )}
    </div>
  );
}

// ── Main Setup Guide shell ────────────────────────────────────
function ViewSetupGuide() {
  const [tab, setTab] = React.useState("start");

  const TABS = [
    { id: "start",        label: "Getting Started"        },
    { id: "profile",      label: "Profile & Branding"     },
    { id: "events",       label: "Event Types"            },
    { id: "availability", label: "Availability"           },
    { id: "payments",     label: "Payments"               },
    { id: "calendar",     label: "Calendar & Integrations"},
    { id: "team",         label: "Team Members"           },
    { id: "booking",      label: "Booking Page"           },
    { id: "industry",     label: "Industry Guides"        },
  ];

  return (
    <>
      <div className="view-h">
        <div>
          <h1>Setup Guide</h1>
          <div className="sub">Follow these steps to get Nexus Booking fully configured for your business.</div>
        </div>
      </div>

      <div className="platform-tabs">
        {TABS.map(t => (
          <button key={t.id}
            className={"platform-tab " + (tab === t.id ? "is-active" : "")}
            onClick={() => setTab(t.id)}>
            {t.label}
          </button>
        ))}
      </div>

      {tab === "start"        && <SetupStart/>}
      {tab === "profile"      && <SetupProfile/>}
      {tab === "events"       && <SetupEvents/>}
      {tab === "availability" && <SetupAvailability/>}
      {tab === "payments"     && <SetupPayments/>}
      {tab === "calendar"     && <SetupCalendar/>}
      {tab === "team"         && <SetupTeam/>}
      {tab === "booking"      && <SetupBookingPage/>}
      {tab === "industry"     && <SetupIndustryGuides/>}
    </>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Gift Vouchers
// ──────────────────────────────────────────────────────────────────────────
function VoucherModal({ voucher, onClose, onSave, currency }) {
  const sym = { GBP:"£", USD:"$", EUR:"€" }[currency] || "£";
  const blank = { code: "", amount: "", recipientName: "", recipientEmail: "", purchaserName: "", purchaserEmail: "", message: "", expiresAt: "" };
  const [draft, setDraft] = React.useState(voucher ? { ...voucher, amount: String(voucher.amount) } : blank);
  const set = (k, v) => setDraft(d => ({ ...d, [k]: v }));
  const genCode = () => set("code", Math.random().toString(36).slice(2, 8).toUpperCase());

  const handleSave = () => {
    if (!draft.code.trim() || !Number(draft.amount)) return;
    onSave({ ...draft, code: draft.code.toUpperCase().trim(), amount: Number(draft.amount) });
    onClose();
  };

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal" style={{maxWidth:480}} onClick={e => e.stopPropagation()}>
        <div className="modal-h">
          <h2>{voucher ? "Edit voucher" : "Issue gift voucher"}</h2>
          <button className="modal-close" onClick={onClose}><I.x size={16}/></button>
        </div>
        <div className="bk-form" style={{padding:0}}>
          <div className="bk-field">
            <label>Voucher code <span className="req">*</span></label>
            <div className="coupon-input-row">
              <input className="bk-input" style={{textTransform:"uppercase",letterSpacing:"0.06em",fontWeight:600}}
                placeholder="e.g. GIFT50" value={draft.code}
                onChange={e => set("code", e.target.value.toUpperCase())}/>
              <button className="btn ghost" type="button" onClick={genCode}>Generate</button>
            </div>
          </div>
          <div className="bk-field">
            <label>Value ({sym}) <span className="req">*</span></label>
            <input className="bk-input" type="number" min="1" placeholder="0.00"
              value={draft.amount} onChange={e => set("amount", e.target.value)}/>
          </div>
          <div className="field-grid" style={{gridTemplateColumns:"1fr 1fr", gap:"0 16px"}}>
            <div className="bk-field">
              <label>Recipient name</label>
              <input className="bk-input" placeholder="Who it's for" value={draft.recipientName} onChange={e => set("recipientName", e.target.value)}/>
            </div>
            <div className="bk-field">
              <label>Recipient email</label>
              <input className="bk-input" type="email" placeholder="recipient@example.com" value={draft.recipientEmail} onChange={e => set("recipientEmail", e.target.value)}/>
            </div>
            <div className="bk-field">
              <label>Purchaser name</label>
              <input className="bk-input" placeholder="Purchased by" value={draft.purchaserName} onChange={e => set("purchaserName", e.target.value)}/>
            </div>
            <div className="bk-field">
              <label>Purchaser email</label>
              <input className="bk-input" type="email" placeholder="purchaser@example.com" value={draft.purchaserEmail} onChange={e => set("purchaserEmail", e.target.value)}/>
            </div>
          </div>
          <div className="bk-field">
            <label>Message</label>
            <textarea className="bk-textarea" placeholder="Personal message to include with the voucher…" rows={2}
              value={draft.message} onChange={e => set("message", e.target.value)}/>
          </div>
          <div className="bk-field">
            <label>Expiry date</label>
            <input className="bk-input" type="date" value={draft.expiresAt} onChange={e => set("expiresAt", e.target.value)}/>
          </div>
          <div style={{display:"flex",gap:8,justifyContent:"flex-end",marginTop:4}}>
            <button className="btn ghost" onClick={onClose}>Cancel</button>
            <button className="btn primary" onClick={handleSave} disabled={!draft.code.trim() || !Number(draft.amount)}>
              {voucher ? "Save changes" : "Issue voucher"}
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}

function ViewVouchers({ data }) {
  const [vouchers, setVouchers] = React.useState(null);
  const [editing,  setEditing]  = React.useState(null);
  const userId   = data.userId;
  const currency = data.profile?.currency || "GBP";
  const sym      = { GBP:"£", USD:"$", EUR:"€" }[currency] || "£";

  React.useEffect(() => { fetchGiftVouchers(userId).then(setVouchers); }, [userId]);

  const handleSave = async (draft) => {
    const id = await saveGiftVoucher(draft, userId);
    fetchGiftVouchers(userId).then(setVouchers);
  };

  const handleDelete = async (id) => {
    if (!confirm("Delete this voucher? This cannot be undone.")) return;
    await deleteGiftVoucher(id);
    setVouchers(v => v.filter(x => x.id !== id));
  };

  if (!vouchers) return <div style={{display:"flex",alignItems:"center",justifyContent:"center",height:300}}><div className="loading-dots"><span/><span/><span/></div></div>;

  return (
    <>
      <div className="view-h">
        <div>
          <h1>Gift vouchers</h1>
          <div className="sub">Issue and manage gift vouchers that clients can redeem on your booking page.</div>
        </div>
        <div className="view-actions">
          <button className="btn primary" onClick={() => setEditing({})}>+ Issue voucher</button>
        </div>
      </div>

      {vouchers.length === 0 ? (
        <div className="empty-state">
          <I.card size={28} style={{color:"var(--text-faint)",marginBottom:12}}/>
          <h3>No vouchers yet</h3>
          <p>Issue a gift voucher and share the code with the recipient. They can apply it when booking on your public booking page.</p>
          <button className="btn primary" style={{marginTop:16}} onClick={() => setEditing({})}>Issue your first voucher</button>
        </div>
      ) : (
        <div className="card">
          <table className="table">
            <thead>
              <tr>
                <th>Code</th>
                <th>Value</th>
                <th>Recipient</th>
                <th>Purchaser</th>
                <th>Expires</th>
                <th>Status</th>
                <th></th>
              </tr>
            </thead>
            <tbody>
              {vouchers.map(v => {
                const redeemed = !!v.redeemedAt;
                const expired  = v.expiresAt && new Date(v.expiresAt) < new Date();
                const statusLabel = redeemed ? "Redeemed" : expired ? "Expired" : "Active";
                const statusClass = redeemed ? "pill cancelled" : expired ? "pill no-show" : "pill confirmed";
                return (
                  <tr key={v.id}>
                    <td><code className="coupon-code">{v.code}</code></td>
                    <td style={{fontWeight:600}}>{sym}{v.amount.toFixed(2)}</td>
                    <td style={{fontSize:13,color:"var(--text-muted)"}}>{v.recipientName || v.recipientEmail || "—"}</td>
                    <td style={{fontSize:13,color:"var(--text-muted)"}}>{v.purchaserName || v.purchaserEmail || "—"}</td>
                    <td style={{fontSize:12,color:"var(--text-muted)"}}>
                      {v.expiresAt ? new Date(v.expiresAt).toLocaleDateString("en-GB",{day:"numeric",month:"short",year:"numeric"}) : "Never"}
                    </td>
                    <td><span className={statusClass}>{statusLabel}</span></td>
                    <td style={{textAlign:"right"}}>
                      <div style={{display:"flex",gap:4,justifyContent:"flex-end"}}>
                        {!redeemed && <button className="btn ghost" style={{fontSize:11,padding:"3px 8px"}} onClick={() => setEditing(v)}>Edit</button>}
                        <button className="btn ghost" style={{fontSize:11,padding:"3px 8px",color:"var(--danger)"}} onClick={() => handleDelete(v.id)}>Delete</button>
                      </div>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      )}

      {editing !== null && (
        <VoucherModal
          voucher={Object.keys(editing).length === 0 ? null : editing}
          currency={currency}
          onClose={() => setEditing(null)}
          onSave={handleSave}
        />
      )}
    </>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Session Packages
// ──────────────────────────────────────────────────────────────────────────
function PackageModal({ pkg, events, onClose, onSave }) {
  const blank = { name: "", description: "", sessionCount: "5", price: "", eventIds: [] };
  const [draft, setDraft] = React.useState(pkg ? {
    ...pkg,
    sessionCount: String(pkg.sessionCount),
    price: String(pkg.price),
  } : blank);
  const set = (k, v) => setDraft(d => ({ ...d, [k]: v }));

  const toggleEvent = (id) => {
    setDraft(d => ({
      ...d,
      eventIds: d.eventIds.includes(id) ? d.eventIds.filter(x => x !== id) : [...d.eventIds, id],
    }));
  };

  const handleSave = () => {
    if (!draft.name.trim() || !Number(draft.sessionCount)) return;
    onSave({ ...draft, sessionCount: Number(draft.sessionCount), price: Number(draft.price || 0) });
    onClose();
  };

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal" style={{maxWidth:460}} onClick={e => e.stopPropagation()}>
        <div className="modal-h">
          <h2>{pkg ? "Edit package" : "New package"}</h2>
          <button className="modal-close" onClick={onClose}><I.x size={16}/></button>
        </div>
        <div className="bk-form" style={{padding:0}}>
          <div className="bk-field">
            <label>Package name <span className="req">*</span></label>
            <input className="bk-input" placeholder="e.g. 5-Session Pilates Bundle"
              value={draft.name} onChange={e => set("name", e.target.value)}/>
          </div>
          <div className="bk-field">
            <label>Description</label>
            <textarea className="bk-textarea" rows={2} placeholder="Optional — shown to clients…"
              value={draft.description} onChange={e => set("description", e.target.value)}/>
          </div>
          <div className="field-grid" style={{gridTemplateColumns:"1fr 1fr",gap:"0 16px"}}>
            <div className="bk-field">
              <label>Number of sessions <span className="req">*</span></label>
              <input className="bk-input" type="number" min="1" value={draft.sessionCount}
                onChange={e => set("sessionCount", e.target.value)}/>
            </div>
            <div className="bk-field">
              <label>Package price</label>
              <input className="bk-input" type="number" min="0" step="0.01" placeholder="0.00"
                value={draft.price} onChange={e => set("price", e.target.value)}/>
            </div>
          </div>
          {events.length > 0 && (
            <div className="bk-field">
              <label>Valid for event types</label>
              <div style={{display:"flex",flexWrap:"wrap",gap:6,marginTop:4}}>
                {events.map(ev => (
                  <label key={ev.id} className="mini-check" style={{background:"var(--surface-2)",borderRadius:6,padding:"4px 10px",cursor:"pointer"}}>
                    <input type="checkbox" checked={draft.eventIds.includes(ev.id)} onChange={() => toggleEvent(ev.id)}/>
                    {ev.name}
                  </label>
                ))}
                {draft.eventIds.length === 0 && <span style={{fontSize:12,color:"var(--text-faint)"}}>All event types (leave empty to apply to all)</span>}
              </div>
            </div>
          )}
          <div style={{display:"flex",gap:8,justifyContent:"flex-end",marginTop:4}}>
            <button className="btn ghost" onClick={onClose}>Cancel</button>
            <button className="btn primary" onClick={handleSave} disabled={!draft.name.trim() || !Number(draft.sessionCount)}>
              {pkg ? "Save changes" : "Create package"}
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}

function PurchaseModal({ packages, onClose, onSave }) {
  const [draft, setDraft] = React.useState({ packageId: packages[0]?.id || "", guestName: "", guestEmail: "", expiresAt: "" });
  const set = (k, v) => setDraft(d => ({ ...d, [k]: v }));
  const selectedPkg = packages.find(p => p.id === draft.packageId);

  const handleSave = () => {
    if (!draft.guestEmail.trim() || !draft.packageId) return;
    onSave({
      packageId:   draft.packageId,
      packageName: selectedPkg?.name || "",
      guestName:   draft.guestName.trim(),
      guestEmail:  draft.guestEmail.trim(),
      sessionsTotal:     selectedPkg?.sessionCount || 0,
      sessionsRemaining: selectedPkg?.sessionCount || 0,
      expiresAt:   draft.expiresAt || null,
    });
    onClose();
  };

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal" style={{maxWidth:440}} onClick={e => e.stopPropagation()}>
        <div className="modal-h">
          <h2>Sell package to client</h2>
          <button className="modal-close" onClick={onClose}><I.x size={16}/></button>
        </div>
        <div className="bk-form" style={{padding:0}}>
          <div className="bk-field">
            <label>Package <span className="req">*</span></label>
            <select className="bk-input" value={draft.packageId} onChange={e => set("packageId", e.target.value)}>
              {packages.map(p => <option key={p.id} value={p.id}>{p.name} ({p.sessionCount} sessions)</option>)}
            </select>
          </div>
          <div className="field-grid" style={{gridTemplateColumns:"1fr 1fr",gap:"0 16px"}}>
            <div className="bk-field">
              <label>Client name</label>
              <input className="bk-input" placeholder="Client full name" value={draft.guestName} onChange={e => set("guestName", e.target.value)}/>
            </div>
            <div className="bk-field">
              <label>Client email <span className="req">*</span></label>
              <input className="bk-input" type="email" placeholder="client@example.com" value={draft.guestEmail} onChange={e => set("guestEmail", e.target.value)}/>
            </div>
          </div>
          <div className="bk-field">
            <label>Expires (optional)</label>
            <input className="bk-input" type="date" value={draft.expiresAt} onChange={e => set("expiresAt", e.target.value)}/>
          </div>
          <div style={{display:"flex",gap:8,justifyContent:"flex-end",marginTop:4}}>
            <button className="btn ghost" onClick={onClose}>Cancel</button>
            <button className="btn primary" onClick={handleSave} disabled={!draft.guestEmail.trim() || !draft.packageId}>
              Issue package
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}

function ViewPackages({ data }) {
  const [packages,   setPackages]   = React.useState(null);
  const [purchases,  setPurchases]  = React.useState(null);
  const [tab,        setTab]        = React.useState("packages");
  const [editPkg,    setEditPkg]    = React.useState(null);
  const [showSell,   setShowSell]   = React.useState(false);
  const userId = data.userId;

  React.useEffect(() => {
    fetchPackages(userId).then(setPackages);
    fetchPackagePurchases(userId).then(setPurchases);
  }, [userId]);

  const handleSavePkg = async (draft) => {
    await savePackage(draft, userId);
    fetchPackages(userId).then(setPackages);
  };

  const handleDeletePkg = async (id) => {
    if (!confirm("Delete this package? Existing purchases won't be affected.")) return;
    await deletePackage(id);
    setPackages(p => p.filter(x => x.id !== id));
  };

  const handleSellPkg = async (draft) => {
    await savePackagePurchase(draft, userId);
    fetchPackagePurchases(userId).then(setPurchases);
  };

  const handleDeletePurchase = async (id) => {
    if (!confirm("Remove this client's package? This can't be undone.")) return;
    await deletePackagePurchase(id);
    setPurchases(p => p.filter(x => x.id !== id));
  };

  if (!packages || !purchases) return <div style={{display:"flex",alignItems:"center",justifyContent:"center",height:300}}><div className="loading-dots"><span/><span/><span/></div></div>;

  return (
    <>
      <div className="view-h">
        <div>
          <h1>Session packages</h1>
          <div className="sub">Sell multi-session bundles — clients redeem one session per booking.</div>
        </div>
        <div className="view-actions">
          {tab === "packages" && <button className="btn primary" onClick={() => setEditPkg({})}>+ New package</button>}
          {tab === "purchases" && packages.length > 0 && <button className="btn primary" onClick={() => setShowSell(true)}>+ Sell to client</button>}
        </div>
      </div>

      <div style={{display:"flex", gap:8, marginBottom:20}}>
        <button className={"chip " + (tab === "packages" ? "is-active" : "")} onClick={() => setTab("packages")}>
          Packages {packages && <span className="count">{packages.length}</span>}
        </button>
        <button className={"chip " + (tab === "purchases" ? "is-active" : "")} onClick={() => setTab("purchases")}>
          Client packages {purchases && <span className="count">{purchases.length}</span>}
        </button>
      </div>

      {tab === "packages" && (
        packages.length === 0 ? (
          <div className="empty-state">
            <I.layers size={28} style={{color:"var(--text-faint)",marginBottom:12}}/>
            <h3>No packages yet</h3>
            <p>Create a session package — for example "5 sessions for £200". Sell it to clients and they can redeem a session each time they book.</p>
            <button className="btn primary" style={{marginTop:16}} onClick={() => setEditPkg({})}>Create your first package</button>
          </div>
        ) : (
          <div className="card">
            <table className="table">
              <thead><tr><th>Name</th><th>Sessions</th><th>Price</th><th>For events</th><th></th></tr></thead>
              <tbody>
                {packages.map(p => (
                  <tr key={p.id}>
                    <td style={{fontWeight:500}}>{p.name}</td>
                    <td>{p.sessionCount}</td>
                    <td>{p.price > 0 ? `£${p.price.toFixed(2)}` : "—"}</td>
                    <td style={{fontSize:12,color:"var(--text-muted)"}}>{p.eventIds.length === 0 ? "All" : `${p.eventIds.length} event type${p.eventIds.length > 1 ? "s" : ""}`}</td>
                    <td style={{textAlign:"right"}}>
                      <div style={{display:"flex",gap:4,justifyContent:"flex-end"}}>
                        <button className="btn ghost" style={{fontSize:11,padding:"3px 8px"}} onClick={() => setEditPkg(p)}>Edit</button>
                        <button className="btn ghost" style={{fontSize:11,padding:"3px 8px",color:"var(--danger)"}} onClick={() => handleDeletePkg(p.id)}>Delete</button>
                      </div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )
      )}

      {tab === "purchases" && (
        purchases.length === 0 ? (
          <div className="empty-state">
            <I.users size={28} style={{color:"var(--text-faint)",marginBottom:12}}/>
            <h3>No client packages yet</h3>
            <p>Once you sell a package to a client, it will appear here. Clients can look up their sessions on your booking page using their email address.</p>
            {packages.length > 0 && <button className="btn primary" style={{marginTop:16}} onClick={() => setShowSell(true)}>Sell a package now</button>}
          </div>
        ) : (
          <div className="card">
            <table className="table">
              <thead><tr><th>Client</th><th>Package</th><th>Sessions</th><th>Purchased</th><th>Expires</th><th></th></tr></thead>
              <tbody>
                {purchases.map(pp => {
                  const pct = pp.sessionsTotal > 0 ? (pp.sessionsTotal - pp.sessionsRemaining) / pp.sessionsTotal : 0;
                  return (
                    <tr key={pp.id}>
                      <td>
                        <div style={{fontWeight:500,fontSize:14}}>{pp.guestName || "—"}</div>
                        <div style={{fontSize:12,color:"var(--text-muted)"}}>{pp.guestEmail}</div>
                      </td>
                      <td style={{fontSize:13}}>{pp.packageName}</td>
                      <td>
                        <div style={{display:"flex",alignItems:"center",gap:8}}>
                          <div style={{flex:1,height:4,background:"var(--surface-3)",borderRadius:4,overflow:"hidden",minWidth:60}}>
                            <div style={{width:`${pct*100}%`,height:"100%",background:"var(--accent)",borderRadius:4}}/>
                          </div>
                          <span style={{fontSize:12,color:"var(--text-muted)",whiteSpace:"nowrap"}}>
                            {pp.sessionsTotal - pp.sessionsRemaining}/{pp.sessionsTotal} used
                          </span>
                        </div>
                      </td>
                      <td style={{fontSize:12,color:"var(--text-muted)"}}>{pp.purchasedAt ? new Date(pp.purchasedAt).toLocaleDateString("en-GB",{day:"numeric",month:"short",year:"numeric"}) : "—"}</td>
                      <td style={{fontSize:12,color:"var(--text-muted)"}}>{pp.expiresAt ? new Date(pp.expiresAt).toLocaleDateString("en-GB",{day:"numeric",month:"short",year:"numeric"}) : "Never"}</td>
                      <td style={{textAlign:"right"}}>
                        <button className="btn ghost" style={{fontSize:11,padding:"3px 8px",color:"var(--danger)"}} onClick={() => handleDeletePurchase(pp.id)}>Remove</button>
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        )
      )}

      {editPkg !== null && (
        <PackageModal
          pkg={Object.keys(editPkg).length === 0 ? null : editPkg}
          events={data.events || []}
          onClose={() => setEditPkg(null)}
          onSave={handleSavePkg}
        />
      )}
      {showSell && packages.length > 0 && (
        <PurchaseModal packages={packages} onClose={() => setShowSell(false)} onSave={handleSellPkg}/>
      )}
    </>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Resource Management
// ──────────────────────────────────────────────────────────────────────────
function ResourceModal({ resource, onClose, onSave }) {
  const isNew = !resource;
  const [name, setName]   = React.useState(resource?.name || "");
  const [type, setType]   = React.useState(resource?.type || "room");
  const [desc, setDesc]   = React.useState(resource?.description || "");
  const [color, setColor] = React.useState(resource?.color || "#006e78");
  const [busy, setBusy]   = React.useState(false);

  const handleSave = async () => {
    if (!name.trim()) return;
    setBusy(true);
    await onSave({ ...resource, name: name.trim(), type, description: desc, color });
    setBusy(false);
    onClose();
  };

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal-card" onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <h3 style={{margin:0}}>{isNew ? "Add resource" : "Edit resource"}</h3>
          <button className="modal-close" onClick={onClose}><I.x size={14}/></button>
        </div>
        <div className="modal-body">
          <div className="bk-field">
            <label>Name</label>
            <input className="bk-input" value={name} onChange={e => setName(e.target.value)} placeholder="e.g. Treatment Room 1"/>
          </div>
          <div className="bk-field">
            <label>Type</label>
            <select className="bk-input" value={type} onChange={e => setType(e.target.value)}>
              <option value="room">Room</option>
              <option value="equipment">Equipment</option>
            </select>
          </div>
          <div className="bk-field">
            <label>Description</label>
            <textarea className="bk-textarea" rows={2} value={desc} onChange={e => setDesc(e.target.value)} placeholder="Optional notes about this resource…"/>
          </div>
          <div className="bk-field">
            <label>Colour</label>
            <input type="color" value={color} onChange={e => setColor(e.target.value)} style={{height:36, cursor:"pointer"}}/>
          </div>
        </div>
        <div className="modal-foot">
          <button className="btn ghost" onClick={onClose}>Cancel</button>
          <button className="btn primary" onClick={handleSave} disabled={busy || !name.trim()}>
            {busy ? "Saving…" : isNew ? "Add resource" : "Save"}
          </button>
        </div>
      </div>
    </div>
  );
}

function ViewResources({ data }) {
  const [resources, setResources] = React.useState(null);
  const [editing, setEditing]     = React.useState(null);
  const userId = data.userId;

  React.useEffect(() => { fetchResources(userId).then(setResources); }, [userId]);

  const handleSave = async (draft) => {
    await saveResource(draft, userId);
    fetchResources(userId).then(setResources);
  };

  const handleDelete = async (id) => {
    if (!confirm("Delete this resource? Existing bookings will not be affected.")) return;
    await deleteResource(id);
    setResources(r => r.filter(x => x.id !== id));
  };

  const handleToggle = async (res) => {
    await saveResource({ ...res, active: !res.active }, userId);
    setResources(rs => rs.map(r => r.id === res.id ? { ...r, active: !r.active } : r));
  };

  if (!resources) return <div style={{display:"flex",alignItems:"center",justifyContent:"center",height:300}}><div className="loading-dots"><span/><span/><span/></div></div>;

  return (
    <>
      <div className="view-h">
        <div>
          <h1>Resources</h1>
          <div className="sub">Manage rooms and equipment available for booking alongside your services.</div>
        </div>
        <div className="view-actions">
          <button className="btn primary" onClick={() => setEditing({})}>+ Add resource</button>
        </div>
      </div>

      {resources.length === 0 ? (
        <div className="empty-state">
          <I.layers size={28} style={{color:"var(--text-faint)",marginBottom:12}}/>
          <h3>No resources yet</h3>
          <p>Add rooms, studios, or equipment that can be booked alongside your services. Nexus Booking will automatically prevent double-booking.</p>
          <button className="btn primary" style={{marginTop:16}} onClick={() => setEditing({})}>Add your first resource</button>
        </div>
      ) : (
        <div className="card">
          <table className="table">
            <thead>
              <tr>
                <th>Name</th>
                <th>Type</th>
                <th>Description</th>
                <th>Active</th>
                <th></th>
              </tr>
            </thead>
            <tbody>
              {resources.map(r => (
                <tr key={r.id}>
                  <td>
                    <div style={{display:"flex",alignItems:"center",gap:8}}>
                      <div style={{width:10,height:10,borderRadius:3,background:r.color,flexShrink:0}}/>
                      <strong style={{fontSize:14}}>{r.name}</strong>
                    </div>
                  </td>
                  <td>
                    <span className="pill" style={{background:"var(--surface-2)",color:"var(--text-muted)",fontSize:11,textTransform:"capitalize"}}>
                      {r.type}
                    </span>
                  </td>
                  <td style={{color:"var(--text-muted)",fontSize:13}}>{r.description || "—"}</td>
                  <td>
                    <label className="switch">
                      <input type="checkbox" checked={r.active} onChange={() => handleToggle(r)}/>
                      <span className="track"><span className="knob"/></span>
                    </label>
                  </td>
                  <td style={{textAlign:"right"}}>
                    <div style={{display:"flex",gap:4,justifyContent:"flex-end"}}>
                      <button className="btn ghost" style={{fontSize:11,padding:"3px 8px"}} onClick={() => setEditing(r)}>Edit</button>
                      <button className="btn ghost" style={{fontSize:11,padding:"3px 8px",color:"var(--danger)"}} onClick={() => handleDelete(r.id)}>Delete</button>
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}

      {editing !== null && (
        <ResourceModal
          resource={Object.keys(editing).length === 0 ? null : editing}
          onClose={() => setEditing(null)}
          onSave={handleSave}
        />
      )}
    </>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Memberships
// ──────────────────────────────────────────────────────────────────────────
function MembershipModal({ membership, onClose, onSave }) {
  const isNew = !membership;
  const [name,     setName]     = React.useState(membership?.name || "");
  const [desc,     setDesc]     = React.useState(membership?.description || "");
  const [price,    setPrice]    = React.useState(membership?.priceMonth != null ? String(membership.priceMonth) : "");
  const [sessions, setSessions] = React.useState(membership?.sessionsPerMonth != null ? String(membership.sessionsPerMonth) : "4");
  const [priceId,  setPriceId]  = React.useState(membership?.stripePriceId || "");
  const [busy, setBusy]         = React.useState(false);

  const handleSave = async () => {
    if (!name.trim()) return;
    setBusy(true);
    await onSave({
      ...membership,
      name: name.trim(),
      description: desc,
      priceMonth: parseFloat(price) || 0,
      sessionsPerMonth: parseInt(sessions) || 4,
      stripePriceId: priceId.trim() || null,
    });
    setBusy(false);
    onClose();
  };

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal-card" onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <h3 style={{margin:0}}>{isNew ? "New membership plan" : "Edit plan"}</h3>
          <button className="modal-close" onClick={onClose}><I.x size={14}/></button>
        </div>
        <div className="modal-body">
          <div className="bk-field">
            <label>Plan name</label>
            <input className="bk-input" value={name} onChange={e => setName(e.target.value)} placeholder="e.g. Monthly Unlimited"/>
          </div>
          <div className="bk-field">
            <label>Description</label>
            <textarea className="bk-textarea" rows={2} value={desc} onChange={e => setDesc(e.target.value)} placeholder="Optional description shown to clients…"/>
          </div>
          <div className="field-grid" style={{gridTemplateColumns:"1fr 1fr"}}>
            <div className="bk-field">
              <label>Monthly price (£)</label>
              <input className="bk-input" type="number" min="0" step="0.01" value={price} onChange={e => setPrice(e.target.value)} placeholder="49.00"/>
            </div>
            <div className="bk-field">
              <label>Sessions per month</label>
              <input className="bk-input" type="number" min="1" step="1" value={sessions} onChange={e => setSessions(e.target.value)} placeholder="4"/>
            </div>
          </div>
          <div className="bk-field">
            <label>Stripe Price ID <span style={{color:"var(--text-faint)",fontWeight:400}}>(optional — for automated billing)</span></label>
            <input className="bk-input" value={priceId} onChange={e => setPriceId(e.target.value)} placeholder="price_1Abc…"/>
            <div style={{fontSize:11,color:"var(--text-muted)",marginTop:4}}>
              Create a recurring price in your Stripe dashboard and paste the ID here to enable one-click subscriptions.
            </div>
          </div>
        </div>
        <div className="modal-foot">
          <button className="btn ghost" onClick={onClose}>Cancel</button>
          <button className="btn primary" onClick={handleSave} disabled={busy || !name.trim()}>
            {busy ? "Saving…" : isNew ? "Create plan" : "Save"}
          </button>
        </div>
      </div>
    </div>
  );
}

function MemberSubscriptionModal({ memberships, onClose, onSave }) {
  const [membershipId, setMembershipId] = React.useState(memberships[0]?.id || "");
  const [guestName,    setGuestName]    = React.useState("");
  const [guestEmail,   setGuestEmail]   = React.useState("");
  const [busy, setBusy]                 = React.useState(false);

  const selectedPlan = memberships.find(m => m.id === membershipId);

  const handleSave = async () => {
    if (!guestEmail.trim() || !membershipId) return;
    setBusy(true);
    await onSave({
      membershipId,
      membershipName: selectedPlan?.name || "",
      guestName: guestName.trim(),
      guestEmail: guestEmail.trim().toLowerCase(),
      sessionsTotal:     selectedPlan?.sessionsPerMonth || 4,
      sessionsRemaining: selectedPlan?.sessionsPerMonth || 4,
    });
    setBusy(false);
    onClose();
  };

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal-card" onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <h3 style={{margin:0}}>Add subscriber</h3>
          <button className="modal-close" onClick={onClose}><I.x size={14}/></button>
        </div>
        <div className="modal-body">
          <div className="bk-field">
            <label>Plan</label>
            <select className="bk-input" value={membershipId} onChange={e => setMembershipId(e.target.value)}>
              {memberships.map(m => <option key={m.id} value={m.id}>{m.name} — £{m.priceMonth}/mo</option>)}
            </select>
          </div>
          <div className="bk-field">
            <label>Client name</label>
            <input className="bk-input" value={guestName} onChange={e => setGuestName(e.target.value)} placeholder="Jane Smith"/>
          </div>
          <div className="bk-field">
            <label>Client email</label>
            <input className="bk-input" type="email" value={guestEmail} onChange={e => setGuestEmail(e.target.value)} placeholder="jane@example.com"/>
          </div>
          {selectedPlan && (
            <div style={{background:"var(--surface-2)",borderRadius:8,padding:"10px 14px",fontSize:13,color:"var(--text-muted)"}}>
              Client will receive <strong style={{color:"var(--text)"}}>{selectedPlan.sessionsPerMonth} sessions</strong> per month
              {selectedPlan.stripePriceId && " · Stripe billing will be initiated automatically"}.
            </div>
          )}
        </div>
        <div className="modal-foot">
          <button className="btn ghost" onClick={onClose}>Cancel</button>
          <button className="btn primary" onClick={handleSave} disabled={busy || !guestEmail.trim()}>
            {busy ? "Adding…" : "Add subscriber"}
          </button>
        </div>
      </div>
    </div>
  );
}

function ViewMemberships({ data }) {
  const [tab, setTab]               = React.useState("plans");
  const [memberships, setMemberships] = React.useState(null);
  const [subscriptions, setSubscriptions] = React.useState(null);
  const [editPlan, setEditPlan]     = React.useState(null);
  const [showAdd, setShowAdd]       = React.useState(false);
  const userId = data.userId;

  React.useEffect(() => {
    fetchMemberships(userId).then(setMemberships);
    fetchMemberSubscriptions(userId).then(setSubscriptions);
  }, [userId]);

  const reload = () => {
    fetchMemberships(userId).then(setMemberships);
    fetchMemberSubscriptions(userId).then(setSubscriptions);
  };

  const handleSavePlan = async (draft) => {
    await saveMembership(draft, userId);
    reload();
  };

  const handleDeletePlan = async (id) => {
    if (!confirm("Delete this plan? Existing subscribers won't be affected.")) return;
    await deleteMembership(id);
    reload();
  };

  const handleAddSubscriber = async (draft) => {
    await saveMemberSubscription(draft, userId);
    reload();
  };

  const handleCancelSub = async (sub) => {
    if (!confirm(`Cancel ${sub.guestName || sub.guestEmail}'s subscription?`)) return;
    await saveMemberSubscription({ ...sub, status: "cancelled" }, userId);
    reload();
  };

  const currency = data.profile?.currency || "GBP";
  const sym      = { GBP:"£", USD:"$", EUR:"€" }[currency] || currency + " ";

  const isLoading = !memberships || !subscriptions;
  if (isLoading) return <div style={{display:"flex",alignItems:"center",justifyContent:"center",height:300}}><div className="loading-dots"><span/><span/><span/></div></div>;

  return (
    <>
      <div className="view-h">
        <div>
          <h1>Memberships</h1>
          <div className="sub">Recurring monthly plans — clients pay once a month and use a set number of sessions.</div>
        </div>
        <div className="view-actions">
          {tab === "plans"      && <button className="btn primary" onClick={() => setEditPlan({})}>+ New plan</button>}
          {tab === "subscribers" && memberships?.length > 0 && <button className="btn primary" onClick={() => setShowAdd(true)}>+ Add subscriber</button>}
        </div>
      </div>

      <div style={{display:"flex",gap:8,marginBottom:20}}>
        <button className={"chip " + (tab === "plans" ? "is-active" : "")} onClick={() => setTab("plans")}>
          Plans <span className="count">{memberships.length}</span>
        </button>
        <button className={"chip " + (tab === "subscribers" ? "is-active" : "")} onClick={() => setTab("subscribers")}>
          Subscribers <span className="count">{subscriptions.filter(s => s.status === "active").length}</span>
        </button>
      </div>

      {tab === "plans" && (
        memberships.length === 0 ? (
          <div className="empty-state">
            <I.card size={28} style={{color:"var(--text-faint)",marginBottom:12}}/>
            <h3>No plans yet</h3>
            <p>Create membership plans — set a monthly price and the number of sessions included. Clients can then be enrolled manually or via Stripe.</p>
            <button className="btn primary" style={{marginTop:16}} onClick={() => setEditPlan({})}>Create first plan</button>
          </div>
        ) : (
          <div className="card">
            <table className="table">
              <thead>
                <tr><th>Plan</th><th>Price/mo</th><th>Sessions/mo</th><th>Active subs</th><th>Stripe</th><th></th></tr>
              </thead>
              <tbody>
                {memberships.map(m => (
                  <tr key={m.id}>
                    <td>
                      <div style={{fontWeight:600,fontSize:14}}>{m.name}</div>
                      {m.description && <div style={{fontSize:12,color:"var(--text-muted)"}}>{m.description}</div>}
                    </td>
                    <td style={{fontWeight:600}}>{sym}{m.priceMonth}/mo</td>
                    <td>{m.sessionsPerMonth}</td>
                    <td>{subscriptions.filter(s => s.membershipId === m.id && s.status === "active").length}</td>
                    <td>
                      {m.stripePriceId
                        ? <span style={{fontSize:11,color:"#059669",fontWeight:600}}>● Connected</span>
                        : <span style={{fontSize:11,color:"var(--text-faint)"}}>Manual</span>}
                    </td>
                    <td style={{textAlign:"right"}}>
                      <div style={{display:"flex",gap:4,justifyContent:"flex-end"}}>
                        <button className="btn ghost" style={{fontSize:11,padding:"3px 8px"}} onClick={() => setEditPlan(m)}>Edit</button>
                        <button className="btn ghost" style={{fontSize:11,padding:"3px 8px",color:"var(--danger)"}} onClick={() => handleDeletePlan(m.id)}>Delete</button>
                      </div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )
      )}

      {tab === "subscribers" && (
        subscriptions.length === 0 ? (
          <div className="empty-state">
            <I.users size={28} style={{color:"var(--text-faint)",marginBottom:12}}/>
            <h3>No subscribers yet</h3>
            <p>Enrol clients onto a membership plan. They can then use their monthly session allowance when booking.</p>
            {memberships.length > 0 && <button className="btn primary" style={{marginTop:16}} onClick={() => setShowAdd(true)}>Add first subscriber</button>}
          </div>
        ) : (
          <div className="card">
            <table className="table">
              <thead>
                <tr><th>Client</th><th>Plan</th><th>Sessions this month</th><th>Status</th><th></th></tr>
              </thead>
              <tbody>
                {subscriptions.map(s => {
                  const pct = s.sessionsTotal > 0 ? Math.round(((s.sessionsTotal - s.sessionsRemaining) / s.sessionsTotal) * 100) : 0;
                  return (
                    <tr key={s.id}>
                      <td>
                        <div style={{fontWeight:600,fontSize:14}}>{s.guestName || s.guestEmail}</div>
                        <div style={{fontSize:12,color:"var(--text-muted)"}}>{s.guestEmail}</div>
                      </td>
                      <td style={{fontSize:13}}>{s.membershipName || "—"}</td>
                      <td>
                        <div style={{display:"flex",alignItems:"center",gap:8}}>
                          <div style={{flex:1,height:6,background:"var(--surface-2)",borderRadius:3,overflow:"hidden",minWidth:80}}>
                            <div style={{width:`${pct}%`,height:"100%",background:"var(--accent)",borderRadius:3}}/>
                          </div>
                          <span style={{fontSize:12,color:"var(--text-muted)",whiteSpace:"nowrap"}}>{s.sessionsRemaining}/{s.sessionsTotal} left</span>
                        </div>
                      </td>
                      <td>
                        <span className={"pill " + (s.status === "active" ? "confirmed" : "cancelled")}>
                          {s.status}
                        </span>
                      </td>
                      <td style={{textAlign:"right"}}>
                        {s.status === "active" && (
                          <button className="btn ghost" style={{fontSize:11,padding:"3px 8px",color:"var(--danger)"}} onClick={() => handleCancelSub(s)}>Cancel</button>
                        )}
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        )
      )}

      {editPlan !== null && (
        <MembershipModal
          membership={Object.keys(editPlan).length === 0 ? null : editPlan}
          onClose={() => setEditPlan(null)}
          onSave={handleSavePlan}
        />
      )}
      {showAdd && memberships.length > 0 && (
        <MemberSubscriptionModal
          memberships={memberships}
          onClose={() => setShowAdd(false)}
          onSave={handleAddSubscriber}
        />
      )}
    </>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Clients (mini-CRM)
// ──────────────────────────────────────────────────────────────────────────
function ViewClients({ data }) {
  const [search, setSearch]   = React.useState("");
  const [sortBy, setSortBy]   = React.useState("lastVisit"); // lastVisit | totalSpend | totalBookings | name
  const [expanded, setExpanded] = React.useState(null); // client email key
  const currency = getCurrency(data.profile?.currency);

  // Aggregate bookings into a client map keyed by email
  const clientMap = React.useMemo(() => {
    const map = {};
    (data.bookings || []).forEach((b) => {
      const key = (b.guestEmail || "").toLowerCase().trim();
      if (!key) return;
      if (!map[key]) {
        map[key] = {
          email:        b.guestEmail || "",
          name:         b.guestName  || b.guestEmail || "Unknown",
          phone:        b.guestPhone || "",
          bookings:     [],
          totalSpend:   0,
          lastVisit:    "",
          services:     new Set(),
        };
      }
      const c = map[key];
      // Keep most complete name
      if ((b.guestName || "").length > c.name.length) c.name = b.guestName;
      if (b.guestPhone && !c.phone) c.phone = b.guestPhone;
      c.bookings.push(b);
      c.totalSpend += Number(b.paymentAmount || 0);
      if (b.date && (!c.lastVisit || b.date > c.lastVisit)) c.lastVisit = b.date;
      if (b.eventName) c.services.add(b.eventName);
    });
    // Convert set → array
    Object.values(map).forEach((c) => { c.services = [...c.services]; });
    return map;
  }, [data.bookings]);

  const clients = React.useMemo(() => {
    const list = Object.values(clientMap);
    const q = search.trim().toLowerCase();
    const filtered = q
      ? list.filter((c) =>
          c.name.toLowerCase().includes(q) ||
          c.email.toLowerCase().includes(q) ||
          c.phone.includes(q)
        )
      : list;
    return filtered.slice().sort((a, b) => {
      if (sortBy === "name")          return a.name.localeCompare(b.name);
      if (sortBy === "totalSpend")    return b.totalSpend   - a.totalSpend;
      if (sortBy === "totalBookings") return b.bookings.length - a.bookings.length;
      // lastVisit default
      return (b.lastVisit || "") > (a.lastVisit || "") ? 1 : -1;
    });
  }, [clientMap, search, sortBy]);

  const daysSince = (isoDate) => {
    if (!isoDate) return null;
    const diff = Math.floor((Date.now() - new Date(isoDate).getTime()) / 86400000);
    return diff;
  };

  const lapsedDays = 60; // highlight clients not seen in 60+ days

  return (
    <>
      <div className="view-h">
        <div>
          <h1>Clients</h1>
          <div className="sub">{clients.length} client{clients.length !== 1 ? "s" : ""} · {Object.keys(clientMap).length} total</div>
        </div>
      </div>

      {/* Toolbar */}
      <div style={{display:"flex", gap:10, marginBottom:16, flexWrap:"wrap"}}>
        <input
          className="bk-input"
          style={{flex:"1 1 200px", maxWidth:320}}
          placeholder="Search by name, email or phone…"
          value={search}
          onChange={(e) => setSearch(e.target.value)}
        />
        <select className="bk-input" style={{width:"auto"}} value={sortBy} onChange={(e) => setSortBy(e.target.value)}>
          <option value="lastVisit">Sort: Last visit</option>
          <option value="totalSpend">Sort: Highest spend</option>
          <option value="totalBookings">Sort: Most bookings</option>
          <option value="name">Sort: Name A–Z</option>
        </select>
      </div>

      {clients.length === 0 ? (
        <div className="card" style={{padding:"40px 20px", textAlign:"center", color:"var(--text-muted)"}}>
          {search ? "No clients match your search." : "No clients yet — bookings will appear here automatically."}
        </div>
      ) : (
        <div style={{display:"flex", flexDirection:"column", gap:8}}>
          {clients.map((c) => {
            const isExpanded = expanded === c.email;
            const ds = daysSince(c.lastVisit);
            const isLapsed = ds !== null && ds >= lapsedDays;
            const upcoming = c.bookings.filter((b) => b.date >= new Date().toISOString().slice(0, 10) && b.status !== "Cancelled");
            const past     = c.bookings.filter((b) => b.date <  new Date().toISOString().slice(0, 10) || b.status === "Cancelled");
            return (
              <div key={c.email} className="card" style={{overflow:"hidden"}}>
                {/* Client row */}
                <div
                  style={{display:"flex", alignItems:"center", gap:12, padding:"14px 18px", cursor:"pointer"}}
                  onClick={() => setExpanded(isExpanded ? null : c.email)}
                >
                  {/* Avatar */}
                  <div style={{
                    width:38, height:38, borderRadius:"50%", flexShrink:0,
                    background:"var(--accent)", display:"flex", alignItems:"center",
                    justifyContent:"center", fontSize:14, fontWeight:700, color:"#fff",
                  }}>
                    {(c.name || "?").charAt(0).toUpperCase()}
                  </div>

                  {/* Name + email */}
                  <div style={{flex:1, minWidth:0}}>
                    <div style={{fontWeight:600, fontSize:14, whiteSpace:"nowrap", overflow:"hidden", textOverflow:"ellipsis"}}>{c.name}</div>
                    <div style={{fontSize:12, color:"var(--text-muted)", whiteSpace:"nowrap", overflow:"hidden", textOverflow:"ellipsis"}}>{c.email}{c.phone ? ` · ${c.phone}` : ""}</div>
                  </div>

                  {/* Stats */}
                  <div style={{display:"flex", gap:20, alignItems:"center", flexShrink:0}}>
                    <div style={{textAlign:"right", display:"none"}} className="client-stat-md">
                      <div style={{fontSize:13, fontWeight:600}}>{formatMoney(c.totalSpend, currency.code)}</div>
                      <div style={{fontSize:11, color:"var(--text-muted)"}}>total spend</div>
                    </div>
                    <div style={{textAlign:"right"}}>
                      <div style={{fontSize:13, fontWeight:600}}>{c.bookings.length}</div>
                      <div style={{fontSize:11, color:"var(--text-muted)"}}>bookings</div>
                    </div>
                    <div style={{textAlign:"right"}}>
                      <div style={{fontSize:13, fontWeight:600}}>{c.lastVisit ? formatIsoDate(c.lastVisit, {}) : "—"}</div>
                      <div style={{fontSize:11, color: isLapsed ? "var(--danger)" : "var(--text-muted)"}}>
                        {isLapsed ? `${ds}d ago` : "last visit"}
                      </div>
                    </div>
                    {isLapsed && (
                      <span style={{
                        fontSize:11, fontWeight:600, background:"#fef2f2", color:"#dc2626",
                        border:"1px solid #fecaca", borderRadius:6, padding:"2px 8px", flexShrink:0,
                      }}>Lapsed</span>
                    )}
                    {upcoming.length > 0 && (
                      <span style={{
                        fontSize:11, fontWeight:600, background:"#f0fdf4", color:"#16a34a",
                        border:"1px solid #bbf7d0", borderRadius:6, padding:"2px 8px", flexShrink:0,
                      }}>{upcoming.length} upcoming</span>
                    )}
                    <I.arrow size={14} style={{color:"var(--text-faint)", transform: isExpanded ? "rotate(90deg)" : "none", transition:"transform 0.15s"}}/>
                  </div>
                </div>

                {/* Expanded booking history */}
                {isExpanded && (
                  <div style={{borderTop:"1px solid var(--border)", padding:"16px 18px", background:"var(--surface-2)"}}>
                    <div style={{display:"flex", gap:24, marginBottom:16, flexWrap:"wrap"}}>
                      <div>
                        <div style={{fontSize:11, color:"var(--text-muted)", marginBottom:2}}>Total spend</div>
                        <div style={{fontWeight:700, fontSize:16}}>{formatMoney(c.totalSpend, currency.code)}</div>
                      </div>
                      <div>
                        <div style={{fontSize:11, color:"var(--text-muted)", marginBottom:2}}>Services used</div>
                        <div style={{fontSize:13}}>{c.services.join(", ") || "—"}</div>
                      </div>
                      {c.phone && (
                        <div>
                          <div style={{fontSize:11, color:"var(--text-muted)", marginBottom:2}}>Phone</div>
                          <div style={{fontSize:13}}>{c.phone}</div>
                        </div>
                      )}
                    </div>

                    {/* Booking history table */}
                    <div style={{fontSize:12, fontWeight:600, color:"var(--text-muted)", marginBottom:8, textTransform:"uppercase", letterSpacing:"0.05em"}}>Booking history</div>
                    <table className="table" style={{fontSize:13}}>
                      <thead>
                        <tr>
                          <th>Date</th>
                          <th>Service</th>
                          <th>Staff</th>
                          <th>Status</th>
                          <th>Paid</th>
                        </tr>
                      </thead>
                      <tbody>
                        {c.bookings.slice().sort((a, b) => b.date > a.date ? 1 : -1).map((b) => (
                          <tr key={b.id}>
                            <td style={{whiteSpace:"nowrap"}}>{formatIsoDate(b.date, {})} {b.time ? `· ${b.time}` : ""}</td>
                            <td>{b.eventName || "—"}</td>
                            <td style={{color:"var(--text-muted)"}}>{b.staffName || "—"}</td>
                            <td>
                              <span className={"pill " + (
                                b.status === "Confirmed"   ? "confirmed" :
                                b.status === "Cancelled"   ? "cancelled"  :
                                b.status === "No-show"     ? "cancelled"  : "pending"
                              )}>
                                {b.status || "Confirmed"}
                              </span>
                            </td>
                            <td>{b.paymentAmount > 0 ? formatMoney(b.paymentAmount, currency.code) : <span style={{color:"var(--text-faint)"}}>—</span>}</td>
                          </tr>
                        ))}
                      </tbody>
                    </table>

                    {/* Quick actions */}
                    <div style={{display:"flex", gap:8, marginTop:14, flexWrap:"wrap"}}>
                      <a
                        href={`mailto:${c.email}`}
                        className="btn ghost"
                        style={{fontSize:12, textDecoration:"none"}}
                      >
                        <I.mail size={13}/> Email client
                      </a>
                      {c.phone && (
                        <a
                          href={`tel:${c.phone}`}
                          className="btn ghost"
                          style={{fontSize:12, textDecoration:"none"}}
                        >
                          <I.phone size={13}/> Call
                        </a>
                      )}
                    </div>
                  </div>
                )}
              </div>
            );
          })}
        </div>
      )}
    </>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Referral Programme
// ──────────────────────────────────────────────────────────────────────────
function ViewReferrals({ data }) {
  const [referrals, setReferrals] = React.useState(null);
  const [copied, setCopied]       = React.useState(false);
  const profile  = data.profile || {};
  const userId   = data.userId;
  const refCode  = profile.referralCode || "";
  const refUrl   = refCode ? `${APP_ORIGIN}/?ref=${refCode}` : "";

  React.useEffect(() => { fetchReferrals(userId).then(setReferrals); }, [userId]);

  const handleCopy = () => {
    navigator.clipboard.writeText(refUrl).then(() => {
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    });
  };

  const handleGenerate = async () => {
    const code = await generateReferralCode(userId);
    // Refresh page data by updating the profile in place
    profile.referralCode = code;
    setReferrals(r => [...(r || [])]);
    window.location.reload();
  };

  const rewarded = (referrals || []).filter(r => r.status === "rewarded").length;
  const pending  = (referrals || []).filter(r => r.status !== "rewarded").length;

  return (
    <>
      <div className="view-h">
        <div>
          <h1>Referral programme</h1>
          <div className="sub">Earn £10/month credit for every paying customer you refer to Nexus Booking.</div>
        </div>
      </div>

      {/* Stats row */}
      <div style={{display:"grid",gridTemplateColumns:"repeat(3,1fr)",gap:12,marginBottom:20}}>
        {[
          { label:"Total referrals", value:(referrals || []).length },
          { label:"Rewarded",        value:rewarded },
          { label:"Credits earned",  value:`£${rewarded * 5}–${rewarded * 10}/mo` },
        ].map(s => (
          <div key={s.label} className="card" style={{padding:"16px 20px",textAlign:"center"}}>
            <div style={{fontSize:26,fontWeight:800,letterSpacing:"-0.02em",color:"var(--accent)"}}>{s.value}</div>
            <div style={{fontSize:12,color:"var(--text-muted)",marginTop:4}}>{s.label}</div>
          </div>
        ))}
      </div>

      {/* Referral link card */}
      <div className="card" style={{padding:"20px 24px",marginBottom:20}}>
        <div style={{fontWeight:600,marginBottom:12}}>Your referral link</div>
        {refUrl ? (
          <div style={{display:"flex",gap:8,alignItems:"center"}}>
            <input className="bk-input" readOnly value={refUrl} style={{flex:1,fontSize:13,fontFamily:"monospace"}}/>
            <button className="btn primary" onClick={handleCopy} style={{whiteSpace:"nowrap"}}>
              {copied ? <><I.check size={13}/> Copied!</> : "Copy link"}
            </button>
          </div>
        ) : (
          <div>
            <p style={{color:"var(--text-muted)",fontSize:13,margin:"0 0 12px"}}>Generate your unique referral link to start earning credits.</p>
            <button className="btn primary" onClick={handleGenerate}>Generate my referral link</button>
          </div>
        )}
        <div style={{marginTop:12,fontSize:12,color:"var(--text-muted)",lineHeight:1.6}}>
          Share this link with other business owners. When they sign up and start paying for Nexus Booking, you'll automatically receive £5/month credit off your subscription — or £10/month if they're on the highest plan. Credit applies for 12 months per referral.
        </div>
      </div>

      {/* Referral history */}
      <div className="card">
        <div style={{padding:"14px 20px",fontWeight:600,borderBottom:"1px solid var(--border)"}}>Referral history</div>
        {!referrals ? (
          <div style={{padding:"32px",textAlign:"center"}}><div className="loading-dots"><span/><span/><span/></div></div>
        ) : referrals.length === 0 ? (
          <div style={{padding:"32px",textAlign:"center",color:"var(--text-muted)",fontSize:13}}>
            No referrals yet — share your link to get started.
          </div>
        ) : (
          <table className="table">
            <thead>
              <tr><th>Referred</th><th>Date</th><th>Status</th><th>Credit</th></tr>
            </thead>
            <tbody>
              {referrals.map(r => (
                <tr key={r.id}>
                  <td style={{fontSize:13}}>{r.referred_email || "—"}</td>
                  <td style={{fontSize:12,color:"var(--text-muted)"}}>
                    {r.created_at ? new Date(r.created_at).toLocaleDateString("en-GB",{day:"numeric",month:"short",year:"numeric"}) : "—"}
                  </td>
                  <td>
                    <span className={"pill " + (r.status === "rewarded" ? "confirmed" : r.status === "signed_up" ? "pending" : "")}>
                      {r.status === "rewarded" ? "Rewarded" : r.status === "signed_up" ? "Signed up" : "Pending"}
                    </span>
                  </td>
                  <td style={{fontSize:13,fontWeight:600,color:r.status === "rewarded" ? "#059669" : "var(--text-faint)"}}>
                    {r.status === "rewarded" ? "+£10/mo" : "—"}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </div>
    </>
  );
}

function InternalView({ active, industry, data, actions, onOpenBooking, onViewAccount }) {
  switch (active) {
    case "calendar":     return <ViewCalendar data={data}/>;
    case "bookings":     return <ViewBookings industry={industry} data={data} actions={actions} onOpenBooking={onOpenBooking}/>;
    case "clients":      return <ViewClients data={data}/>;
    case "events":       return <ViewEventTypes industry={industry} data={data} actions={actions}/>;
    case "availability": return <ViewAvailability data={data} actions={actions}/>;
    case "teams":        return <ViewTeams data={data} actions={actions}/>;
    case "locations":    return <ViewLocations data={data} actions={actions}/>;
    case "integrations": return <ViewIntegrations data={data} actions={actions}/>;
    case "reviews":      return <ViewReviews data={data}/>;
    case "coupons":      return <ViewCoupons data={data}/>;
    case "vouchers":     return <ViewVouchers data={data}/>;
    case "packages":     return <ViewPackages data={data}/>;
    case "resources":    return <ViewResources data={data}/>;
    case "memberships":  return <ViewMemberships data={data}/>;
    case "referrals":    return <ViewReferrals data={data}/>;
    case "analytics":    return <ViewAnalytics data={data}/>;
    case "billing":      return <ViewBilling industry={industry} data={data}/>;
    case "settings":     return <ViewSettings data={data} actions={actions}/>;
    case "platform":     return data?.profile?.isSuperAdmin
                           ? <ViewPlatform onViewAccount={onViewAccount}/>
                           : <div style={{padding:40,textAlign:"center",color:"var(--text-muted)"}}>Access denied.</div>;
    case "setup":        return <ViewSetupGuide/>;
    default:             return null;
  }
}

window.InternalView = InternalView;
