/* global React, I, S */
/* Pamp — Vendor (Business) portal */

const V_NAV = [
  { key: "dashboard", label: "Dashboard", icon: I.dashboard },
  { key: "appointments", label: "Appointments", icon: I.calendar, badge: "12" },
  { key: "services", label: "Services", icon: I.scissors },
  { key: "gallery", label: "Gallery", icon: I.sparkle },
  { key: "clients", label: "Clients", icon: I.users },
  { key: "staff", label: "Staff", icon: I.staff },
  { section: "Money" },
  { key: "wallet", label: "Wallets & earnings", icon: I.wallet },
  { key: "plan", label: "My plan", icon: I.crown },
  { section: "Insight" },
  { key: "reports", label: "Reports", icon: I.chart },
  { key: "support", label: "Support", icon: I.help },
  { key: "settings", label: "Settings", icon: I.settings },
];

function VendorApp({ collapsed, onToggle, onTheme, theme, onExit, session, onNavigate, currentPage }) {
  const page = currentPage || "dashboard";
  const setPage = onNavigate;
  const userId = session?.user?.id;
  const profile = session?.profile;
  const toast = window.useToast();
  // undefined = still loading; null = loaded but no vendor_profile row exists
  const [vendor, setVendor] = React.useState(undefined);
  const [vendorLoadKey, setVendorLoadKey] = React.useState(0);
  const [creating, setCreating] = React.useState(false);

  React.useEffect(() => {
    if (!userId) return;
    let alive = true;
    setVendor(undefined);
    SB.getVendorProfile(userId).then(v => { if (alive) setVendor(v); });
    return () => { alive = false; };
  }, [userId, vendorLoadKey]);

  const reloadVendor = () => setVendorLoadKey(k => k + 1);

  // Still loading
  if (vendor === undefined) {
    return (
      <div className="app-root" style={{ alignItems: "center", justifyContent: "center" }}>
        <div className="loading-state"><div className="spin" /><div>Loading your studio…</div></div>
      </div>
    );
  }

  // Loaded but no vendor_profile - prompt to create one
  if (vendor === null) {
    const createStudio = async () => {
      setCreating(true);
      try {
        const defaultName = profile?.full_name ? `${profile.full_name}'s Studio` : "My Studio";
        const ownerName   = profile?.full_name || profile?.email || "Owner";
        // Call the SECURITY DEFINER RPC so we bypass RLS for this initial
        // insert. The function authenticates via auth.uid() and only ever
        // creates a row for the calling user.
        const { data, error } = await SB.client.rpc("create_my_vendor_profile", {
          p_business_name: defaultName,
          p_owner_name: ownerName,
        });
        if (error) {
          toast.error(error.message || "Couldn't create your studio");
          return;
        }
        toast.success("Studio created — head to Settings to customize.");
        // The RPC returns the new (or existing) row directly. Set it into
        // state so we don't need a follow-up SELECT that could hit RLS.
        if (data) setVendor(data);
        else reloadVendor();
      } finally {
        setCreating(false);
      }
    };

    return (
      <div className="app-root" style={{ alignItems: "center", justifyContent: "center", padding: 24 }}>
        <div className="card" style={{ maxWidth: 480, padding: 32, textAlign: "center" }}>
          <div style={{
            width: 64, height: 64, borderRadius: 16, margin: "0 auto 18px",
            background: "var(--accent-soft)", color: "var(--accent-ink)",
            display: "inline-flex", alignItems: "center", justifyContent: "center",
          }}>
            <I.store size={28} />
          </div>
          <div className="display" style={{ fontSize: 24, letterSpacing: "-0.02em" }}>Your studio isn't set up yet</div>
          <p className="muted" style={{ fontSize: 13.5, lineHeight: 1.6, marginTop: 8, marginBottom: 22 }}>
            Your account exists but you don't have a vendor profile yet. Tap below to create one
            with default settings — you can customize the name, logo, and details in Settings right after.
          </p>
          <div className="row" style={{ justifyContent: "center", gap: 8 }}>
            <S.Btn variant="ghost" onClick={onExit} disabled={creating}>Sign out</S.Btn>
            <S.Btn variant="primary" icon={<I.plus size={14} />} onClick={createStudio} disabled={creating}>
              {creating ? "Creating…" : "Create my studio"}
            </S.Btn>
          </div>
        </div>
      </div>
    );
  }

  const vendorId = vendor.id;

  return (
    <div className="shell" data-sidebar={collapsed ? "collapsed" : "expanded"}>
      <S.Sidebar
        items={V_NAV}
        current={page}
        onNav={setPage}
        collapsed={collapsed}
        footer={
          <button className="nav-item" onClick={onExit} style={{ width: "100%" }} data-tip="Sign out">
            <span className="ni-icon"><I.logout size={18} /></span>
            <span className="ni-label">Sign out</span>
          </button>
        }
      />
      <div className="main-col">
        <S.Topbar
          onToggleSidebar={onToggle}
          onTheme={onTheme}
          theme={theme}
          search="Search clients, appointments, services…"
          right={<>
            <S.IconBtn title="Messages" style={{ position: "relative" }}>
              <I.mail size={18} />
            </S.IconBtn>
            <S.IconBtn title="Calendar" onClick={() => setPage("appointments")}><I.calendar size={18} /></S.IconBtn>
          </>}
        />
        <main className="main-scroll">
          {page === "dashboard"    && <VendorDashboard vendorId={vendorId} vendor={vendor} onNav={setPage} />}
          {page === "appointments" && <VendorCalendar vendorId={vendorId} />}
          {page === "services"     && <VendorServices vendorId={vendorId} />}
          {page === "gallery"      && <VendorGallery />}
          {page === "clients"      && <VendorClients vendorId={vendorId} />}
          {page === "staff"        && <VendorStaff />}
          {page === "wallet"       && <VendorWallet vendorId={vendorId} vendor={vendor} />}
          {page === "plan"         && <VendorPlan />}
          {page === "reports"      && <VendorReports vendorId={vendorId} />}
          {page === "support"      && <VendorSupport />}
          {page === "settings"     && <VendorSettings vendor={vendor} onSaved={reloadVendor} />}
        </main>
      </div>
    </div>
  );
}

/* ====================================================================
   VENDOR — DASHBOARD
   ==================================================================== */
function VendorDashboard({ vendorId, vendor, onNav }) {
  const [bookings, setBookings] = React.useState(null);

  React.useEffect(() => {
    if (!vendorId) return;
    let alive = true;
    SB.getVendorBookings(vendorId).then(b => { if (alive) setBookings(b || []); });
    return () => { alive = false; };
  }, [vendorId]);

  if (!vendor) {
    return <div className="page-enter">
      <window.EmptyState
        icon={<I.store size={24} />}
        title="Your studio profile isn't set up"
        sub="Go to Settings to create your vendor profile."
      />
    </div>;
  }
  if (bookings === null) return <div className="page-enter"><window.LoadingState /></div>;

  // Compute stats
  const today = new Date().toISOString().slice(0, 10);
  const todayBookings  = bookings.filter(b => b.booking_date === today);
  const todayConfirmed = todayBookings.filter(b => b.status === "confirmed" || b.status === "in_progress" || b.status === "completed");
  const todayRevenue   = todayConfirmed.reduce((s, b) => s + Number(b.total_price || 0), 0);
  const upcoming       = bookings.filter(b => {
    if (b.status === "cancelled" || b.status === "completed" || b.status === "no_show") return false;
    return b.booking_date >= today;
  });
  const next = upcoming.sort((a, b) => {
    const ta = new Date(`${a.booking_date}T${a.start_time || "00:00"}`).getTime();
    const tb = new Date(`${b.booking_date}T${b.start_time || "00:00"}`).getTime();
    return ta - tb;
  })[0];

  const greeting = (() => {
    const h = new Date().getHours();
    if (h < 12) return "Good morning";
    if (h < 18) return "Good afternoon";
    return "Good evening";
  })();
  const firstName = (vendor.business_name || "").split(" ")[0];

  // Today's timeline - sort by time
  const timelineToday = todayBookings.sort((a, b) => (a.start_time || "").localeCompare(b.start_time || ""));

  return (
    <div className="page-enter">
      <S.PageHead
        eyebrow={`${vendor.business_name || "Your studio"}${vendor.city ? " · " + vendor.city : ""}`}
        title={`${greeting}${firstName ? `, ${firstName}` : ""}.`}
        sub={todayBookings.length === 0
          ? "Nothing on the books for today. Take it easy or fill the calendar."
          : `${todayBookings.length} appointment${todayBookings.length === 1 ? "" : "s"} today · ${todayConfirmed.length} confirmed.`}
        right={<>
          <S.Btn variant="outline" size="sm" icon={<I.calendar size={14} />} onClick={() => onNav?.("appointments")}>Calendar</S.Btn>
          <S.Btn variant="primary" size="sm" icon={<I.plus size={14} />} onClick={() => onNav?.("appointments")}>New appointment</S.Btn>
        </>}
      />

      <div style={{ display: "grid", gridTemplateColumns: "2.2fr 1fr 1fr 1fr", gap: 20, marginBottom: 20 }}>
        <div className="card" style={{ display: "flex", flexDirection: "column", justifyContent: "space-between", minHeight: 180 }}>
          <div className="row between">
            <div className="eyebrow">Today's revenue</div>
            <S.Chip tone={todayConfirmed.length > 0 ? "pos" : ""}>{todayConfirmed.length} booking{todayConfirmed.length === 1 ? "" : "s"}</S.Chip>
          </div>
          <div>
            <div className="display" style={{ fontSize: 56, letterSpacing: "-0.035em", lineHeight: 1 }}>{window.fmtMoney(todayRevenue)}</div>
            <div className="muted tiny" style={{ marginTop: 6 }}>
              {todayBookings.length === 0 ? "No bookings yet today" : `From ${todayConfirmed.length} confirmed${todayBookings.length > todayConfirmed.length ? ` · ${todayBookings.length - todayConfirmed.length} pending` : ""}`}
            </div>
          </div>
        </div>
        <S.Metric label="Today" value={todayBookings.length.toString()} delta={todayConfirmed.length > 0 ? `${todayConfirmed.length} confirmed` : ""} />
        <S.Metric label="Upcoming" value={upcoming.length.toString()} delta="Next 30 days" />
        <S.Metric label="All bookings" value={bookings.length.toString()} delta="All time" />
      </div>

      <div className="grid-12" style={{ marginBottom: 20 }}>
        <div className="card" style={{ gridColumn: "span 8" }}>
          <div className="row between" style={{ marginBottom: 18 }}>
            <div>
              <div className="h3">Today's schedule</div>
              <div className="muted tiny" style={{ marginTop: 4 }}>{new Date().toLocaleDateString(undefined, { weekday: "long", month: "long", day: "numeric" })}</div>
            </div>
          </div>
          {timelineToday.length === 0 ? (
            <window.EmptyState icon={<I.calendar size={24} />} title="No appointments today" sub="Enjoy the quiet — or open up bookings on your calendar." />
          ) : (
            <div className="col" style={{ gap: 10 }}>
              {timelineToday.map(b => (
                <div key={b.id} className="row" style={{ gap: 14, padding: "12px 14px", borderRadius: 10, background: "var(--surface-2)" }}>
                  <div className="mono" style={{ fontSize: 13, color: "var(--ink-2)", width: 70, flexShrink: 0 }}>{window.fmtTime(b.start_time)}</div>
                  <div style={{ flex: 1 }}>
                    <div style={{ fontWeight: 500 }}>{b.profiles?.full_name || b.profiles?.email || "Client"}</div>
                    <div className="muted tiny">{b.services?.name || "Service"}</div>
                  </div>
                  <div className="row-tight">
                    <S.Chip tone={window.statusTone(b.status)}>{window.statusLabel(b.status)}</S.Chip>
                    <span className="mono">{window.fmtMoney(b.total_price)}</span>
                  </div>
                </div>
              ))}
            </div>
          )}
        </div>

        <div className="card" style={{ gridColumn: "span 4" }}>
          <div className="h3" style={{ marginBottom: 4 }}>Next up</div>
          <div className="muted tiny" style={{ marginBottom: 18 }}>
            {next ? `${window.fmtDate(next.booking_date)} at ${window.fmtTime(next.start_time)}` : "No upcoming appointments"}
          </div>
          {next ? (
            <div style={{ padding: 18, background: "var(--accent-soft)", borderRadius: 14, marginBottom: 12 }}>
              <div className="row between">
                <S.Chip tone="accent">{window.statusLabel(next.status)}</S.Chip>
                <span className="mono tiny" style={{ color: "var(--accent-ink)" }}>{window.fmtTime(next.start_time)}</span>
              </div>
              <div className="row" style={{ marginTop: 12, gap: 12 }}>
                <S.Avatar name={next.profiles?.full_name || "Client"} size="lg" />
                <div>
                  <div style={{ fontWeight: 500 }}>{next.profiles?.full_name || "Client"}</div>
                  <div className="muted tiny">{next.services?.name || "Service"}</div>
                </div>
              </div>
              <div className="divider" style={{ margin: "12px 0", borderColor: "oklch(0% 0 0 / 0.08)" }} />
              <div className="row between mono tiny">
                <span>{window.fmtDate(next.booking_date)}</span>
                <span>{window.fmtMoney(next.total_price)}</span>
              </div>
            </div>
          ) : (
            <window.EmptyState icon={<I.calendar size={20} />} title="Nothing booked" sub="New bookings will show here." />
          )}
        </div>
      </div>
    </div>
  );
}

/* ====================================================================
   VENDOR — CALENDAR / APPOINTMENTS (List + Week)
   ==================================================================== */
function VendorCalendar({ vendorId }) {
  const toast = window.useToast();
  const [bookings, setBookings] = React.useState(null);
  const [selectedId, setSelectedId] = React.useState(null);
  const [filter, setFilter] = React.useState("upcoming");
  const [reloadKey, setReloadKey] = React.useState(0);

  React.useEffect(() => {
    if (!vendorId) return;
    let alive = true;
    setBookings(null);
    SB.getVendorBookings(vendorId).then(b => { if (alive) setBookings(b || []); });
    return () => { alive = false; };
  }, [vendorId, reloadKey]);

  if (bookings === null) return <div className="page-enter"><window.LoadingState /></div>;

  const today = new Date().toISOString().slice(0, 10);
  const filtered = filter === "upcoming"
    ? bookings.filter(b => b.booking_date >= today && b.status !== "cancelled" && b.status !== "no_show")
    : filter === "past"
      ? bookings.filter(b => b.booking_date < today || b.status === "completed")
      : filter === "cancelled"
        ? bookings.filter(b => b.status === "cancelled" || b.status === "no_show")
        : bookings;
  const selected = filtered.find(b => b.id === selectedId);

  const updateStatus = async (id, status) => {
    const ok = await SB.updateBookingStatus(id, status);
    if (!ok) { toast.error("Update failed"); return; }
    toast.success(`Booking ${status}`);
    setReloadKey(k => k + 1);
    if (status === "cancelled" || status === "completed") setSelectedId(null);
  };

  return (
    <div className="page-enter">
      <S.PageHead
        eyebrow={`${bookings.length} total bookings`}
        title="Calendar"
        sub="All your appointments — past, upcoming, and cancelled."
      />

      <div className="row" style={{ gap: 8, marginBottom: 20 }}>
        {[
          { k: "upcoming",  l: "Upcoming",  n: bookings.filter(b => b.booking_date >= today && b.status !== "cancelled" && b.status !== "no_show").length },
          { k: "past",      l: "Past",      n: bookings.filter(b => b.booking_date < today || b.status === "completed").length },
          { k: "cancelled", l: "Cancelled", n: bookings.filter(b => b.status === "cancelled" || b.status === "no_show").length },
        ].map(f => (
          <button key={f.k} onClick={() => { setFilter(f.k); setSelectedId(null); }}
            className={`btn btn-sm ${filter === f.k ? "btn-primary" : "btn-outline"}`}>
            {f.l} <span className="mono tiny" style={{ marginLeft: 4, opacity: 0.6 }}>{f.n}</span>
          </button>
        ))}
      </div>

      <div style={{ display: "grid", gridTemplateColumns: selected ? "1fr 400px" : "1fr", gap: 20, alignItems: "flex-start" }}>
        <div className="card card-flush">
          {filtered.length === 0 ? (
            <window.EmptyState icon={<I.calendar size={24} />} title="No bookings here" />
          ) : (
            <table className="tbl">
              <thead>
                <tr>
                  <th>When</th>
                  <th>Client</th>
                  <th>Service</th>
                  <th>Status</th>
                  <th className="col-num">Price</th>
                  <th />
                </tr>
              </thead>
              <tbody>
                {filtered.map(b => (
                  <tr key={b.id} onClick={() => setSelectedId(b.id)} style={{ cursor: "pointer", background: selectedId === b.id ? "var(--accent-soft)" : undefined }}>
                    <td>
                      <div className="mono tiny">{window.fmtDate(b.booking_date)}</div>
                      <div className="muted tiny">{window.fmtTime(b.start_time)}</div>
                    </td>
                    <td><div className="row-tight"><S.Avatar name={b.profiles?.full_name || "Client"} size="sm" />{b.profiles?.full_name || "Client"}</div></td>
                    <td>{b.services?.name || "—"}</td>
                    <td><S.Chip tone={window.statusTone(b.status)}>{window.statusLabel(b.status)}</S.Chip></td>
                    <td className="col-num mono">{window.fmtMoney(b.total_price)}</td>
                    <td><S.IconBtn><I.chevR size={14} /></S.IconBtn></td>
                  </tr>
                ))}
              </tbody>
            </table>
          )}
        </div>

        {selected && (
          <div className="card" style={{ padding: 0, position: "sticky", top: 0 }}>
            <div style={{ padding: 22, borderBottom: "1px solid var(--border)" }}>
              <div className="row between">
                <div className="eyebrow">Booking detail</div>
                <S.IconBtn onClick={() => setSelectedId(null)}><I.x size={14} /></S.IconBtn>
              </div>
              <div className="display" style={{ fontSize: 22, marginTop: 8 }}>{selected.profiles?.full_name || "Client"}</div>
              <div className="muted tiny">{selected.profiles?.email || ""}</div>
            </div>
            <div style={{ padding: 22, borderBottom: "1px solid var(--border)" }}>
              <div className="col" style={{ gap: 10 }}>
                <DetailRow label="Service" value={selected.services?.name || "—"} />
                <DetailRow label="Date" value={window.fmtDate(selected.booking_date)} />
                <DetailRow label="Time" value={window.fmtTime(selected.start_time)} />
                <DetailRow label="Total" value={window.fmtMoney(selected.total_price)} mono strong />
                <DetailRow label="Status" value={window.statusLabel(selected.status)} />
                <DetailRow label="Payment" value={window.statusLabel(selected.payment_status || "—")} />
              </div>
            </div>
            <div style={{ padding: 22 }}>
              {selected.status === "pending" && <S.Btn variant="primary" size="sm" style={{ width: "100%", marginBottom: 8 }} onClick={() => updateStatus(selected.id, "confirmed")}>Confirm</S.Btn>}
              {(selected.status === "confirmed" || selected.status === "pending") && <S.Btn variant="outline" size="sm" style={{ width: "100%", marginBottom: 8 }} onClick={() => updateStatus(selected.id, "completed")}>Mark complete</S.Btn>}
              {selected.status !== "cancelled" && selected.status !== "completed" && <S.Btn variant="ghost" size="sm" style={{ width: "100%", color: "var(--neg)" }} onClick={() => updateStatus(selected.id, "cancelled")}>Cancel</S.Btn>}
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

function DetailRow({ label, value, mono, strong }) {
  return (
    <div className="row between">
      <span className="muted tiny">{label}</span>
      <span className={mono ? "mono" : ""} style={{ fontWeight: strong ? 500 : 400 }}>{value}</span>
    </div>
  );
}/* ====================================================================
   VENDOR — SERVICES
   ==================================================================== */
function VendorServices({ vendorId }) {
  const toast = window.useToast();
  const [services, setServices] = React.useState(null);
  const [modalOpen, setModalOpen] = React.useState(false);
  const [editing, setEditing] = React.useState(null);
  const [reloadKey, setReloadKey] = React.useState(0);

  React.useEffect(() => {
    if (!vendorId) return;
    let alive = true;
    setServices(null);
    SB.client
      .from("services")
      .select("*")
      .eq("vendor_id", vendorId)
      .order("created_at", { ascending: false })
      .then(({ data }) => { if (alive) setServices(data || []); });
    return () => { alive = false; };
  }, [vendorId, reloadKey]);

  if (services === null) return <div className="page-enter"><window.LoadingState /></div>;

  const remove = async (svc) => {
    if (!confirm(`Delete "${svc.name}"? This can't be undone.`)) return;
    const { error } = await SB.client.from("services").delete().eq("id", svc.id);
    if (error) { toast.error(error.message || "Delete failed"); return; }
    toast.success("Service deleted");
    setReloadKey(k => k + 1);
  };

  return (
    <div className="page-enter">
      <S.PageHead
        eyebrow={`${services.length} service${services.length === 1 ? "" : "s"}`}
        title="Services"
        sub="What you offer, with pricing and duration. Clients see these when they book."
        right={<S.Btn variant="primary" size="sm" icon={<I.plus size={14} />} onClick={() => { setEditing(null); setModalOpen(true); }}>New service</S.Btn>}
      />

      {services.length === 0 ? (
        <window.EmptyState
          icon={<I.scissors size={24} />}
          title="No services yet"
          sub="Add your first service so clients can book it."
          action={<S.Btn variant="primary" size="sm" icon={<I.plus size={14} />} onClick={() => { setEditing(null); setModalOpen(true); }}>New service</S.Btn>}
        />
      ) : (
        <div className="grid-3">
          {services.map(s => (
            <div key={s.id} className="card" style={{ padding: 22 }}>
              <div className="row between">
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontWeight: 500, fontSize: 15 }}>{s.name}</div>
                  {s.description && <div className="muted tiny" style={{ marginTop: 4 }}>{s.description}</div>}
                </div>
                <div className="row-tight">
                  <S.IconBtn title="Edit" onClick={() => { setEditing(s); setModalOpen(true); }}><I.edit size={14} /></S.IconBtn>
                  <S.IconBtn title="Delete" onClick={() => remove(s)}><I.trash size={14} /></S.IconBtn>
                </div>
              </div>
              <div className="divider" style={{ margin: "14px 0" }} />
              <div className="row between">
                <div>
                  <div className="muted tiny">Price</div>
                  <div className="display" style={{ fontSize: 22 }}>{window.fmtMoney(s.price)}</div>
                </div>
                <div style={{ textAlign: "right" }}>
                  <div className="muted tiny">Duration</div>
                  <div className="display" style={{ fontSize: 22 }}>{s.duration_mins || 60}<span className="muted" style={{ fontSize: 12, fontWeight: 400, marginLeft: 4 }}>min</span></div>
                </div>
              </div>
            </div>
          ))}
        </div>
      )}

      <ServiceFormModal
        open={modalOpen}
        service={editing}
        vendorId={vendorId}
        onClose={() => { setModalOpen(false); setEditing(null); }}
        onSaved={() => { setModalOpen(false); setEditing(null); setReloadKey(k => k + 1); toast.success(editing ? "Service updated" : "Service added"); }}
      />
    </div>
  );
}

function ServiceFormModal({ open, service, vendorId, onClose, onSaved }) {
  const toast = window.useToast();
  const isEdit = !!service;
  const [busy, setBusy] = React.useState(false);
  const [data, setData] = React.useState({ name: "", description: "", price: "", duration_mins: 60 });

  React.useEffect(() => {
    if (open && service) {
      setData({
        name: service.name || "",
        description: service.description || "",
        price: service.price?.toString() || "",
        duration_mins: service.duration_mins || 60,
      });
    } else if (open) {
      setData({ name: "", description: "", price: "", duration_mins: 60 });
    }
  }, [open, service?.id]);

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

  const submit = async () => {
    if (!data.name.trim()) { toast.error("Name is required"); return; }
    const price = parseFloat(data.price);
    if (isNaN(price) || price < 0) { toast.error("Price must be 0 or more"); return; }
    const dur = parseInt(data.duration_mins, 10);
    if (!dur || dur <= 0) { toast.error("Duration must be > 0"); return; }

    setBusy(true);
    try {
      const payload = {
        vendor_id: vendorId,
        name: data.name.trim(),
        description: data.description.trim() || null,
        price,
        duration_mins: dur,
      };
      if (isEdit) {
        const { error } = await SB.client.from("services").update(payload).eq("id", service.id);
        if (error) { toast.error(error.message); return; }
      } else {
        const { error } = await SB.client.from("services").insert(payload);
        if (error) { toast.error(error.message); return; }
      }
      onSaved?.();
    } finally {
      setBusy(false);
    }
  };

  return (
    <window.M.Modal open={open} onClose={onClose} size="lg"
      icon={<I.scissors />}
      title={isEdit ? `Edit ${service?.name}` : "New service"}
      subtitle="Clients see this on your booking page."
      footer={<>
        <S.Btn variant="ghost" onClick={onClose} disabled={busy}>Cancel</S.Btn>
        <S.Btn variant="primary" onClick={submit} disabled={busy}>{busy ? "Saving..." : isEdit ? "Save changes" : "Add service"}</S.Btn>
      </>}>
      <window.M.FormGrid>
        <window.M.Field full label="Service name">
          <window.M.TextField value={data.name} onChange={(v) => set("name", v)} placeholder="e.g. Full color and cut" />
        </window.M.Field>
        <window.M.Field full label="Description" hint="Optional. Shown under the service name.">
          <window.M.Textarea value={data.description} onChange={(v) => set("description", v)} placeholder="What's included, who it's for..." />
        </window.M.Field>
        <window.M.Field label="Price">
          <input className="text-input" type="number" min="0" step="0.01" value={data.price} onChange={(e) => set("price", e.target.value)} placeholder="100.00" />
        </window.M.Field>
        <window.M.Field label="Duration (minutes)">
          <input className="text-input" type="number" min="5" step="5" value={data.duration_mins} onChange={(e) => set("duration_mins", e.target.value)} placeholder="60" />
        </window.M.Field>
      </window.M.FormGrid>
    </window.M.Modal>
  );
}

/* ====================================================================
   VENDOR — CLIENTS
   ==================================================================== */
function VendorClients({ vendorId }) {
  const [bookings, setBookings] = React.useState(null);
  const [searchInput, setSearchInput] = React.useState("");
  const search = window.useDebounce(searchInput, 250);
  const [selected, setSelected] = React.useState(null);

  React.useEffect(() => {
    if (!vendorId) return;
    let alive = true;
    setBookings(null);
    SB.getVendorBookings(vendorId).then(b => { if (alive) setBookings(b || []); });
    return () => { alive = false; };
  }, [vendorId]);

  if (bookings === null) return <div className="page-enter"><window.LoadingState /></div>;

  // Derive clients from bookings - group by client (profiles)
  const clientMap = {};
  bookings.forEach(b => {
    const p = b.profiles;
    if (!p) return;
    const key = p.email || JSON.stringify(p);
    if (!clientMap[key]) {
      clientMap[key] = {
        name: p.full_name || p.email || "—",
        email: p.email || "",
        bookings: 0,
        completed: 0,
        upcoming: 0,
        cancelled: 0,
        totalSpent: 0,
        lastVisit: null,
      };
    }
    const c = clientMap[key];
    c.bookings += 1;
    if (b.status === "completed") {
      c.completed += 1;
      c.totalSpent += Number(b.total_price || 0);
    } else if (b.status === "cancelled" || b.status === "no_show") {
      c.cancelled += 1;
    } else {
      c.upcoming += 1;
    }
    if (b.booking_date && (!c.lastVisit || b.booking_date > c.lastVisit)) c.lastVisit = b.booking_date;
  });

  let clients = Object.values(clientMap).sort((a, b) => b.totalSpent - a.totalSpent);
  if (search) {
    const q = search.toLowerCase();
    clients = clients.filter(c => c.name.toLowerCase().includes(q) || c.email.toLowerCase().includes(q));
  }

  return (
    <div className="page-enter">
      <S.PageHead
        eyebrow={`${clients.length} client${clients.length === 1 ? "" : "s"}`}
        title="Clients"
        sub="Everyone who's booked with you, ranked by lifetime value."
      />

      <div className="card card-flush">
        <div className="row" style={{ padding: 16, gap: 10 }}>
          <S.Input
            icon={<I.search size={15} />}
            placeholder="Search by name or email..."
            style={{ flex: 1, maxWidth: 360 }}
            value={searchInput}
            onChange={(e) => setSearchInput(e.target.value)}
          />
        </div>
        {clients.length === 0 ? (
          <window.EmptyState icon={<I.users size={24} />} title={search ? "No matches" : "No clients yet"} sub={search ? "Try a different search term." : "Clients appear here once they book with you."} />
        ) : (
          <table className="tbl">
            <thead>
              <tr>
                <th>Client</th>
                <th>Bookings</th>
                <th>Status</th>
                <th>Last visit</th>
                <th className="col-num">Lifetime value</th>
              </tr>
            </thead>
            <tbody>
              {clients.map((c, i) => (
                <tr key={i} onClick={() => setSelected(c)} style={{ cursor: "pointer" }}>
                  <td>
                    <div className="row-tight">
                      <S.Avatar name={c.name} size="sm" />
                      <div>
                        <div style={{ fontWeight: 500 }}>{c.name}</div>
                        <div className="muted tiny">{c.email}</div>
                      </div>
                    </div>
                  </td>
                  <td className="mono">{c.bookings}</td>
                  <td>
                    <div className="row-tight" style={{ flexWrap: "wrap", gap: 4 }}>
                      {c.completed > 0 && <span className="muted tiny">{c.completed} done</span>}
                      {c.upcoming > 0 && <S.Chip tone="warn">{c.upcoming} upcoming</S.Chip>}
                    </div>
                  </td>
                  <td className="mono muted">{c.lastVisit ? window.fmtDate(c.lastVisit) : "—"}</td>
                  <td className="col-num mono" style={{ fontWeight: 500 }}>{window.fmtMoney(c.totalSpent)}</td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </div>

      {selected && (
        <window.M.Modal open={!!selected} onClose={() => setSelected(null)} size="lg"
          icon={<I.users />}
          title={selected.name}
          subtitle={selected.email}
          footer={<S.Btn variant="primary" onClick={() => setSelected(null)}>Close</S.Btn>}>
          <div className="grid-2" style={{ gap: 14 }}>
            <div style={{ padding: 14, background: "var(--surface-2)", borderRadius: 10 }}>
              <div className="muted tiny">Total bookings</div>
              <div className="display" style={{ fontSize: 22, marginTop: 4 }}>{selected.bookings}</div>
            </div>
            <div style={{ padding: 14, background: "var(--surface-2)", borderRadius: 10 }}>
              <div className="muted tiny">Lifetime value</div>
              <div className="display" style={{ fontSize: 22, marginTop: 4 }}>{window.fmtMoney(selected.totalSpent)}</div>
            </div>
            <div style={{ padding: 14, background: "var(--surface-2)", borderRadius: 10 }}>
              <div className="muted tiny">Completed</div>
              <div className="display" style={{ fontSize: 22, marginTop: 4 }}>{selected.completed}</div>
            </div>
            <div style={{ padding: 14, background: "var(--surface-2)", borderRadius: 10 }}>
              <div className="muted tiny">Cancelled / no-show</div>
              <div className="display" style={{ fontSize: 22, marginTop: 4 }}>{selected.cancelled}</div>
            </div>
          </div>
          {selected.lastVisit && (
            <div style={{ marginTop: 16 }}>
              <div className="muted tiny">Last visit</div>
              <div style={{ fontSize: 14, marginTop: 4 }}>{window.fmtDate(selected.lastVisit)}</div>
            </div>
          )}
        </window.M.Modal>
      )}
    </div>
  );
}

/* ====================================================================
   VENDOR — STAFF
   ==================================================================== */
const STAFF_ROLES = [
  { value: "Manager", label: "Manager", desc: "Full access to schedules, services, and reports." },
  { value: "Reception", label: "Reception", desc: "Bookings, client check-in, and front desk." },
  { value: "Therapist", label: "Therapist / Service provider", desc: "Owns their calendar and clients." },
  { value: "Custom", label: "Custom role", desc: "Define your own set of permissions." },
];

const STAFF_PERMISSIONS = [
  { id: "bookings", label: "Bookings · view & edit" },
  { id: "clients", label: "Clients · view & contact" },
  { id: "services", label: "Services & pricing" },
  { id: "payouts", label: "Wallet & payouts" },
  { id: "reports", label: "Reports & analytics" },
  { id: "team", label: "Manage other staff" },
];

const INITIAL_STAFF = [
  { id: "s1", name: "Léa Marchand", role: "Manager", email: "lea@maisoncolor.fr", phone: "+33 6 12 34 56 78", status: "Active", joined: "Apr 12, 2023", bookings: 312, util: 96, rating: 4.9 },
  { id: "s2", name: "Camille Roy", role: "Therapist", email: "camille@maisoncolor.fr", phone: "+33 6 21 45 89 01", status: "Active", joined: "Aug 02, 2023", bookings: 284, util: 88, rating: 4.8 },
  { id: "s3", name: "Inès Khan", role: "Therapist", email: "ines@maisoncolor.fr", phone: "+33 6 98 12 33 02", status: "Active", joined: "Jan 18, 2024", bookings: 198, util: 92, rating: 4.9 },
  { id: "s4", name: "Nora Beaumont", role: "Reception", email: "nora@maisoncolor.fr", phone: "+33 6 44 11 76 91", status: "Active", joined: "Sep 04, 2024", bookings: 0, util: 64, rating: null },
  { id: "s5", name: "Theo Sun", role: "Therapist", email: "theo@maisoncolor.fr", phone: "+33 6 22 78 45 19", status: "Pending", joined: "Invited Feb 1", bookings: 0, util: 0, rating: null },
  { id: "s6", name: "Mira Aoki", role: "Custom", email: "mira@maisoncolor.fr", phone: "+33 6 31 02 19 87", status: "Suspended", joined: "Feb 19, 2024", bookings: 142, util: 0, rating: 4.7 },
];

function VendorStaff() {
  const [staff, setStaff] = React.useState(INITIAL_STAFF);
  const [addOpen, setAddOpen] = React.useState(false);
  const [editing, setEditing] = React.useState(null);
  const [confirm, setConfirm] = React.useState(null);
  const [filter, setFilter] = React.useState("all");

  const filtered = staff.filter(s => filter === "all" ? true : filter === "active" ? s.status === "Active" : filter === "pending" ? s.status === "Pending" : s.status === "Suspended");

  const counts = {
    total: staff.length,
    active: staff.filter(s => s.status === "Active").length,
    pending: staff.filter(s => s.status === "Pending").length,
    suspended: staff.filter(s => s.status === "Suspended").length,
    roles: new Set(staff.map(s => s.role)).size,
  };

  const saveStaff = (next) => {
    if (editing) setStaff(staff.map(s => s.id === editing.id ? { ...s, ...next } : s));
    else setStaff([...staff, {
      ...next, id: "s" + Date.now(), status: "Pending",
      joined: "Invited " + new Date().toLocaleDateString("en-US", { month: "short", day: "numeric" }),
      bookings: 0, util: 0, rating: null,
    }]);
    setAddOpen(false); setEditing(null);
  };
  const removeStaff = (id) => { setStaff(staff.filter(s => s.id !== id)); setConfirm(null); };
  const setStatus = (id, status) => setStaff(staff.map(s => s.id === id ? { ...s, status } : s));

  return (
    <div className="page-enter">
      <window.DemoBanner feature="staff management" />
      <S.PageHead
        eyebrow={`Team · ${counts.total} members`}
        title="Staff"
        sub="Invite team members, assign roles, and manage permissions for your studio."
        right={<>
          <S.Btn variant="outline" size="sm" icon={<I.filter size={14} />}>Roles</S.Btn>
          <S.Btn variant="primary" size="sm" icon={<I.plus size={14} />} onClick={() => { setEditing(null); setAddOpen(true); }}>Add staff</S.Btn>
        </>}
      />

      {/* Summary cards */}
      <div className="grid-4" style={{ marginBottom: 20 }}>
        <S.Metric hero label="Total staff" value={String(counts.total)} delta={`+${counts.pending} this month`} />
        <S.Metric label="Active" value={String(counts.active)} delta={`${Math.round(counts.active / counts.total * 100)}% of team`} deltaTone="pos" />
        <S.Metric label="Pending invites" value={String(counts.pending)} delta={counts.pending > 0 ? "Awaiting response" : "All accepted"} deltaTone={counts.pending > 0 ? "warn" : "pos"} />
        <S.Metric label="Roles" value={String(counts.roles)} delta="Across team" />
      </div>

      {/* Directory */}
      <div className="card card-flush">
        <div className="row between" style={{ padding: 16, gap: 10, flexWrap: "wrap", borderBottom: "1px solid var(--border)" }}>
          <div className="row" style={{ gap: 10 }}>
            <S.Input icon={<I.search size={15} />} placeholder="Search by name, role, email…" style={{ flex: 1, maxWidth: 320 }} />
            <div className="segmented">
              {[{ k: "all", l: "All" }, { k: "active", l: "Active" }, { k: "pending", l: "Pending" }, { k: "suspended", l: "Suspended" }].map(t => (
                <button key={t.k} className={filter === t.k ? "active" : ""} onClick={() => setFilter(t.k)}>{t.l}</button>
              ))}
            </div>
          </div>
          <span className="muted tiny">Showing {filtered.length} of {staff.length}</span>
        </div>

        <table className="tbl">
          <thead>
            <tr>
              <th>Staff member</th>
              <th>Role</th>
              <th>Email</th>
              <th>Phone</th>
              <th>Status</th>
              <th>Joined</th>
              <th style={{ width: 160 }}>Actions</th>
            </tr>
          </thead>
          <tbody>
            {filtered.map(s => (
              <tr key={s.id}>
                <td>
                  <div className="row-tight" style={{ gap: 12 }}>
                    <S.Avatar name={s.name} size="sm" />
                    <div>
                      <div style={{ fontWeight: 500 }}>{s.name}</div>
                      <div className="muted tiny">
                        {s.status === "Active" && s.bookings > 0 ? `${s.bookings} bookings · ${s.util}% util` :
                         s.status === "Pending" ? "Invitation sent" : "—"}
                      </div>
                    </div>
                  </div>
                </td>
                <td><S.Chip tone={s.role === "Manager" ? "accent" : s.role === "Reception" ? "info" : s.role === "Custom" ? "warn" : ""}>{s.role}</S.Chip></td>
                <td className="muted">{s.email}</td>
                <td className="muted">{s.phone}</td>
                <td><S.Chip tone={s.status === "Active" ? "pos" : s.status === "Pending" ? "warn" : "neg"}>{s.status}</S.Chip></td>
                <td className="muted">{s.joined}</td>
                <td>
                  <div className="row-tight" style={{ gap: 4 }}>
                    <S.IconBtn title="Edit" onClick={() => { setEditing(s); setAddOpen(true); }}><I.settings size={15} /></S.IconBtn>
                    {s.status === "Suspended" ? (
                      <S.IconBtn title="Reactivate" onClick={() => setStatus(s.id, "Active")}><I.check size={15} /></S.IconBtn>
                    ) : s.status === "Active" ? (
                      <S.IconBtn title="Suspend" onClick={() => setStatus(s.id, "Suspended")}><I.eyeOff size={15} /></S.IconBtn>
                    ) : (
                      <S.IconBtn title="Resend invite" onClick={() => {}}><I.mail size={15} /></S.IconBtn>
                    )}
                    <S.IconBtn title="Remove" onClick={() => setConfirm(s)}><I.x size={15} /></S.IconBtn>
                  </div>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      <AddStaffModal
        open={addOpen}
        staff={editing}
        onClose={() => { setAddOpen(false); setEditing(null); }}
        onSave={saveStaff}
      />
      <window.M.ConfirmModal
        open={!!confirm}
        onClose={() => setConfirm(null)}
        onConfirm={() => removeStaff(confirm?.id)}
        title={`Remove ${confirm?.name}?`}
        body="They'll lose access to your studio immediately. Their booking history stays intact."
        confirmLabel="Remove staff"
        danger
        icon={<I.x />}
      />
    </div>
  );
}

function AddStaffModal({ open, staff, onClose, onSave }) {
  const [data, setData] = React.useState({ name: "", email: "", phone: "", role: "Therapist", perms: ["bookings", "clients"] });
  const [errors, setErrors] = React.useState({});
  React.useEffect(() => {
    if (open) {
      setData(staff
        ? { name: staff.name, email: staff.email, phone: staff.phone, role: staff.role, perms: ["bookings", "clients"] }
        : { name: "", email: "", phone: "", role: "Therapist", perms: ["bookings", "clients"] });
      setErrors({});
    }
  }, [open, staff]);
  const set = (k, v) => { setData(d => ({ ...d, [k]: v })); setErrors(e => ({ ...e, [k]: undefined })); };
  const togglePerm = (id) => set("perms", data.perms.includes(id) ? data.perms.filter(p => p !== id) : [...data.perms, id]);

  const submit = () => {
    const e = {};
    if (!data.name.trim()) e.name = "Name is required.";
    if (!data.email.trim()) e.email = "Email is required.";
    else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(data.email)) e.email = "Enter a valid email address.";
    setErrors(e);
    if (Object.keys(e).length === 0) onSave(data);
  };

  return (
    <window.M.Modal open={open} onClose={onClose} size="lg"
      icon={<I.staff />} title={staff ? `Edit ${staff.name}` : "Add a team member"}
      subtitle={staff ? "Update profile, role, or permissions." : "They'll get an email invite to join your studio on Pamp."}
      footer={<>
        <S.Btn variant="ghost" onClick={onClose}>Cancel</S.Btn>
        <S.Btn variant="primary" iconRight={<I.arrowR size={14} />} onClick={submit}>{staff ? "Save changes" : "Send invite"}</S.Btn>
      </>}
    >
      <window.M.FormGrid>
        <window.M.Field full label="Full name" error={errors.name}>
          <window.M.TextField value={data.name} onChange={(v) => set("name", v)} placeholder="Jordan Lee" />
        </window.M.Field>
        <window.M.Field label="Email" error={errors.email}>
          <window.M.TextField icon={<I.mail size={14} />} value={data.email} onChange={(v) => set("email", v)} placeholder="jordan@studio.com" />
        </window.M.Field>
        <window.M.Field label="Phone">
          <window.M.TextField icon={<I.phone size={14} />} value={data.phone} onChange={(v) => set("phone", v)} placeholder="+1 555 0142" />
        </window.M.Field>
        <window.M.Field full label="Role">
          <window.M.RadioCards value={data.role} onChange={(v) => set("role", v)}
            options={STAFF_ROLES.map(r => ({ value: r.value, label: r.label, desc: r.desc }))} />
        </window.M.Field>
        <window.M.Field full label="Permissions" hint="Pick what this person can access.">
          <div className="grid-2" style={{ gap: 10 }}>
            {STAFF_PERMISSIONS.map(p => {
              const on = data.perms.includes(p.id);
              return (
                <button key={p.id} type="button" onClick={() => togglePerm(p.id)}
                  className="row" style={{
                    padding: "12px 14px", border: `1px solid ${on ? "var(--accent)" : "var(--border-strong)"}`,
                    borderRadius: "var(--r-md)", background: on ? "var(--accent-soft)" : "var(--surface)",
                    gap: 10, textAlign: "left",
                  }}>
                  <span className="cb-box" data-checked={on}>{on && <I.check size={11} />}</span>
                  <span style={{ fontSize: 13, fontWeight: 500 }}>{p.label}</span>
                </button>
              );
            })}
          </div>
        </window.M.Field>
      </window.M.FormGrid>
    </window.M.Modal>
  );
}

/* ====================================================================
   VENDOR — WALLET
   ==================================================================== */
function VendorWallet({ vendorId, vendor }) {
  const toast = window.useToast();
  const [earnings, setEarnings] = React.useState(null);
  const [payouts, setPayouts] = React.useState(null);
  const [requestOpen, setRequestOpen] = React.useState(false);
  const [reloadKey, setReloadKey] = React.useState(0);

  React.useEffect(() => {
    if (!vendorId) return;
    let alive = true;
    setEarnings(null); setPayouts(null);
    Promise.all([
      SB.getVendorEarnings(vendorId),
      SB.client.from("payout_requests").select("*").eq("vendor_id", vendorId).order("requested_at", { ascending: false }),
    ]).then(([e, p]) => {
      if (!alive) return;
      setEarnings(e || []);
      setPayouts(p.data || []);
    });
    return () => { alive = false; };
  }, [vendorId, reloadKey]);

  if (earnings === null || payouts === null) return <div className="page-enter"><window.LoadingState /></div>;

  const totalEarnings = earnings.reduce((s, b) => s + Number(b.total_price || 0), 0);
  const totalPaidOut  = payouts.filter(p => p.status === "approved" || p.status === "paid").reduce((s, p) => s + Number(p.amount || 0), 0);
  const pendingOut    = payouts.filter(p => p.status === "pending").reduce((s, p) => s + Number(p.amount || 0), 0);
  const balance       = Number(vendor?.balance || 0);
  const available     = Math.max(0, balance - pendingOut);

  return (
    <div className="page-enter">
      <S.PageHead
        eyebrow="Earnings & payouts"
        title="Wallet"
        sub="Track what you've earned, what's been paid out, and request new payouts."
        right={<S.Btn variant="primary" size="sm" icon={<I.transfer size={14} />} onClick={() => setRequestOpen(true)} disabled={available <= 0}>Request payout</S.Btn>}
      />

      <div className="grid-4" style={{ marginBottom: 24 }}>
        <S.Metric hero label="Available balance" value={window.fmtMoney(balance)} delta={pendingOut > 0 ? `${window.fmtMoney(pendingOut)} pending` : "Ready to withdraw"} deltaTone={pendingOut > 0 ? "warn" : "pos"} />
        <S.Metric label="Lifetime earnings" value={window.fmtMoney(totalEarnings)} delta={`${earnings.length} completed`} />
        <S.Metric label="Total paid out" value={window.fmtMoney(totalPaidOut)} />
        <S.Metric label="Pending payouts" value={window.fmtMoney(pendingOut)} deltaTone={pendingOut > 0 ? "warn" : ""} />
      </div>

      <div className="card card-flush" style={{ marginBottom: 24 }}>
        <div className="row between" style={{ padding: "22px 22px 14px" }}>
          <div className="h3">Payout history</div>
          <span className="muted tiny">{payouts.length} request{payouts.length === 1 ? "" : "s"}</span>
        </div>
        {payouts.length === 0 ? (
          <window.EmptyState icon={<I.transfer size={24} />} title="No payouts yet" sub="Request a payout once you have available balance." />
        ) : (
          <table className="tbl">
            <thead>
              <tr>
                <th>Requested</th>
                <th>Method</th>
                <th className="col-num">Amount</th>
                <th>Status</th>
                <th>Processed</th>
              </tr>
            </thead>
            <tbody>
              {payouts.map(p => (
                <tr key={p.id}>
                  <td className="mono muted">{window.fmtDate(p.requested_at)}</td>
                  <td><div className="row-tight tiny"><I.card size={12} />{p.method || "Bank"}</div></td>
                  <td className="col-num mono" style={{ fontWeight: 500 }}>{window.fmtMoney(p.amount)}</td>
                  <td><S.Chip tone={window.statusTone(p.status)}>{window.statusLabel(p.status)}</S.Chip></td>
                  <td className="mono muted">{p.processed_at ? window.fmtDate(p.processed_at) : "—"}</td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </div>

      <PayoutRequestModal
        open={requestOpen}
        onClose={() => setRequestOpen(false)}
        vendorId={vendorId}
        available={available}
        onSubmitted={() => { setRequestOpen(false); setReloadKey(k => k + 1); toast.success("Payout requested"); }}
      />
    </div>
  );
}

function PayoutRequestModal({ open, onClose, vendorId, available, onSubmitted }) {
  const toast = window.useToast();
  const [amount, setAmount] = React.useState("");
  const [method, setMethod] = React.useState("bank");
  const [notes, setNotes] = React.useState("");
  const [busy, setBusy] = React.useState(false);

  React.useEffect(() => { if (open) { setAmount(""); setMethod("bank"); setNotes(""); } }, [open]);

  const submit = async () => {
    const amt = parseFloat(amount);
    if (!amt || amt <= 0) { toast.error("Enter a valid amount"); return; }
    if (amt > available) { toast.error(`Amount can't exceed available balance (${window.fmtMoney(available)})`); return; }
    setBusy(true);
    try {
      const { error } = await SB.client.from("payout_requests").insert({
        vendor_id: vendorId,
        amount: amt,
        method,
        status: "pending",
        notes: notes.trim() || null,
      });
      if (error) { toast.error(error.message); return; }
      onSubmitted?.();
    } finally {
      setBusy(false);
    }
  };

  return (
    <window.M.Modal open={open} onClose={onClose}
      icon={<I.transfer />}
      title="Request payout"
      subtitle={`Available balance: ${window.fmtMoney(available)}`}
      footer={<>
        <S.Btn variant="ghost" onClick={onClose} disabled={busy}>Cancel</S.Btn>
        <S.Btn variant="primary" onClick={submit} disabled={busy || available <= 0}>{busy ? "Submitting..." : "Submit request"}</S.Btn>
      </>}>
      <window.M.FormGrid>
        <window.M.Field full label="Amount">
          <input className="text-input" type="number" min="0" max={available} step="0.01" value={amount} onChange={(e) => setAmount(e.target.value)} placeholder="0.00" />
        </window.M.Field>
        <window.M.Field full label="Method">
          <window.M.Segmented value={method} onChange={setMethod} options={[
            { value: "bank",   label: "Bank transfer" },
            { value: "mobile", label: "Mobile money" },
          ]} />
        </window.M.Field>
        <window.M.Field full label="Notes (optional)">
          <window.M.Textarea value={notes} onChange={setNotes} placeholder="Account info, reference, anything we need to know..." />
        </window.M.Field>
      </window.M.FormGrid>
    </window.M.Modal>
  );
}

/* ====================================================================
   VENDOR — PLAN
   ==================================================================== */
function VendorPlan() {
  return (
    <div className="page-enter">
      <window.DemoBanner feature="vendor plan" />
      <S.PageHead eyebrow="Current plan · Studio" title="My plan" sub="Renews Mar 14 · $49/mo billed monthly." />
      <div className="grid-12">
        <div className="card" style={{ gridColumn: "span 5", background: "var(--accent)", color: "oklch(20% 0.10 145)", borderColor: "transparent" }}>
          <div className="row between">
            <span className="chip" style={{ background: "white", color: "oklch(20% 0.10 145)", borderColor: "transparent" }}>Studio plan</span>
            <span className="chip" style={{ background: "oklch(0% 0 0 / 0.14)", color: "oklch(20% 0.10 145)", borderColor: "transparent" }}>Active</span>
          </div>
          <div className="display" style={{ fontSize: 56, color: "oklch(15% 0.10 145)", marginTop: 18, letterSpacing: "-0.035em" }}>$49<span style={{ fontSize: 18, opacity: 0.5 }}>/mo</span></div>
          <div style={{ color: "oklch(28% 0.10 145)", fontSize: 13, marginTop: 6 }}>Best for growing studios with 2–5 staff.</div>
          <div className="divider" style={{ margin: "24px 0", background: "oklch(0% 0 0 / 0.16)" }} />
          <div className="col" style={{ gap: 10 }}>
            {[
              "Up to 5 staff seats",
              "Unlimited bookings",
              "Reduced platform fee · 3.5%",
              "SMS reminders included",
              "Custom branded mini-site",
            ].map(f => <div key={f} className="row-tight" style={{ fontSize: 13, color: "oklch(20% 0.10 145)" }}><I.check size={14} />{f}</div>)}
          </div>
          <div className="row" style={{ marginTop: 28, gap: 8 }}>
            <S.Btn variant="ink" iconRight={<I.arrowR size={14} />}>Upgrade to Atelier</S.Btn>
            <S.Btn variant="ghost" style={{ color: "oklch(20% 0.10 145)", background: "oklch(0% 0 0 / 0.10)" }}>Manage billing</S.Btn>
          </div>
        </div>
        <div className="card" style={{ gridColumn: "span 7" }}>
          <div className="h3" style={{ marginBottom: 16 }}>This billing cycle</div>
          <div className="grid-3">
            <Metric2 label="Bookings used" value="84 / ∞" />
            <Metric2 label="SMS sent" value="142 / 500" />
            <Metric2 label="Staff seats" value="4 / 5" />
          </div>
          <div className="divider" style={{ margin: "24px 0" }} />
          <div className="h3" style={{ marginBottom: 14 }}>Recent invoices</div>
          <div className="col" style={{ gap: 8 }}>
            {[
              { d: "Feb 14", a: 49, s: "Paid" },
              { d: "Jan 14", a: 49, s: "Paid" },
              { d: "Dec 14", a: 49, s: "Paid" },
            ].map((iv, i) => (
              <div key={i} className="row between" style={{ padding: 12, border: "1px solid var(--border)", borderRadius: 10 }}>
                <div className="row-tight"><I.card size={16} /> <span>Studio plan · {iv.d}, 2026</span></div>
                <div className="row-tight"><span className="mono">${iv.a}.00</span><S.Chip tone="pos">{iv.s}</S.Chip><S.IconBtn><I.download size={14} /></S.IconBtn></div>
              </div>
            ))}
          </div>
        </div>
      </div>

      {/* explore other plans */}
      <div style={{ marginTop: 36 }}>
        <div className="row between" style={{ marginBottom: 18 }}>
          <div>
            <div className="eyebrow" style={{ marginBottom: 6 }}>Explore other plans</div>
            <div className="h2" style={{ fontSize: 24 }}>Move up when you’re ready</div>
          </div>
          <div className="row-tight" style={{ background: "var(--surface-3)", padding: 3, borderRadius: 999 }}>
            <button className="btn btn-sm" style={{ background: "var(--surface)", color: "var(--ink)", boxShadow: "var(--shadow-sm)" }}>Monthly</button>
            <button className="btn btn-ghost btn-sm">Annual <span className="chip chip-pos" style={{ marginLeft: 6, height: 18, padding: "0 6px", fontSize: 10 }}>−20%</span></button>
          </div>
        </div>

        <div className="grid-4">
          {[
            {
              name: "Starter", price: 0, suffix: "Free",
              tag: "For trying Pamp", color: "var(--ink-3)",
              features: ["1 location", "30 bookings / month", "Standard platform fee · 5%", "Email reminders only"],
              cta: "Downgrade", action: "outline",
            },
            {
              name: "Studio", price: 49, current: true,
              tag: "Most chosen", color: "var(--accent)",
              features: ["Up to 5 staff seats", "Unlimited bookings", "Reduced fee · 3.5%", "SMS reminders included", "Custom branded site"],
              cta: "Current plan", action: "disabled",
            },
            {
              name: "Atelier", price: 149, featured: true,
              tag: "For established studios", color: "var(--ink)",
              features: ["Unlimited staff seats", "Lowest platform fee · 2.4%", "API access", "Multi-location", "Priority support"],
              cta: "Upgrade to Atelier", action: "primary",
            },
            {
              name: "Enterprise", price: null,
              tag: "For groups & chains", color: "var(--info)",
              features: ["Custom contract", "SSO + SAML", "Audit logs & exports", "Dedicated CSM", "Bespoke SLA"],
              cta: "Talk to sales", action: "outline",
            },
          ].map((p) => (
            <div key={p.name} className="card" style={{
              position: "relative",
              borderColor: p.featured ? "var(--ink)" : p.current ? "var(--accent)" : undefined,
              borderWidth: p.featured || p.current ? 1.5 : 1,
              padding: 24,
              display: "flex", flexDirection: "column",
            }}>
              {p.current && <div style={{ position: "absolute", top: -10, left: 22 }}><S.Chip tone="accent">Current</S.Chip></div>}
              {p.featured && <div style={{ position: "absolute", top: -10, left: 22 }}><span className="chip" style={{ background: "var(--ink)", color: "var(--surface)", borderColor: "transparent" }}>Recommended</span></div>}

              <div className="eyebrow" style={{ color: p.color, marginBottom: 8 }}>{p.name}</div>
              <div className="muted tiny" style={{ marginBottom: 14 }}>{p.tag}</div>
              <div className="display" style={{ fontSize: 38, letterSpacing: "-0.03em", lineHeight: 1 }}>
                {p.price === null ? "Custom" : p.price === 0 ? "Free" : (
                  <>$<span>{p.price}</span><span className="muted" style={{ fontSize: 14, fontWeight: 400 }}> /mo</span></>
                )}
              </div>

              <div className="divider" style={{ margin: "20px 0" }} />
              <div className="col" style={{ gap: 10, flex: 1 }}>
                {p.features.map((f) => (
                  <div key={f} className="row-tight" style={{ fontSize: 13, alignItems: "flex-start" }}>
                    <span style={{ color: p.color, display: "inline-flex", marginTop: 2 }}><I.check size={14} /></span>{f}
                  </div>
                ))}
              </div>

              <div style={{ marginTop: 22 }}>
                <S.Btn
                  variant={p.action === "primary" ? "primary" : p.action === "disabled" ? "outline" : "outline"}
                  size="sm"
                  disabled={p.action === "disabled"}
                  style={{ width: "100%" }}
                  iconRight={p.action === "primary" ? <I.arrowR size={14} /> : null}
                >{p.cta}</S.Btn>
              </div>
            </div>
          ))}
        </div>

        <div className="muted tiny" style={{ textAlign: "center", marginTop: 18 }}>
          All plans include 24/7 support · cancel anytime · prices in USD before tax
        </div>
      </div>
    </div>
  );
}

function VendorReports({ vendorId }) {
  const [bookings, setBookings] = React.useState(null);

  React.useEffect(() => {
    if (!vendorId) return;
    let alive = true;
    SB.getVendorBookings(vendorId).then(b => { if (alive) setBookings(b || []); });
    return () => { alive = false; };
  }, [vendorId]);

  if (bookings === null) return <div className="page-enter"><window.LoadingState /></div>;

  const completed = bookings.filter(b => b.status === "completed");
  const cancelled = bookings.filter(b => b.status === "cancelled" || b.status === "no_show");
  const totalRevenue = completed.reduce((s, b) => s + Number(b.total_price || 0), 0);
  const avgTicket = completed.length ? totalRevenue / completed.length : 0;

  // Revenue by month - last 12 months
  const now = new Date();
  const monthBuckets = Array(12).fill(0);
  const monthLabels = [];
  for (let i = 11; i >= 0; i--) {
    const d = new Date(now.getFullYear(), now.getMonth() - i, 1);
    monthLabels.push(d.toLocaleDateString("en-US", { month: "short" }));
  }
  completed.forEach(b => {
    const d = new Date(b.booking_date);
    const monthsAgo = (now.getFullYear() - d.getFullYear()) * 12 + (now.getMonth() - d.getMonth());
    if (monthsAgo >= 0 && monthsAgo < 12) monthBuckets[11 - monthsAgo] += Number(b.total_price || 0);
  });

  // Top services by revenue
  const serviceMap = {};
  completed.forEach(b => {
    const name = b.services?.name;
    if (!name) return;
    serviceMap[name] = serviceMap[name] || { name, count: 0, revenue: 0 };
    serviceMap[name].count += 1;
    serviceMap[name].revenue += Number(b.total_price || 0);
  });
  const topServices = Object.values(serviceMap).sort((a, b) => b.revenue - a.revenue).slice(0, 5);

  // Top clients by revenue
  const clientMap = {};
  completed.forEach(b => {
    const name = b.profiles?.full_name || b.profiles?.email;
    if (!name) return;
    clientMap[name] = clientMap[name] || { name, count: 0, revenue: 0 };
    clientMap[name].count += 1;
    clientMap[name].revenue += Number(b.total_price || 0);
  });
  const topClients = Object.values(clientMap).sort((a, b) => b.revenue - a.revenue).slice(0, 5);

  // Status breakdown
  const completionRate = bookings.length === 0 ? 0 : (completed.length / bookings.length * 100);

  return (
    <div className="page-enter">
      <S.PageHead
        eyebrow="Your business at a glance"
        title="Reports"
        sub="Revenue, bookings, and performance over time."
      />

      <div className="grid-4" style={{ marginBottom: 20 }}>
        <S.Metric hero label="Lifetime revenue" value={window.fmtMoney(totalRevenue)} delta={`${completed.length} completed`} />
        <S.Metric label="Avg. ticket" value={window.fmtMoney(avgTicket)} />
        <S.Metric label="Completion rate" value={`${completionRate.toFixed(1)}%`} deltaTone={completionRate > 80 ? "pos" : completionRate > 50 ? "warn" : "neg"} />
        <S.Metric label="Cancellations" value={cancelled.length.toString()} deltaTone={cancelled.length === 0 ? "pos" : "warn"} />
      </div>

      <div className="grid-12" style={{ marginBottom: 20 }}>
        <div className="card" style={{ gridColumn: "span 8" }}>
          <div className="row between" style={{ marginBottom: 18 }}>
            <div>
              <div className="eyebrow">Revenue</div>
              <div className="h3" style={{ marginTop: 4 }}>By month \u00b7 last 12 months</div>
            </div>
          </div>
          {totalRevenue === 0 ? (
            <div className="muted" style={{ padding: "60px 0", textAlign: "center" }}>No completed bookings yet</div>
          ) : (
            <S.BarChart height={240} labels={monthLabels} data={monthBuckets} color="var(--accent)" />
          )}
        </div>

        <div className="card" style={{ gridColumn: "span 4" }}>
          <div className="eyebrow" style={{ marginBottom: 4 }}>Top earners</div>
          <div className="h3" style={{ marginBottom: 18 }}>Services by revenue</div>
          {topServices.length === 0 ? (
            <div className="muted tiny" style={{ padding: "20px 0" }}>No data yet</div>
          ) : (
            <div className="col" style={{ gap: 14 }}>
              {topServices.map((s, i) => {
                const max = topServices[0].revenue;
                const pct = max > 0 ? (s.revenue / max) * 100 : 0;
                return (
                  <div key={s.name}>
                    <div className="row between" style={{ marginBottom: 4 }}>
                      <span style={{ fontSize: 13, fontWeight: 500 }}>{s.name}</span>
                      <span className="mono tiny muted">{window.fmtMoney(s.revenue)}</span>
                    </div>
                    <div className="bar"><span style={{ width: `${pct}%`, background: i === 0 ? "var(--accent)" : "var(--accent-soft)" }} /></div>
                  </div>
                );
              })}
            </div>
          )}
        </div>
      </div>

      <div className="card">
        <div className="row between" style={{ marginBottom: 18 }}>
          <div>
            <div className="eyebrow">Loyalty</div>
            <div className="h3" style={{ marginTop: 4 }}>Top clients by lifetime value</div>
          </div>
        </div>
        {topClients.length === 0 ? (
          <div className="muted" style={{ padding: "20px 0", textAlign: "center" }}>No completed bookings yet</div>
        ) : (
          <div className="col" style={{ gap: 14 }}>
            {topClients.map((c, i) => {
              const max = topClients[0].revenue;
              const pct = max > 0 ? (c.revenue / max) * 100 : 0;
              return (
                <div key={c.name}>
                  <div className="row between" style={{ marginBottom: 4 }}>
                    <span style={{ fontSize: 13, fontWeight: 500 }}>{c.name}</span>
                    <span className="mono tiny muted">{c.count} {c.count === 1 ? "booking" : "bookings"} \u00b7 {window.fmtMoney(c.revenue)}</span>
                  </div>
                  <div className="bar"><span style={{ width: `${pct}%`, background: i === 0 ? "var(--accent)" : "var(--accent-soft)" }} /></div>
                </div>
              );
            })}
          </div>
        )}
      </div>
    </div>
  );
}

function VendorSupport() {
  return <window.SupportPage kind="vendor" />;
}

window.VendorApp = VendorApp;

/* ====================================================================
   VENDOR — GALLERY
   ==================================================================== */
function VendorGallery() {
  const [tab, setTab] = React.useState("all");
  const cats = [
    { k: "all", l: "All", n: 48 },
    { k: "color", l: "Color", n: 22 },
    { k: "cuts", l: "Cuts", n: 14 },
    { k: "interior", l: "Studio", n: 8 },
    { k: "team", l: "Team", n: 4 },
  ];
  return (
    <div className="page-enter">
      <window.DemoBanner feature="gallery" />
      <S.PageHead
        eyebrow="48 images · 4 collections"
        title="Gallery"
        sub="Show off your best work. Photos appear on your booking page and in Discover."
        right={<>
          <S.Btn variant="outline" size="sm" icon={<I.list size={14} />}>Collections</S.Btn>
          <S.Btn variant="primary" size="sm" icon={<I.plus size={14} />}>Upload photos</S.Btn>
        </>}
      />

      <div className="card" style={{ padding: 22, marginBottom: 20, borderStyle: "dashed", borderColor: "var(--border-strong)", borderWidth: 2 }}>
        <div className="row" style={{ gap: 16, alignItems: "center" }}>
          <div style={{
            width: 56, height: 56, borderRadius: 14, background: "var(--accent-soft)", color: "var(--accent-ink)",
            display: "flex", alignItems: "center", justifyContent: "center",
          }}><I.export size={24} /></div>
          <div style={{ flex: 1 }}>
            <div style={{ fontWeight: 500, fontSize: 15 }}>Drag &amp; drop photos here</div>
            <div className="muted tiny" style={{ marginTop: 4 }}>JPG or PNG · up to 12 MB each · we’ll auto-crop and optimize</div>
          </div>
          <S.Btn variant="outline" size="sm">Browse files</S.Btn>
        </div>
      </div>

      <div className="row" style={{ gap: 8, marginBottom: 18, overflowX: "auto" }}>
        {cats.map((c) => (
          <button key={c.k} onClick={() => setTab(c.k)}
            className={`btn btn-sm ${tab === c.k ? "btn-primary" : "btn-outline"}`}>
            {c.l} <span className="mono tiny" style={{ marginLeft: 6, opacity: 0.7 }}>{c.n}</span>
          </button>
        ))}
        <div className="spacer" />
        <S.Btn variant="ghost" size="sm" iconRight={<I.chevD size={12} />}>Newest first</S.Btn>
      </div>

      {/* mosaic grid */}
      <div style={{
        display: "grid", gridTemplateColumns: "repeat(4, 1fr)",
        gridAutoRows: 140, gap: 12,
      }}>
        {GALLERY.map((g, i) => (
          <div key={i} style={{
            gridColumn: g.col || "span 1", gridRow: g.row || "span 1",
            position: "relative", borderRadius: 14, overflow: "hidden",
          }} className="placeholder-img">
            <div style={{
              position: "absolute", inset: 0, padding: 12,
              display: "flex", flexDirection: "column", justifyContent: "flex-end",
              background: "linear-gradient(180deg, transparent 50%, oklch(0% 0 0 / 0.55) 100%)",
              color: "white",
            }}>
              <div style={{ display: "flex", justifyContent: "space-between", marginTop: "auto" }}>
                <S.Chip tone="accent" style={{ background: "oklch(100% 0 0 / 0.92)" }}>{g.tag}</S.Chip>
                <span className="mono tiny" style={{ background: "oklch(0% 0 0 / 0.50)", color: "white", padding: "3px 7px", borderRadius: 999 }}>
                  <I.heart size={10} /> {g.likes}
                </span>
              </div>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

const GALLERY = [
  { tag: "Color", likes: 142, col: "span 2", row: "span 2" },
  { tag: "Cut",   likes: 88 },
  { tag: "Color", likes: 64 },
  { tag: "Color", likes: 218, col: "span 1", row: "span 2" },
  { tag: "Studio", likes: 32 },
  { tag: "Team",  likes: 124 },
  { tag: "Color", likes: 76 },
  { tag: "Cut",   likes: 48, col: "span 2" },
  { tag: "Color", likes: 92 },
  { tag: "Studio", likes: 28, col: "span 1", row: "span 1" },
  { tag: "Color", likes: 156 },
  { tag: "Cut",   likes: 72 },
];

/* ====================================================================
   VENDOR — SETTINGS
   ==================================================================== */
function VendorSettings({ vendor, onSaved }) {
  const toast = window.useToast();
  const [data, setData] = React.useState(null);
  const [original, setOriginal] = React.useState("");
  const [busy, setBusy] = React.useState(false);

  React.useEffect(() => {
    if (!vendor) return;
    const next = {
      business_name: vendor.business_name || "",
      owner_name:    vendor.owner_name || "",
      tagline:       vendor.tagline || "",
      category:      vendor.category || "",
      city:          vendor.city || "",
      phone:         vendor.phone || vendor.contact_phone || "",
      email:         vendor.contact_email || vendor.owner_email || "",
      logo_url:      vendor.logo_url || "",
      cover_image_url: vendor.cover_image_url || "",
      is_active:     vendor.is_active !== false,
    };
    setData(next);
    setOriginal(JSON.stringify(next));
  }, [vendor?.id]);

  if (data === null) return <div className="page-enter"><window.LoadingState /></div>;

  const dirty = JSON.stringify(data) !== original;
  const set = (k, v) => setData(d => ({ ...d, [k]: v }));

  const save = async () => {
    setBusy(true);
    try {
      const payload = {
        business_name: data.business_name.trim() || null,
        owner_name:    data.owner_name.trim() || null,
        tagline:       data.tagline.trim() || null,
        category:      data.category.trim() || null,
        city:          data.city.trim() || null,
        logo_url:      data.logo_url.trim() || null,
        cover_image_url: data.cover_image_url.trim() || null,
        is_active:     data.is_active,
      };
      const { error } = await SB.client.from("vendor_profiles").update(payload).eq("id", vendor.id);
      if (error) { toast.error(error.message || "Save failed"); return; }
      toast.success("Studio updated");
      setOriginal(JSON.stringify(data));
      onSaved?.();
    } finally {
      setBusy(false);
    }
  };

  const CATEGORIES = ["Hair", "Nails", "Spa", "Massage", "Barber", "Facials", "Brows & lashes", "Wellness", "Fitness", "Other"];

  return (
    <div className="page-enter">
      <S.PageHead
        eyebrow="Studio"
        title="Settings"
        sub="Your business profile, what clients see, and account state."
        right={<>
          <S.Btn variant="ghost" size="sm" onClick={() => setData(JSON.parse(original))} disabled={!dirty || busy}>Discard</S.Btn>
          <S.Btn variant="primary" size="sm" icon={<I.check size={14} />} onClick={save} disabled={!dirty || busy}>{busy ? "Saving..." : "Save changes"}</S.Btn>
        </>}
      />

      <div className="card" style={{ padding: 22, marginBottom: 20 }}>
        <div className="h3" style={{ marginBottom: 4 }}>Business profile</div>
        <div className="muted tiny" style={{ marginBottom: 18 }}>What clients see on your booking page.</div>
        <div className="grid-2" style={{ gap: 16 }}>
          <div>
            <label className="field-label">Business name</label>
            <S.Input value={data.business_name} onChange={(e) => set("business_name", e.target.value)} placeholder="e.g. Maison Color and Co." />
          </div>
          <div>
            <label className="field-label">Owner / contact name</label>
            <S.Input value={data.owner_name} onChange={(e) => set("owner_name", e.target.value)} placeholder="Your name" />
          </div>
          <div style={{ gridColumn: "span 2" }}>
            <label className="field-label">Tagline</label>
            <S.Input value={data.tagline} onChange={(e) => set("tagline", e.target.value)} placeholder="Short, punchy. One line." />
          </div>
          <div>
            <label className="field-label">Category</label>
            <select className="text-input" value={data.category} onChange={(e) => set("category", e.target.value)}>
              <option value="">Pick one...</option>
              {CATEGORIES.map(c => <option key={c} value={c}>{c}</option>)}
            </select>
          </div>
          <div>
            <label className="field-label">City</label>
            <S.Input icon={<I.location size={14} />} value={data.city} onChange={(e) => set("city", e.target.value)} placeholder="Accra, Ghana" />
          </div>
        </div>
      </div>

      <div className="card" style={{ padding: 22, marginBottom: 20 }}>
        <div className="h3" style={{ marginBottom: 4 }}>Imagery</div>
        <div className="muted tiny" style={{ marginBottom: 18 }}>Logo and cover image shown on Discover and your booking page.</div>
        <div className="grid-2" style={{ gap: 16 }}>
          <div>
            <label className="field-label">Logo URL</label>
            <S.Input value={data.logo_url} onChange={(e) => set("logo_url", e.target.value)} placeholder="https://..." />
            {data.logo_url && (
              <div style={{ marginTop: 10 }}>
                <img src={data.logo_url} alt="" style={{ width: 64, height: 64, borderRadius: 14, objectFit: "cover" }} onError={(e) => { e.target.style.display = "none"; }} />
              </div>
            )}
          </div>
          <div>
            <label className="field-label">Cover image URL</label>
            <S.Input value={data.cover_image_url} onChange={(e) => set("cover_image_url", e.target.value)} placeholder="https://..." />
            {data.cover_image_url && (
              <div style={{ marginTop: 10 }}>
                <img src={data.cover_image_url} alt="" style={{ width: "100%", maxWidth: 240, height: 96, borderRadius: 10, objectFit: "cover" }} onError={(e) => { e.target.style.display = "none"; }} />
              </div>
            )}
          </div>
        </div>
      </div>

      <div className="card" style={{ padding: 22 }}>
        <div className="h3" style={{ marginBottom: 4 }}>Visibility</div>
        <div className="muted tiny" style={{ marginBottom: 18 }}>Hide your studio from Discover without deleting it.</div>
        <window.M.Checkbox checked={data.is_active} onChange={(v) => set("is_active", v)} label="Active (visible to clients on Discover)" />
      </div>
    </div>
  );
}

window.VendorGallery = VendorGallery;
window.VendorSettings = VendorSettings;

/* ====================================================================
   VENDOR — SHARED: native select styled like text-input
   ==================================================================== */
function VSelect({ value, onChange, options, placeholder }) {
  return (
    <div className="text-input" style={{ display: "flex", alignItems: "center", padding: "0 12px 0 14px", position: "relative" }}>
      <select
        value={value}
        onChange={(e) => onChange?.(e.target.value)}
        style={{
          flex: 1, height: "100%", border: 0, background: "transparent",
          outline: "none", color: value ? "var(--ink)" : "var(--ink-4)",
          fontSize: 13.5, appearance: "none", cursor: "pointer", paddingRight: 8,
        }}
      >
        {placeholder && <option value="">{placeholder}</option>}
        {options.map((o) => {
          const val = typeof o === "string" ? o : o.value;
          const lab = typeof o === "string" ? o : o.label;
          return <option key={val} value={val}>{lab}</option>;
        })}
      </select>
      <I.chevD size={14} style={{ color: "var(--ink-3)", pointerEvents: "none" }} />
    </div>
  );
}


