/* Platform Admin — Overview, Makers, Pieces, Orders, Customers, Finance, Workshops, Content, Audit, Team, Settings */

// Audit-event kind → folk Icon name + brand colour (shared by Overview + Audit log).
const AUDIT_KIND_META = {
  approve: { icon: "check",  color: "var(--olive)" },
  reject:  { icon: "knot",   color: "var(--terracotta)" },
  login:   { icon: "lock",   color: "var(--muted)" },
  create:  { icon: "star",   color: "var(--gold)" },
  edit:    { icon: "feather", color: "var(--ink)" },
  payout:  { icon: "gift",   color: "var(--olive)" },
  suspend: { icon: "no-water", color: "var(--terracotta)" },
};
function _auditMeta(kind) { return AUDIT_KIND_META[kind] || { icon: "calendar", color: "var(--muted)" }; }

// Bilingual order status labels (H6) — DB enums rendered in EN + AR with a tone.
const ORDER_STATUS_LABEL = {
  pending:              { en: "Pending",            ar: "قيد الانتظار",   tone: "gold" },
  pending_confirmation: { en: "Pending confirmation", ar: "بانتظار التأكيد", tone: "gold" },
  confirmed:            { en: "Confirmed",          ar: "مؤكَّد",         tone: "gold" },
  in_preparation:       { en: "In preparation",     ar: "قيد التحضير",    tone: "gold" },
  ready_for_dispatch:   { en: "Ready to dispatch",  ar: "جاهز للشحن",     tone: "gold" },
  packed:               { en: "Packed",             ar: "مُعبَّأ",         tone: "gold" },
  shipped:              { en: "Shipped",            ar: "مشحون",          tone: "terracotta" },
  out_for_delivery:     { en: "Out for delivery",   ar: "خرج للتوصيل",    tone: "terracotta" },
  delivered:            { en: "Delivered",          ar: "تمّ التسليم",     tone: "olive" },
  returned:             { en: "Returned",           ar: "مُرتجَع",         tone: "muted" },
  cancelled:            { en: "Cancelled",          ar: "ملغى",           tone: "muted" },
  refunded:             { en: "Refunded",           ar: "مستردّ",          tone: "muted" },
};
function _orderStatusLabel(status, lang) {
  if (!status) return "—";
  const key = String(status).toLowerCase();
  const m = ORDER_STATUS_LABEL[key];
  if (!m) return String(status).replace(/_/g, " ");
  return m[lang] || m.en;
}
function _orderStatusTone(status) {
  const m = ORDER_STATUS_LABEL[String(status || "").toLowerCase()];
  return m ? m.tone : "gold";
}

// Bilingual shipment status labels (H6).
const SHIPMENT_STATUS_LABEL = {
  label_created:    { en: "Label created",   ar: "أُنشئت البطاقة",  tone: "gold" },
  picked_up:        { en: "Picked up",       ar: "تمّ الاستلام",    tone: "gold" },
  in_transit:       { en: "In transit",      ar: "في الطريق",       tone: "gold" },
  out_for_delivery: { en: "Out for delivery", ar: "خرج للتوصيل",    tone: "terracotta" },
  delivered:        { en: "Delivered",       ar: "تمّ التسليم",      tone: "olive" },
  delivery_failed:  { en: "Delivery failed", ar: "فشل التسليم",     tone: "terracotta" },
  returned:         { en: "Returned",        ar: "مُرتجَع",          tone: "muted" },
  cancelled:        { en: "Cancelled",       ar: "ملغى",            tone: "muted" },
};
function _enumLabel(map, value, lang) {
  if (!value) return "—";
  const m = map[String(value).toLowerCase()];
  if (!m) return String(value).replace(/_/g, " ");
  return m[lang] || m.en;
}

// Bilingual QC, notification, timeline-kind & workshop-booking status labels (H6/H3).
const QC_STATUS_LABEL = {
  pending:            { en: "Pending",   ar: "قيد المراجعة", tone: "gold" },
  passed:             { en: "Passed",    ar: "اجتاز",        tone: "olive" },
  failed:             { en: "Failed",    ar: "رسب",          tone: "terracotta" },
  revision_requested: { en: "Revision",  ar: "تعديل مطلوب",  tone: "gold" },
};
const NOTIF_STATUS_LABEL = {
  queued:  { en: "Queued",  ar: "في الطابور", tone: "gold" },
  sent:    { en: "Sent",    ar: "أُرسل",      tone: "olive" },
  failed:  { en: "Failed",  ar: "فشل",        tone: "terracotta" },
  skipped: { en: "Skipped", ar: "تخطّي",      tone: "muted" },
};
const TIMELINE_KIND_LABEL = {
  order_placed:        { en: "Order placed",       ar: "تمّ الطلب" },
  payment_confirmed:   { en: "Payment confirmed",  ar: "تأكّد الدفع" },
  order_confirmed:     { en: "Order confirmed",    ar: "تأكّد الطلب" },
  status_changed:      { en: "Status changed",     ar: "تغيّرت الحالة" },
  in_preparation:      { en: "In preparation",     ar: "قيد التحضير" },
  qc_opened:           { en: "QC opened",          ar: "فُتحت المراجعة" },
  qc_passed:           { en: "QC passed",          ar: "اجتازت المراجعة" },
  qc_failed:           { en: "QC failed",          ar: "رسبت المراجعة" },
  shipment_created:    { en: "Shipment created",   ar: "أُنشئ الشحن" },
  shipped:             { en: "Shipped",            ar: "تمّ الشحن" },
  delivered:           { en: "Delivered",          ar: "تمّ التسليم" },
  admin_note:          { en: "Admin note",         ar: "ملاحظة إدارية" },
  cancelled:           { en: "Cancelled",          ar: "أُلغي" },
  refunded:            { en: "Refunded",           ar: "استُرد" },
};
function _timelineKindLabel(kind, lang) {
  if (!kind) return "—";
  const m = TIMELINE_KIND_LABEL[String(kind).toLowerCase()];
  if (m) return m[lang] || m.en;
  // Fallback: humanize the raw enum (e.g. "ready_for_dispatch" → "ready for dispatch").
  return String(kind).replace(/_/g, " ");
}

const REFUND_STATUS_LABEL = {
  none:       { en: "None",       ar: "لا يوجد" },
  pending:    { en: "Pending",    ar: "قيد المعالجة" },
  processing: { en: "Processing", ar: "جارٍ" },
  completed:  { en: "Completed",  ar: "مكتمل" },
  refunded:   { en: "Refunded",   ar: "مستردّ" },
  failed:     { en: "Failed",     ar: "فشل" },
  not_eligible: { en: "Not eligible", ar: "غير مؤهَّل" },
};

const WORKSHOP_STATUS_LABEL = {
  draft:        { en: "Draft",       ar: "مسوّدة" },
  published:    { en: "Live",        ar: "منشورة" },
  fully_booked: { en: "Full",        ar: "مكتملة" },
  in_progress:  { en: "In progress", ar: "جارية" },
  completed:    { en: "Completed",   ar: "اكتملت" },
  cancelled:    { en: "Cancelled",   ar: "ملغاة" },
  archived:     { en: "Archived",    ar: "مؤرشفة" },
};
function _workshopStatusLabel(statusKey, fallback, lang) {
  const m = WORKSHOP_STATUS_LABEL[String(statusKey || "").toLowerCase()];
  return m ? (m[lang] || m.en) : (fallback || statusKey);
}

const BOOKING_STATUS_LABEL = {
  pending:         { en: "Pending",   ar: "قيد الانتظار", tone: "gold" },
  pending_payment: { en: "Awaiting payment", ar: "بانتظار الدفع", tone: "gold" },
  confirmed:       { en: "Confirmed", ar: "مؤكَّد",        tone: "olive" },
  attended:        { en: "Attended",  ar: "حضر",          tone: "olive" },
  waitlisted:      { en: "Waitlisted", ar: "قائمة انتظار", tone: "gold" },
  no_show:         { en: "No-show",   ar: "لم يحضر",      tone: "terracotta" },
  cancelled:       { en: "Cancelled", ar: "ملغى",         tone: "muted" },
};

// Bilingual piece-status labels (H5) — covers every status the data layer emits.
const PIECE_STATUS_LABEL = {
  Live:     { en: "Live",     ar: "منشور" },
  Review:   { en: "Review",   ar: "مراجعة" },
  Draft:    { en: "Draft",    ar: "مسوّدة" },
  Archived: { en: "Archived", ar: "مؤرشف" },
};
function _pieceStatusLabel(status, lang) {
  const m = PIECE_STATUS_LABEL[status];
  return m ? (m[lang] || m.en) : status;
}

// ————————— OVERVIEW —————————
function OverviewPage({ lang, openApproval, gotoSection, firstName }) {
  const stats = window.ADMIN_STATS;
  // Time-of-day greeting (M2) — bilingual, computed from the browser clock.
  const hour = new Date().getHours();
  const partOfDay = hour < 12
    ? { en: "morning", ar: "صباح" }
    : hour < 18
      ? { en: "afternoon", ar: "ظهر" }
      : { en: "evening", ar: "مساء" };
  const weekday = (() => {
    try { return new Date().toLocaleDateString(lang === "ar" ? "ar-EG" : "en-GB", { weekday: "long" }); }
    catch { return ""; }
  })();
  // OV-1 — the GMV card value is the CURRENT month, so derive the month name
  // from the clock (localized) instead of a hardcoded "April".
  const currentMonth = (() => {
    try { return new Date().toLocaleDateString(lang === "ar" ? "ar-EG" : "en-GB", { month: "long" }); }
    catch { return ""; }
  })();
  // F8 — gmvDelta already carries its own sign (e.g. "-40%"). Strip any stray
  // leading "+" before a "-" so we never render "+-40%".
  const normSign = (d) => typeof d === "string" ? d.replace(/^\+\s*-/, "-") : d;
  const approvals = window.ADMIN_APPROVALS;
  const audit = window.ADMIN_AUDIT.slice(0, 6);
  const high = approvals.filter(a => a.priority === "high").slice(0, 3);
  const recent = approvals.slice(0, 4);

  const StatBox = ({ label, value, sub, delta, accent }) => (
    <div style={{
      padding: "22px 24px", borderRadius: 14, background: "var(--paper)",
      border: "1px solid var(--line-2)", position: "relative", overflow: "hidden",
    }}>
      <div style={{ position: "absolute", top: 0, left: 0, right: 0, height: 3, background: accent || "transparent" }} />
      <div style={{ fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--muted)" }}>{label}</div>
      <div style={{ marginTop: 8, display: "flex", alignItems: "baseline", gap: 8, flexWrap: "wrap" }}>
        <div style={{ fontFamily: "var(--ff-display)", fontSize: 36, lineHeight: 1 }}>{value}</div>
        {delta && <span style={{ fontFamily: "var(--ff-mono)", fontSize: 11, color: delta.startsWith("+") ? "var(--olive)" : "var(--terracotta)" }}>{delta}</span>}
      </div>
      {sub && <div style={{ marginTop: 6, fontSize: 12, color: "var(--muted)" }}>{sub}</div>}
    </div>
  );

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 28 }}>
      {/* Greeting band */}
      <div style={{
        padding: "26px 28px", borderRadius: 14,
        background: "linear-gradient(110deg, var(--ink) 0%, #2a261f 70%, var(--olive-2) 100%)",
        color: "var(--paper)",
        display: "grid", gridTemplateColumns: "minmax(0, 1.3fr) minmax(0, 1fr)", gap: 24, alignItems: "center",
      }} className="adm-hero">
        <div>
          <div style={{ fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--gold-soft)" }}>
            {lang === "en" ? `Platform admin · ${weekday} ${partOfDay.en}` : `إدارة المنصّة · ${partOfDay.ar} ${weekday}`}
          </div>
          <h1 style={{ fontFamily: "var(--ff-display)", fontSize: "clamp(28px, 4vw, 44px)", lineHeight: 1.05, marginTop: 10 }}>
            {lang === "en"
              ? `Good ${partOfDay.en}${firstName ? `, ${firstName}` : ""}.`
              : `${hour < 12 ? "صباح الخير" : "مساء الخير"}${firstName ? `، ${firstName}` : ""}.`}
            <div style={{ fontStyle: "italic", color: "var(--gold-soft)", marginTop: 4, fontSize: "0.7em" }}>
              {lang === "en" ? `${window.adminNum(approvals.length, lang)} requests are waiting for you.` : `${window.adminNum(approvals.length, lang)} طلبات تنتظرك.`}
            </div>
          </h1>
        </div>
        {(() => {
          const trio = [
            { l: lang === "en" ? "Pending" : "قيد المراجعة", v: approvals.length, c: "var(--gold-soft)" },
            { l: lang === "en" ? "High" : "عاجل", v: approvals.filter(a => a.priority === "high").length, c: "#e8a890" },
            { l: lang === "en" ? "Today" : "اليوم", v: stats.todayApprovals || 0, c: "#a3c995" },
          ];
          // OV-4 — when the whole trio is zero, the flat "0 / 0 / 0" reads as a
          // dead dashboard. Replace it with a calm "all clear" affordance.
          const allClear = trio.every(s => !s.v);
          if (allClear) {
            return (
              <div style={{
                display: "flex", alignItems: "center", gap: 14, padding: "18px 20px",
                border: "1px solid #a3c99533", borderRadius: 10, background: "rgba(163,201,149,0.06)",
              }}>
                <span style={{
                  width: 40, height: 40, borderRadius: "50%", flexShrink: 0,
                  background: "rgba(163,201,149,0.14)", color: "#a3c995",
                  display: "grid", placeItems: "center",
                }}><Icon name="check" size={20} /></span>
                <div>
                  <div style={{ fontFamily: "var(--ff-display)", fontStyle: "italic", fontSize: 22, color: "#a3c995", lineHeight: 1.1 }}>
                    {lang === "en" ? "All clear." : "كلّ شيء مُنجَز."}
                  </div>
                  <div style={{ marginTop: 4, fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", textTransform: "uppercase", color: "rgba(244,237,226,0.7)" }}>
                    {lang === "en" ? "No approvals waiting" : "لا طلبات معلّقة"}
                  </div>
                </div>
              </div>
            );
          }
          return (
            <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 10 }}>
              {trio.map((s, i) => (
                <div key={i} style={{ padding: "14px 16px", border: `1px solid ${s.c}33`, borderRadius: 10, background: "rgba(255,255,255,0.03)" }}>
                  <div style={{ fontFamily: "var(--ff-display)", fontSize: 32, lineHeight: 1, color: s.c }}>{window.adminNum(s.v, lang)}</div>
                  <div style={{ marginTop: 4, fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", textTransform: "uppercase", color: "rgba(244,237,226,0.7)" }}>{s.l}</div>
                </div>
              ))}
            </div>
          );
        })()}
      </div>

      {/* Quick stats */}
      <div className="adm-grid-4">
        <StatBox label={lang === "en" ? `GMV · ${currentMonth}` : `إجمالي · ${currentMonth}`} value={window.adminThousandsK(stats.gmv, lang)} sub="EGP" delta={normSign(stats.gmvDelta)} accent="var(--terracotta)" />
        <StatBox label={lang === "en" ? "Active makers" : "صنّاع نشطون"} value={window.adminNum(stats.makers, lang)} sub={`+${window.adminNum(stats.applicants, lang)} ${lang === "en" ? "applicants" : "متقدّمين"}`} delta={`${stats.makersDelta >= 0 ? "+" : ""}${window.adminNum(stats.makersDelta, lang)}`} accent="var(--olive)" />
        <StatBox label={lang === "en" ? "Pieces live" : "قطع منشورة"} value={window.adminNum(stats.piecesLive, lang)} sub={`${window.adminNum(stats.piecesDraft, lang)} ${lang === "en" ? "drafts" : "مسودّات"}`} accent="var(--gold)" />
        <StatBox label={lang === "en" ? "Customers" : "عملاء"} value={window.adminNum(stats.customers, lang)} sub={`+${window.adminNum(stats.customerDelta, lang)} ${lang === "en" ? "new this week" : "جديد هذا الأسبوع"}`} accent="var(--ink)" />
      </div>

      {/* Two-column: Approvals + Audit */}
      <div className="adm-grid-2">
        <div style={{ padding: 24, border: "1px solid var(--line-2)", borderRadius: 14, background: "var(--paper)" }}>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 16 }}>
            <h3 style={{ fontFamily: "var(--ff-display)", fontSize: 22 }}>{lang === "en" ? "Top of the queue" : "أوّل القائمة"}</h3>
            <button onClick={() => gotoSection("approvals")} style={{ background: "transparent", border: 0, fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--terracotta)", cursor: "pointer" }}>
              {lang === "en" ? "All approvals →" : "الكل →"}
            </button>
          </div>
          {recent.map((a, i) => {
            const type = AP_TYPE_LABEL[a.type] || { en: a.type, tone: "muted" };
            return (
              <button key={a.id} onClick={() => openApproval(a)} style={{
                display: "flex", gap: 14, padding: "14px 0", width: "100%", textAlign: "left",
                background: "transparent", border: 0, borderTop: i === 0 ? "none" : "1px solid var(--line-2)",
                cursor: "pointer", alignItems: "center",
              }}>
                <AdminTypeIcon type={a.type} size={36} />
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" }}>
                    <span style={{ fontFamily: "var(--ff-display)", fontSize: 16 }}>{window.approvalTitle(a, lang)}</span>
                    <PriorityDot p={a.priority} />
                  </div>
                  <div style={{ marginTop: 3, fontSize: 12, color: "var(--muted)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
                    {a.makerName} · {a.summary}
                  </div>
                </div>
                <div style={{ fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.2em", color: "var(--muted)", whiteSpace: "nowrap" }}>{window.fmtAge(a.age, lang)}</div>
              </button>
            );
          })}
        </div>

        <div style={{ padding: 24, border: "1px solid var(--line-2)", borderRadius: 14, background: "var(--paper)" }}>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 16 }}>
            <h3 style={{ fontFamily: "var(--ff-display)", fontSize: 22 }}>{lang === "en" ? "Recent audit log" : "سجلّ النشاط"}</h3>
            <button onClick={() => gotoSection("audit")} style={{ background: "transparent", border: 0, fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--terracotta)", cursor: "pointer" }}>
              {lang === "en" ? "Full log →" : "الكل →"}
            </button>
          </div>
          {audit.map((e, i) => {
            const m = _auditMeta(e.kind);
            return (
              <div key={i} style={{ display: "flex", gap: 12, padding: "10px 0", borderTop: i === 0 ? "none" : "1px solid var(--line-2)", alignItems: "center" }}>
                <div style={{ width: 28, height: 28, borderRadius: "50%", background: "var(--paper-2)", color: m.color, display: "grid", placeItems: "center", flexShrink: 0 }}><Icon name={m.icon} size={15} /></div>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 13, lineHeight: 1.4 }}>
                    <strong style={{ fontWeight: 500 }}>{e.actor}</strong> {window.auditActionLabel(e.action, lang)}
                  </div>
                </div>
                <div style={{ fontFamily: "var(--ff-mono)", fontSize: 10, color: "var(--muted)", whiteSpace: "nowrap" }}>{window.fmtAge(e.age, lang)}</div>
              </div>
            );
          })}
        </div>
      </div>

      {/* High-priority spotlight */}
      {high.length > 0 && (
        <div style={{ padding: 24, border: "1px solid #e8a89055", borderRadius: 14, background: "linear-gradient(180deg, rgba(232,168,144,0.08), transparent)" }}>
          <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 14 }}>
            <PriorityDot p="high" />
            <h3 style={{ fontFamily: "var(--ff-display)", fontSize: 22 }}>{lang === "en" ? "High-priority approvals" : "طلبات عاجلة"}</h3>
          </div>
          <div className="adm-grid-3">
            {high.map(a => {
              const type = AP_TYPE_LABEL[a.type] || { en: a.type, tone: "muted" };
              return (
                <button key={a.id} onClick={() => openApproval(a)} style={{
                  padding: 18, border: "1px solid var(--line-2)", borderRadius: 12, background: "var(--paper)",
                  textAlign: "left", cursor: "pointer", display: "flex", flexDirection: "column", gap: 10,
                }}>
                  <AdminPill tone={type.tone}>{type[lang] || type.en}</AdminPill>
                  <div style={{ fontFamily: "var(--ff-display)", fontSize: 18 }}>{window.approvalTitle(a, lang)}</div>
                  <div style={{ fontSize: 12, color: "var(--muted)" }}>{a.summary}</div>
                  <div style={{ marginTop: "auto", display: "flex", justifyContent: "space-between", fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.2em", color: "var(--muted)" }}>
                    <span>{a.makerName}</span><span>{window.fmtAge(a.age, lang)}</span>
                  </div>
                </button>
              );
            })}
          </div>
        </div>
      )}
    </div>
  );
}

// ————————— MAKER APPLICATIONS (onboarding review queue) —————————
// Lists pending maker applications from window.ADMIN_APPLICATIONS (loaded via
// the admin_list_maker_applications RPC). Approve / reject call the
// maker_provision edge function with the admin session bearer. Reject requires
// a reviewer note. Matches the admin table + drawer + pill patterns.
function ApplicationsPage({ lang }) {
  const all = window.ADMIN_APPLICATIONS || [];
  const [filter, setFilter] = React.useState("open"); // open | all
  const [drawer, setDrawer] = React.useState(null);   // selected application row

  const open = all.filter(window.isOpenApplication);
  const shown = filter === "open" ? open : all;

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 22 }}>
      {/* Intro strip — mirrors the Approvals queue header */}
      <div style={{
        padding: "20px 24px",
        background: "linear-gradient(100deg, var(--ink) 0%, #2a261f 100%)",
        color: "var(--paper)", borderRadius: 14,
        display: "flex", alignItems: "center", gap: 18, flexWrap: "wrap",
      }}>
        <div style={{ fontFamily: "var(--ff-display)", fontSize: 18, fontStyle: "italic", color: "var(--gold-soft)" }}>
          {lang === "en" ? "Every maker begins here." : "كلّ صانعٍ يبدأ من هنا."}
        </div>
        <div style={{ flex: 1, minWidth: 200, fontSize: 13, color: "rgba(244,237,226,0.75)" }}>
          {lang === "en"
            ? "Review who applied to join. Approve to provision a maker account, or request changes with a note."
            : "راجع من تقدّم للانضمام. وافق لإنشاء حساب صانع، أو اطلب تعديلًا مع ملاحظة."}
        </div>
        <div>
          <div style={{ fontFamily: "var(--ff-display)", fontSize: 34, lineHeight: 1 }}>
            {lang === "ar" ? open.length.toLocaleString("ar-EG") : open.length.toLocaleString("en-US")}
          </div>
          <div style={{ fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--gold-soft)" }}>{lang === "en" ? "pending" : "معلّق"}</div>
        </div>
      </div>

      {/* Filter */}
      <div style={{ display: "flex", gap: 6, padding: 4, background: "var(--paper-2)", borderRadius: 999, alignSelf: "flex-start" }}>
        {[
          { k: "open", l: lang === "en" ? "Pending" : "معلّق", c: open.length },
          { k: "all", l: lang === "en" ? "All" : "الكل", c: all.length },
        ].map(f => (
          <button key={f.k} onClick={() => setFilter(f.k)} style={{
            padding: "6px 14px", borderRadius: 999, border: 0,
            background: filter === f.k ? "var(--ink)" : "transparent",
            color: filter === f.k ? "var(--paper)" : "var(--ink)",
            fontSize: 12, fontFamily: "var(--ff-sans)", cursor: "pointer",
            display: "inline-flex", alignItems: "center", gap: 8,
          }}>
            {f.l}
            <span style={{ fontFamily: "var(--ff-mono)", fontSize: 9, opacity: 0.65 }}>
              {lang === "ar" ? f.c.toLocaleString("ar-EG") : f.c.toLocaleString("en-US")}
            </span>
          </button>
        ))}
      </div>

      {/* Table / list */}
      <div style={{ border: "1px solid var(--line-2)", borderRadius: 14, overflow: "hidden", background: "var(--paper)" }}>
        <div className="apl-tbl-scroll" style={{ overflowX: "auto" }}>
          <div style={{ minWidth: 760 }}>
            <div className="apl-row-h" style={{
              display: "grid",
              gridTemplateColumns: "44px 1.3fr 1fr 1fr 0.7fr 0.6fr 0.5fr",
              padding: "14px 22px", background: "var(--paper-2)",
              fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--muted)",
            }}>
              <div></div>
              <div>{lang === "en" ? "Applicant" : "المتقدّم"}</div>
              <div>{lang === "en" ? "Trade · City" : "الحرفة · المدينة"}</div>
              <div>{lang === "en" ? "Contact" : "التواصل"}</div>
              <div>{lang === "en" ? "Status" : "الحالة"}</div>
              <div>{lang === "en" ? "Applied" : "تقدّم"}</div>
              <div></div>
            </div>

            {shown.length === 0 && (
              <div style={{ padding: "60px 20px", textAlign: "center", color: "var(--muted)" }}>
                <div style={{ display: "inline-flex", color: "var(--olive)", marginBottom: 10 }}><Icon name="hand" size={32} /></div>
                <div style={{ fontFamily: "var(--ff-display)", fontSize: 28, color: "var(--ink)" }}>
                  {lang === "en" ? "No pending applications." : "لا توجد طلبات معلّقة."}
                </div>
                <div style={{ marginTop: 8, fontSize: 13 }}>
                  {lang === "en" ? "New maker applications appear here for review." : "تظهر طلبات الصنّاع الجدد هنا للمراجعة."}
                </div>
              </div>
            )}

            {shown.map((a, i) => (
              <button key={a.id} onClick={() => setDrawer(a)} style={{
                width: "100%", textAlign: "left", border: 0, background: "transparent", cursor: "pointer",
                borderTop: i === 0 ? "none" : "1px solid var(--line-2)",
                padding: "16px 22px",
                display: "grid",
                gridTemplateColumns: "44px 1.3fr 1fr 1fr 0.7fr 0.6fr 0.5fr",
                gap: 14, alignItems: "center", transition: "background .15s",
              }}
              onMouseEnter={e => e.currentTarget.style.background = "var(--paper-2)"}
              onMouseLeave={e => e.currentTarget.style.background = "transparent"}>
                <div style={{ width: 36, height: 36, borderRadius: "50%", background: "rgba(194,99,66,0.13)", color: "var(--terracotta)", display: "grid", placeItems: "center" }}>
                  <Icon name="hand" size={18} />
                </div>
                <div style={{ minWidth: 0 }}>
                  <div style={{ fontFamily: "var(--ff-display)", fontSize: 17, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{a.name || "—"}</div>
                  <div style={{ marginTop: 3, fontSize: 12, color: "var(--muted)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{a.email || "—"}</div>
                </div>
                <div style={{ fontSize: 13, minWidth: 0 }}>
                  {window.categoryLabel(a.trade, lang)}
                  <div style={{ fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.18em", color: "var(--muted)", textTransform: "uppercase" }}>{a.city || a.governorate || "—"}</div>
                </div>
                <div style={{ fontFamily: "var(--ff-mono)", fontSize: 11, color: "var(--olive)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{a.phone || "—"}</div>
                <AdminPill tone={window.applicationStatusTone(a.status)}>{window.applicationStatusLabel(a.status, lang)}</AdminPill>
                <div style={{ fontFamily: "var(--ff-mono)", fontSize: 11, color: "var(--muted)" }}>{window.fmtAge(a.created_at, lang)}</div>
                <span style={{ color: "var(--muted)", fontSize: 18, justifySelf: "end" }}>→</span>
              </button>
            ))}
          </div>
        </div>
      </div>

      <ApplicationDrawer application={drawer} onClose={() => setDrawer(null)} lang={lang} />

      <style>{`
        @media (max-width: 900px) {
          .apl-row-h { display: none !important; }
        }
      `}</style>
    </div>
  );
}

// ——— Maker-application detail drawer ———
// Shows the full application; Approve / Request changes call maker_provision.
function ApplicationDrawer({ application, onClose, lang }) {
  const [action, setAction] = React.useState(null); // null | 'approve' | 'reject'
  const [note, setNote] = React.useState("");
  const [noteErr, setNoteErr] = React.useState(false);
  const [busy, setBusy] = React.useState(false);

  React.useEffect(() => {
    if (!application) return;
    setAction(null); setNote(""); setNoteErr(false); setBusy(false);
    const prev = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    window.addEventListener("keydown", onKey);
    return () => { document.body.style.overflow = prev; window.removeEventListener("keydown", onKey); };
  }, [application, onClose]);

  if (!application) return null;
  const a = application;
  const isOpen = window.isOpenApplication(a);
  const noteRequired = action === "reject"; // reviewer_note REQUIRED for rejection
  const eyebrow = { fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--muted)" };

  const submit = async () => {
    if (noteRequired && !note.trim()) { setNoteErr(true); return; }
    setBusy(true);
    try {
      const decision = action === "approve" ? "approved" : "rejected";
      const body = { application_id: a.id, decision };
      if (note.trim()) body.reviewer_note = note.trim();
      // Call the maker_provision edge function with the admin session bearer.
      const { data, error } = await window.sb.functions.invoke("maker_provision", { body });
      if (error) {
        // supabase-js wraps non-2xx as FunctionsHttpError; try to surface the body.
        let detail = error.message || "";
        try { const ctx = await error.context?.json(); if (ctx?.error) detail = ctx.error; } catch (_) {}
        throw new Error(detail || "Action failed");
      }
      if (data && data.error) throw new Error(data.error);
      const okMsg = action === "approve"
        ? (lang === "en" ? `Maker provisioned · ${a.name}` : `تمّ إنشاء حساب الصانع · ${a.name}`)
        : (lang === "en" ? `Application rejected · ${a.name}` : `رُفض الطلب · ${a.name}`);
      window.toast(okMsg, { type: action === "approve" ? "success" : "info", lang });
      onClose();
      if (window.loadAdminData) window.loadAdminData();
    } catch (ex) {
      window.toast(ex.message || (lang === "en" ? "Action failed" : "فشل الإجراء"), { type: "error", lang });
      setBusy(false);
    }
  };

  const Field = ({ label, children }) => (
    <div>
      <div style={eyebrow}>{label}</div>
      <div style={{ marginTop: 4, fontSize: 14, color: "var(--ink)" }}>{children}</div>
    </div>
  );

  const links = Array.isArray(a.portfolio_links) ? a.portfolio_links.filter(Boolean) : [];

  return (
    <div onClick={onClose} style={{
      position: "fixed", inset: 0, background: "rgba(28,26,21,0.6)", zIndex: 80,
      display: "flex", justifyContent: "flex-end",
    }} dir={lang === "ar" ? "rtl" : "ltr"}>
      <div onClick={e => e.stopPropagation()} style={{
        width: "min(640px, 100%)", height: "100%", background: "var(--paper)",
        display: "flex", flexDirection: "column", boxShadow: "-20px 0 60px rgba(0,0,0,0.25)",
      }}>
        {/* Header */}
        <div style={{ padding: "22px 28px", borderBottom: "1px solid var(--line-2)", background: "var(--paper-2)" }}>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 12 }}>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap" }}>
                <AdminPill tone={window.applicationStatusTone(a.status)}>{window.applicationStatusLabel(a.status, lang)}</AdminPill>
                <span style={{ ...eyebrow, fontSize: 9, color: "var(--terracotta)" }}>{lang === "en" ? "Maker application" : "طلب انضمام صانع"}</span>
              </div>
              <h2 style={{ marginTop: 8, fontFamily: "var(--ff-display)", fontSize: 28, lineHeight: 1.1 }}>{a.name || "—"}</h2>
              <div style={{ marginTop: 4, fontSize: 13, color: "var(--muted)" }}>
                {window.categoryLabel(a.trade, lang)}{a.city ? ` · ${a.city}` : ""}{a.governorate ? ` · ${a.governorate}` : ""}
              </div>
            </div>
            <button onClick={onClose} aria-label={lang === "en" ? "Close" : "إغلاق"} style={{ background: "transparent", border: 0, fontSize: 24, cursor: "pointer", color: "var(--muted)", minWidth: 44, minHeight: 44, display: "inline-flex", alignItems: "center", justifyContent: "center", padding: 0 }}>×</button>
          </div>
        </div>

        {/* Body */}
        <div style={{ flex: 1, overflowY: "auto", padding: "24px 28px", display: "flex", flexDirection: "column", gap: 22 }}>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16, padding: "16px 18px", background: "var(--paper-2)", borderRadius: 12 }}>
            <Field label={lang === "en" ? "Email" : "البريد"}>
              {a.email ? <a href={`mailto:${a.email}`} style={{ color: "var(--terracotta)", textDecoration: "none" }}>{a.email}</a> : "—"}
            </Field>
            <Field label={lang === "en" ? "Phone" : "الهاتف"}>{a.phone || "—"}</Field>
            <Field label={lang === "en" ? "Trade" : "الحرفة"}>{window.categoryLabel(a.trade, lang)}</Field>
            <Field label={lang === "en" ? "Location" : "الموقع"}>{[a.city, a.governorate].filter(Boolean).join(" · ") || "—"}</Field>
          </div>

          {/* Portfolio links */}
          <div>
            <div style={{ ...eyebrow, marginBottom: 8 }}>{lang === "en" ? "Portfolio" : "أعمال سابقة"}</div>
            {links.length === 0 ? (
              <div style={{ fontSize: 13, color: "var(--muted)" }}>{lang === "en" ? "No links provided." : "لا روابط."}</div>
            ) : (
              <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
                {links.map((url, i) => (
                  <a key={i} href={url} target="_blank" rel="noopener noreferrer"
                    style={{ fontFamily: "var(--ff-mono)", fontSize: 12, color: "var(--terracotta)", textDecoration: "none", wordBreak: "break-all" }}>
                    {url} ↗
                  </a>
                ))}
              </div>
            )}
          </div>

          {/* Story */}
          {a.story && (
            <div>
              <div style={{ ...eyebrow, marginBottom: 8 }}>{lang === "en" ? "Their story" : "حكايتهم"}</div>
              <div style={{
                padding: "14px 16px", borderLeft: lang === "ar" ? 0 : "2px solid var(--gold)",
                borderRight: lang === "ar" ? "2px solid var(--gold)" : 0,
                background: "var(--paper-2)", borderRadius: lang === "ar" ? "10px 0 0 10px" : "0 10px 10px 0",
                fontFamily: "var(--ff-editorial)", fontSize: 15, fontStyle: "italic", color: "var(--ink)", lineHeight: 1.6,
              }}>
                "{a.story}"
              </div>
            </div>
          )}

          {/* Reviewer note (already decided) */}
          {a.reviewer_note && !isOpen && (
            <div>
              <div style={{ ...eyebrow, marginBottom: 8 }}>{lang === "en" ? "Reviewer note" : "ملاحظة المراجِع"}</div>
              <div style={{ padding: "12px 14px", background: "var(--paper-2)", borderRadius: 10, fontSize: 13, color: "var(--olive)" }}>{a.reviewer_note}</div>
            </div>
          )}

          {/* Meta */}
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12, padding: "14px 16px", background: "var(--paper-2)", borderRadius: 10 }}>
            <Field label={lang === "en" ? "Applied" : "تاريخ التقديم"}>{window.fmtDate(a.created_at, lang, { day: "numeric", month: "long", year: "numeric" })}</Field>
            {a.reviewed_at && <Field label={lang === "en" ? "Reviewed" : "تاريخ المراجعة"}>{window.fmtDate(a.reviewed_at, lang, { day: "numeric", month: "long", year: "numeric" })}</Field>}
          </div>

          {/* Action panel */}
          {isOpen && action && (
            <div style={{ padding: "16px 18px", border: `1.5px solid ${action === "approve" ? "var(--olive)" : "var(--terracotta)"}`, borderRadius: 12 }}>
              <div style={{ fontFamily: "var(--ff-display)", fontSize: 18, marginBottom: 10 }}>
                {action === "approve"
                  ? (lang === "en" ? "Approve & provision this maker?" : "الموافقة وإنشاء حساب الصانع؟")
                  : (lang === "en" ? "Reject this application?" : "رفض الطلب؟")}
              </div>
              <textarea
                value={note} onChange={e => { setNote(e.target.value); if (e.target.value.trim()) setNoteErr(false); }}
                rows={3} disabled={busy}
                placeholder={lang === "en"
                  ? (action === "approve" ? "Optional note (kept on the record)…" : "Tell them why (required)…")
                  : (action === "approve" ? "ملاحظة اختياريّة (تُحفظ)…" : "أخبرهم بالسبب (مطلوب)…")}
                style={{
                  width: "100%", padding: "10px 12px",
                  border: `1px solid ${noteErr ? "var(--terracotta)" : "var(--line-2)"}`, borderRadius: 8,
                  background: "var(--paper)", fontFamily: "var(--ff-sans)", fontSize: 13, resize: "vertical", boxSizing: "border-box",
                }} />
              {noteErr && (
                <div role="alert" style={{ marginTop: 6, fontSize: 12, color: "var(--terracotta)" }}>
                  {lang === "en" ? "A note is required when rejecting." : "الملاحظة مطلوبة عند الرفض."}
                </div>
              )}
              <div style={{ display: "flex", gap: 8, marginTop: 10 }}>
                <button onClick={submit} disabled={busy} className="btn" style={{ padding: "10px 18px", fontSize: 11, opacity: busy ? 0.6 : 1 }}>
                  {busy ? "…" : (lang === "en" ? "Send" : "إرسال")} →
                </button>
                <button onClick={() => { setAction(null); setNote(""); setNoteErr(false); }} disabled={busy} className="btn ghost" style={{ padding: "10px 18px", fontSize: 11 }}>
                  {lang === "en" ? "Cancel" : "إلغاء"}
                </button>
              </div>
            </div>
          )}
        </div>

        {/* Footer actions */}
        {isOpen && !action && (
          <div style={{ padding: "16px 28px", borderTop: "1px solid var(--line-2)", background: "var(--paper-2)", display: "flex", gap: 10, flexWrap: "wrap" }}>
            <button onClick={() => setAction("approve")} style={{
              flex: 1, padding: "14px 20px", border: 0, borderRadius: 999,
              background: "var(--olive)", color: "var(--paper)",
              fontFamily: "var(--ff-sans)", fontSize: 12, letterSpacing: "0.14em", textTransform: "uppercase",
              cursor: "pointer", fontWeight: 500,
            }}>✓ {lang === "en" ? "Approve" : "موافقة"}</button>
            <button onClick={() => setAction("reject")} style={{
              padding: "14px 20px", border: "1px solid var(--terracotta)", borderRadius: 999,
              background: "transparent", color: "var(--terracotta)",
              fontFamily: "var(--ff-sans)", fontSize: 12, letterSpacing: "0.14em", textTransform: "uppercase", cursor: "pointer",
            }}>× {lang === "en" ? "Request changes / Reject" : "طلب تعديل / رفض"}</button>
          </div>
        )}
      </div>
    </div>
  );
}

// ————————— MAKERS —————————
function AdminMakersPage({ lang, openApproval }) {
  const makers = window.ADMIN_MAKERS;
  const [q, setQ] = React.useState("");
  const [tier, setTier] = React.useState("all");
  const [busy, setBusy] = React.useState(null);
  // A maker is suspended when the platform has unpublished them. The data
  // layer (transformMaker) flags this as tier === "Suspended"; we also accept
  // an explicit is_published === false if it's carried through.
  const isSuspended = (m) => m.tier === "Suspended" || m.is_published === false;
  const filtered = makers.filter(m => {
    if (tier === "suspended") { if (!isSuspended(m)) return false; }
    else if (tier !== "all" && m.tier !== tier) return false;
    if (q && !(m.name + m.ar + m.city + m.trade).toLowerCase().includes(q.toLowerCase())) return false;
    return true;
  });
  // Bilingual tier label for the pill (M8 / H5-style).
  const TIER_LABEL = {
    "Senior Master":  { en: "Senior Master",  ar: "أستاذ كبير" },
    "Verified House": { en: "Verified House", ar: "بيت موثَّق" },
    "Emerging":       { en: "Emerging",       ar: "صاعد" },
    "Suspended":      { en: "Suspended",      ar: "موقوف" },
    "Unrated":        { en: "Unrated",        ar: "غير مقيَّم" },
  };
  const tierLabel = (t) => (TIER_LABEL[t]?.[lang]) || t || (lang === "en" ? "Unrated" : "غير مقيَّم");

  const toggleSuspend = async (m) => {
    if (!m.id) return;
    const suspended = isSuspended(m);
    const willReactivate = suspended; // suspended → reactivate (publish); active → suspend (unpublish)
    if (!confirm(willReactivate
      ? (lang === "en" ? `Reactivate ${m.name}? Their pieces become visible again.` : `إعادة تفعيل ${m.name}؟ ستظهر قطعهم مجددًا.`)
      : (lang === "en" ? `Suspend ${m.name}? Their pieces will be hidden from the site.` : `تعليق ${m.name}؟ ستُخفى قطعهم من الموقع.`))) return;
    setBusy(m.slug);
    const { error } = await window.sb.from("makers").update({ is_published: willReactivate }).eq("id", m.id);
    setBusy(null);
    if (error) { alert(error.message); return; }
    if (window.loadAdminData) window.loadAdminData();
  };
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 18 }}>
      <div style={{ display: "flex", gap: 12, flexWrap: "wrap", alignItems: "center" }}>
        <input value={q} onChange={e => setQ(e.target.value)} placeholder={lang === "en" ? "Search by name, city, trade…" : "بحث…"} style={{
          flex: 1, minWidth: 200, padding: "10px 16px", border: "1px solid var(--line-2)", borderRadius: 999,
          background: "var(--paper)", fontFamily: "var(--ff-sans)", fontSize: 13,
        }} />
        <window.BrandSelect
          value={tier} onChange={v => setTier(v)} lang={lang}
          ariaLabel={lang === "en" ? "Filter by tier" : "تصفية بالفئة"}
          style={{ minWidth: 170 }}
          options={[
            { value: "all", label: lang === "en" ? "All tiers" : "كل الفئات" },
            { value: "Senior Master", label: lang === "en" ? "Senior Master" : "أستاذ كبير" },
            { value: "Verified House", label: lang === "en" ? "Verified House" : "بيت موثَّق" },
            { value: "Emerging", label: lang === "en" ? "Emerging" : "صاعد" },
            { value: "suspended", label: lang === "en" ? "Suspended" : "موقوف" },
          ]}
        />
        {/* Makers join through the public apply form → admin reviews them in the
            onboarding Applications queue (approve provisions the maker account). */}
        <a href="#/admin/applications" className="btn ghost" style={{ whiteSpace: "nowrap" }}>
          {lang === "en" ? "Review applicants" : "مراجعة المتقدّمين"} →
        </a>
      </div>

      <div style={{ border: "1px solid var(--line-2)", borderRadius: 14, overflow: "hidden", background: "var(--paper)" }}>
        <div className="adm-tbl-h stack" style={{
          display: "grid",
          gridTemplateColumns: "60px 1.4fr 1fr 0.8fr 0.6fr 0.6fr 0.7fr 80px",
          padding: "14px 22px", background: "var(--paper-2)",
          fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--muted)",
        }}>
          <div></div>
          <div>{lang === "en" ? "Maker" : "الصانع"}</div>
          <div>{lang === "en" ? "Trade · City" : "الحرفة · المدينة"}</div>
          <div>{lang === "en" ? "Tier" : "الفئة"}</div>
          <div>{lang === "en" ? "Rubric" : "التقييم"}</div>
          <div>{lang === "en" ? "Pieces" : "القطع"}</div>
          <div>{lang === "en" ? "GMV" : "المبيعات"}</div>
          <div></div>
        </div>
        {filtered.map((m, i) => (
          <div key={m.slug} className="adm-tbl-row stack" style={{
            display: "grid",
            gridTemplateColumns: "60px 1.4fr 1fr 0.8fr 0.6fr 0.6fr 0.7fr 80px",
            padding: "16px 22px", borderTop: "1px solid var(--line-2)",
            alignItems: "center", gap: 14,
          }}>
            <div style={{ width: 44, height: 44, borderRadius: "50%", overflow: "hidden" }}>
              <Placeholder tone={m.tone} label={m.name.split(" ")[0].toLowerCase()} />
            </div>
            <div style={{ minWidth: 0 }}>
              <a href={`#/makers/${m.slug}`} style={{ fontFamily: "var(--ff-display)", fontSize: 18, color: "var(--ink)", textDecoration: "none" }}>{m.name}</a>
              <div className="ar" style={{ fontSize: 12, color: "var(--terracotta)" }}>{m.ar}</div>
            </div>
            <div style={{ fontSize: 13 }}>{window.categoryLabel(m.trade, lang)}<div style={{ fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.18em", color: "var(--muted)", textTransform: "uppercase" }}>{m.city}</div></div>
            <AdminPill tone={isSuspended(m) ? "terracotta" : m.tier === "Senior Master" ? "ink" : m.tier === "Verified House" ? "olive" : m.tier === "Unrated" ? "muted" : "gold"}>{tierLabel(m.tier)}</AdminPill>
            <div style={{ fontFamily: "var(--ff-display)", fontSize: 18 }}>{m.rubric != null ? m.rubric : "—"}</div>
            <div style={{ fontSize: 13 }}>{m.pieces}</div>
            <div style={{ fontFamily: "var(--ff-display)", fontSize: 16 }}>{window.adminThousandsK(m.gmv, lang)}</div>
            <div style={{ display: "flex", flexDirection: "column", gap: 4 }}>
              <a href={`#/makers/${m.slug}`} style={{ fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", color: "var(--terracotta)", textDecoration: "none", whiteSpace: "nowrap", textTransform: "uppercase" }}>{lang === "en" ? "profile →" : "الملف →"}</a>
              <button onClick={() => toggleSuspend(m)} disabled={busy === m.slug} style={{ background: "transparent", border: 0, fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", color: isSuspended(m) ? "var(--olive)" : "var(--muted)", cursor: "pointer", textTransform: "uppercase", padding: 0, textAlign: "left" }}>
                {busy === m.slug ? "…" : (isSuspended(m) ? (lang === "en" ? "reactivate" : "تفعيل") : (lang === "en" ? "suspend" : "تعليق"))}
              </button>
            </div>
          </div>
        ))}
      </div>

      <style>{`
        @media (max-width: 900px) {
          .adm-tbl-h { display: none !important; }
          .adm-tbl-row { grid-template-columns: 60px 1fr auto !important; }
          .adm-tbl-row > :nth-child(3), .adm-tbl-row > :nth-child(4),
          .adm-tbl-row > :nth-child(5), .adm-tbl-row > :nth-child(6),
          .adm-tbl-row > :nth-child(7) { display: none; }
        }
      `}</style>
    </div>
  );
}

// ————————— PIECES —————————
function AdminPiecesPage({ lang }) {
  const pieces = window.ADMIN_PIECES;
  const [status, setStatus] = React.useState("all");
  const [q, setQ] = React.useState("");
  const [busy, setBusy] = React.useState(null);
  const filt = pieces.filter(p => {
    if (status !== "all" && p.status.toLowerCase() !== status) return false;
    if (q && !(p.name + p.maker + p.num).toLowerCase().includes(q.toLowerCase())) return false;
    return true;
  });

  const togglePublish = async (p) => {
    if (!p.id) return;
    setBusy(p.id);
    const { error } = await window.sb.from("products").update({ is_published: p.status !== "Live" }).eq("id", p.id);
    setBusy(null);
    if (error) { alert(error.message); return; }
    if (window.loadAdminData) window.loadAdminData();
  };
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 18 }}>
      <div style={{ display: "flex", gap: 12, flexWrap: "wrap", alignItems: "center" }}>
        <input value={q} onChange={e => setQ(e.target.value)} placeholder={lang === "en" ? "Search pieces…" : "بحث…"} style={{
          flex: 1, minWidth: 200, padding: "10px 16px", border: "1px solid var(--line-2)", borderRadius: 999,
          background: "var(--paper)", fontFamily: "var(--ff-sans)", fontSize: 13,
        }} />
        <div style={{ display: "flex", gap: 6, padding: 4, background: "var(--paper-2)", borderRadius: 999 }}>
          {/* PC-1 — status is only ever Live/Draft, so Review/Archived tabs
              always returned zero. Keep only the three real states. */}
          {[
            { k: "all", en: "All", ar: "الكل" },
            { k: "live", en: "Live", ar: "منشور" },
            { k: "draft", en: "Draft", ar: "مسوّدة" },
          ].map(f => (
            <button key={f.k} onClick={() => setStatus(f.k)} style={{
              padding: "6px 12px", borderRadius: 999, border: 0,
              background: status === f.k ? "var(--ink)" : "transparent",
              color: status === f.k ? "var(--paper)" : "var(--ink)",
              fontSize: 11, cursor: "pointer",
            }}>{f[lang] || f.en}</button>
          ))}
        </div>
      </div>

      {filt.length === 0 ? (
        <div style={{ padding: "60px 20px", textAlign: "center", border: "1px dashed var(--line)", borderRadius: 14 }}>
          <div style={{ fontFamily: "var(--ff-display)", fontSize: 22 }}>{lang === "en" ? "No pieces match this filter." : "لا توجد قطع تطابق البحث."}</div>
          <div style={{ marginTop: 6, fontSize: 13, color: "var(--muted)" }}>{lang === "en" ? "Try a different status or clear the search." : "جرّب حالة أخرى أو امسح البحث."}</div>
        </div>
      ) : (
      <div className="adm-grid-pieces" style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(220px, 1fr))", gap: 18 }}>
        {filt.map((p, i) => (
          <div key={i} style={{ border: "1px solid var(--line-2)", borderRadius: 12, overflow: "hidden", background: "var(--paper)" }}>
            <div style={{ aspectRatio: "1", position: "relative" }}>
              <Placeholder tone={p.tone} label={p.name.toLowerCase()} meta={p.num} />
              <div style={{ position: "absolute", top: 10, left: 10 }}><AdminPill tone={p.status === "Live" ? "olive" : "muted"}>{_pieceStatusLabel(p.status, lang)}</AdminPill></div>
            </div>
            <div style={{ padding: 14 }}>
              <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", gap: 8 }}>
                <div style={{ fontFamily: "var(--ff-display)", fontSize: 17, lineHeight: 1.2 }}>{p.name}</div>
                <div style={{ fontFamily: "var(--ff-display)", fontSize: 16, whiteSpace: "nowrap" }}>{window.adminNum(p.price, lang)} <span style={{ fontFamily: "var(--ff-mono)", fontSize: 10, color: "var(--muted)" }}>EGP</span></div>
              </div>
              <div style={{ fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.2em", color: "var(--muted)", textTransform: "uppercase", marginTop: 4 }}>{p.makerName} · {p.num}</div>
              <div style={{ marginTop: 10, display: "flex", justifyContent: "space-between", fontFamily: "var(--ff-mono)", fontSize: 10, color: "var(--muted)", letterSpacing: "0.18em", textTransform: "uppercase" }}>
                <span>{p.sold} {lang === "en" ? "sold" : "بيع"}</span><span>{p.stock} {lang === "en" ? "stock" : "مخزون"}</span>
              </div>
              <button onClick={() => togglePublish(p)} disabled={busy === p.id || !p.id} style={{ marginTop: 10, width: "100%", padding: "8px 12px", borderRadius: 999, border: "1px solid var(--line)", background: p.status === "Live" ? "transparent" : "var(--olive)", color: p.status === "Live" ? "var(--ink)" : "var(--paper)", fontSize: 11, cursor: p.id ? "pointer" : "not-allowed", opacity: busy === p.id ? 0.5 : (p.id ? 1 : 0.5) }}>
                {busy === p.id ? "…" : (p.status === "Live" ? (lang === "en" ? "Unpublish" : "إخفاء") : (lang === "en" ? "Publish" : "نشر"))}
              </button>
            </div>
          </div>
        ))}
      </div>
      )}
    </div>
  );
}

// ————————— PIECES & IMAGES —————————
// Admin direct-write image manager. Sits alongside the existing Pieces tab
// (which is a publish/unpublish moderation surface) and the maker-side
// PiecePhotosModal (which goes through the approval queue). Admin writes
// directly to product_images + Supabase Storage; is_admin() RLS allows it.
function AdminPiecesImagesPage({ lang }) {
  // pieces flows from the same window.ADMIN_PIECES used by AdminPiecesPage,
  // so we never duplicate the products fetch.
  const pieces = (window.ADMIN_PIECES || []).filter(p => p.id);
  const [imagesByProduct, setImagesByProduct] = React.useState({});
  const [q, setQ] = React.useState("");
  const [statusFilter, setStatusFilter] = React.useState("all");
  const [active, setActive] = React.useState(null);

  // One batch fetch on mount: every image, grouped by product_id. Closed-beta
  // scale; if this ever exceeds a few thousand rows we'll add a paginated RPC.
  const refresh = React.useCallback(() => {
    window.sb.from("product_images")
      .select("id, product_id, storage_path, alt_en, alt_ar, is_main, position, created_at")
      .order("position", { ascending: true })
      .then(({ data, error }) => {
        if (error) { console.warn("admin pieces images load:", error.message); return; }
        const by = {};
        for (const row of (data || [])) {
          if (!by[row.product_id]) by[row.product_id] = [];
          by[row.product_id].push(row);
        }
        // Sort each list: is_main first, then by position
        for (const k of Object.keys(by)) {
          by[k].sort((a, b) => {
            if (a.is_main && !b.is_main) return -1;
            if (b.is_main && !a.is_main) return 1;
            return (a.position ?? 0) - (b.position ?? 0);
          });
        }
        setImagesByProduct(by);
      });
  }, []);
  React.useEffect(refresh, [refresh]);

  const publicUrl = (storagePath) => {
    if (!storagePath) return null;
    const { data } = window.sb.storage.from("product-images").getPublicUrl(storagePath);
    return data?.publicUrl || null;
  };

  const filtered = pieces.filter(p => {
    if (statusFilter !== "all" && p.status.toLowerCase() !== statusFilter) return false;
    if (q) {
      const hay = (p.name + " " + p.maker + " " + p.num + " " + (p.makerName || "")).toLowerCase();
      if (!hay.includes(q.toLowerCase())) return false;
    }
    return true;
  });

  const eyebrow = { fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--muted)" };

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 18 }}>
      <div>
        <h2 style={{ fontFamily: "var(--ff-display)", fontSize: 32, letterSpacing: "-0.01em", marginBottom: 4 }}>
          {lang === "en" ? "Pieces & images" : "القطع والصور"}
        </h2>
        <p style={{ fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.2em", color: "var(--muted)", textTransform: "uppercase" }}>
          {lang === "en"
            ? "Curator's catalogue — direct image control, no approval queue."
            : "كتالوج الإدارة — تحكّم مباشر، بلا قائمة موافقات."}
        </p>
      </div>

      <div style={{ display: "flex", gap: 12, flexWrap: "wrap", alignItems: "center" }}>
        <input
          value={q} onChange={e => setQ(e.target.value)}
          placeholder={lang === "en" ? "Search by name, SKU, or maker…" : "بحث بالاسم أو الرمز أو الصانع…"}
          aria-label={lang === "en" ? "Search pieces" : "بحث في القطع"}
          style={{
            flex: 1, minWidth: 220, padding: "10px 16px", border: "1px solid var(--line-2)",
            borderRadius: 999, background: "var(--paper)", fontFamily: "var(--ff-sans)", fontSize: 13, outline: 0,
          }} />
        <div style={{ display: "flex", gap: 6, padding: 4, background: "var(--paper-2)", borderRadius: 999 }}>
          {[
            { k: "all",   en: "All",       ar: "الكل" },
            { k: "live",  en: "Live",      ar: "منشور" },
            { k: "draft", en: "Draft",     ar: "مسوّدة" },
          ].map(f => (
            <button key={f.k} onClick={() => setStatusFilter(f.k)} style={{
              padding: "6px 12px", borderRadius: 999, border: 0,
              background: statusFilter === f.k ? "var(--ink)" : "transparent",
              color: statusFilter === f.k ? "var(--paper)" : "var(--ink)",
              fontSize: 11, cursor: "pointer", fontFamily: "var(--ff-sans)",
            }}>{f[lang] || f.en}</button>
          ))}
        </div>
      </div>

      <div style={{ border: "1px solid var(--line-2)", borderRadius: 14, overflow: "hidden", background: "var(--paper)" }}>
        <div className="adm-tbl-h" style={{
          display: "grid", gridTemplateColumns: "70px 1.6fr 1.2fr 0.7fr 0.7fr 60px",
          padding: "14px 22px", background: "var(--paper-2)",
          fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--muted)",
          alignItems: "center",
        }}>
          <div></div>
          <div>{lang === "en" ? "Piece" : "القطعة"}</div>
          <div>{lang === "en" ? "Maker" : "الصانع"}</div>
          <div>{lang === "en" ? "Status" : "الحالة"}</div>
          <div>{lang === "en" ? "Photos" : "الصور"}</div>
          <div></div>
        </div>
        {filtered.length === 0 && (
          <div style={{ padding: "60px 20px", textAlign: "center", color: "var(--muted)", fontSize: 14 }}>
            {lang === "en" ? "No pieces match this filter." : "لا توجد قطع تطابق البحث."}
          </div>
        )}
        {filtered.map((p) => {
          const imgs = imagesByProduct[p.id] || [];
          const mainImg = imgs.find(i => i.is_main) || imgs[0];
          const count = imgs.length;
          return (
            <div key={p.id} onClick={() => setActive(p)}
              role="button" tabIndex={0}
              onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); setActive(p); } }}
              aria-label={(lang === "en" ? "Manage images for " : "إدارة صور ") + (p.name || p.num)}
              style={{
                display: "grid", gridTemplateColumns: "70px 1.6fr 1.2fr 0.7fr 0.7fr 60px",
                padding: "14px 22px", borderTop: "1px solid var(--line-2)", alignItems: "center", fontSize: 13,
                cursor: "pointer", background: "var(--paper)", outline: 0,
              }}>
              <div style={{ width: 50, height: 50, borderRadius: 8, overflow: "hidden", border: "1px solid var(--line-2)" }}>
                {mainImg && publicUrl(mainImg.storage_path) ? (
                  <img src={publicUrl(mainImg.storage_path)}
                    alt={mainImg.alt_en || p.name || ""}
                    loading="lazy"
                    style={{ width: "100%", height: "100%", objectFit: "cover", display: "block" }} />
                ) : (
                  <Placeholder tone={p.tone || "sand"} label="" meta="" />
                )}
              </div>
              <div style={{ minWidth: 0 }}>
                <div style={{ fontFamily: "var(--ff-display)", fontSize: 17, lineHeight: 1.2 }}>{p.name}</div>
                <div className="ar" style={{ fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.2em", color: "var(--muted)", textTransform: "uppercase", marginTop: 4 }}>
                  {p.num}{p.trade ? ` · ${p.trade}` : ""}
                </div>
              </div>
              <div style={{ minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{p.makerName || "—"}</div>
              <div>
                <AdminPill tone={p.status === "Live" ? "olive" : p.status === "Review" ? "gold" : "muted"}>
                  {_pieceStatusLabel(p.status, lang)}
                </AdminPill>
              </div>
              <div style={{ fontFamily: "var(--ff-mono)", fontSize: 11, letterSpacing: "0.08em", color: count === 0 ? "var(--terracotta)" : "var(--olive)" }}>
                {count === 0
                  ? (lang === "en" ? "0 — none" : "٠ — لا شيء")
                  : (lang === "en" ? `${count} photo${count === 1 ? "" : "s"}` : `${count.toLocaleString("ar-EG")} صور`)}
              </div>
              <div style={{ fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.22em", color: "var(--terracotta)", textAlign: "right" }}>→</div>
            </div>
          );
        })}
      </div>

      <PiecesImagesDrawer
        piece={active}
        existing={active ? (imagesByProduct[active.id] || []) : []}
        onClose={() => setActive(null)}
        lang={lang}
        onChanged={refresh}
      />
    </div>
  );
}

// ─── Per-product image manager (slide-from-right drawer)
function PiecesImagesDrawer({ piece, existing, onClose, lang, onChanged }) {
  const [busy, setBusy] = React.useState(null);   // id of row being mutated, or 'upload', or 'replace'
  const [err, setErr] = React.useState("");
  const [altEdits, setAltEdits] = React.useState({});  // {imageId: {alt_en, alt_ar}}
  const [confirmDeleteId, setConfirmDeleteId] = React.useState(null);

  // ESC closes, body scroll lock, role=dialog — matches AdminOrderDrawer.
  React.useEffect(() => {
    if (!piece) return;
    const prev = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    window.addEventListener("keydown", onKey);
    return () => {
      document.body.style.overflow = prev;
      window.removeEventListener("keydown", onKey);
    };
  }, [piece, onClose]);

  React.useEffect(() => {
    // Clear transient state when opening a different piece.
    setBusy(null); setErr(""); setAltEdits({}); setConfirmDeleteId(null);
  }, [piece?.id]);

  if (!piece) return null;

  const publicUrl = (storagePath) => {
    if (!storagePath) return null;
    const { data } = window.sb.storage.from("product-images").getPublicUrl(storagePath);
    return data?.publicUrl || null;
  };

  // ─── Mutations (all direct DB writes — admin bypasses the maker approval
  // queue via is_admin() RLS).

  // Sequential set-main: demote current main, then promote new. Race-safe
  // for the closed-beta scale (single admin clicking through a queue); a
  // concurrent click could briefly produce zero mains, but the PDP falls
  // back to the first row in that case.
  const setAsMain = async (img) => {
    if (img.is_main) return;
    setBusy(img.id); setErr("");
    const currentMain = existing.find(i => i.is_main && i.id !== img.id);
    try {
      if (currentMain) {
        const { error: e1 } = await window.sb.from("product_images")
          .update({ is_main: false })
          .eq("id", currentMain.id);
        if (e1) throw e1;
      }
      const { error: e2 } = await window.sb.from("product_images")
        .update({ is_main: true })
        .eq("id", img.id);
      if (e2) throw e2;
      onChanged && onChanged();
    } catch (ex) {
      setErr(ex.message || "Failed to set main image");
    } finally {
      setBusy(null);
    }
  };

  // Swap positions with the neighbour above/below. Position-only — is_main
  // ordering is rendered separately.
  const move = async (img, direction) => {
    const list = existing.filter(i => !i.is_main).slice(); // non-main rows
    const idx = list.findIndex(i => i.id === img.id);
    if (img.is_main || idx < 0) return;
    const swapWith = direction === "up" ? list[idx - 1] : list[idx + 1];
    if (!swapWith) return;
    setBusy(img.id); setErr("");
    try {
      // Two sequential updates — bigger positions first to dodge any
      // hypothetical unique constraint, even though there isn't one.
      const aPos = img.position ?? 0;
      const bPos = swapWith.position ?? 0;
      const { error: e1 } = await window.sb.from("product_images")
        .update({ position: bPos }).eq("id", img.id);
      if (e1) throw e1;
      const { error: e2 } = await window.sb.from("product_images")
        .update({ position: aPos }).eq("id", swapWith.id);
      if (e2) throw e2;
      onChanged && onChanged();
    } catch (ex) {
      setErr(ex.message || "Failed to reorder");
    } finally {
      setBusy(null);
    }
  };

  const remove = async (img) => {
    setBusy(img.id); setErr("");
    try {
      // Delete storage file first (best-effort — failures are non-fatal so
      // we don't leave the row behind), then the DB row.
      if (img.storage_path) {
        await window.sb.storage.from("product-images").remove([img.storage_path]).catch(() => {});
      }
      const { error } = await window.sb.from("product_images").delete().eq("id", img.id);
      if (error) throw error;
      setConfirmDeleteId(null);
      onChanged && onChanged();
    } catch (ex) {
      setErr(ex.message || "Failed to delete");
    } finally {
      setBusy(null);
    }
  };

  const saveAlt = async (img) => {
    const edits = altEdits[img.id];
    if (!edits) return;
    setBusy(img.id); setErr("");
    try {
      const patch = {};
      if (edits.alt_en !== undefined) patch.alt_en = edits.alt_en;
      if (edits.alt_ar !== undefined) patch.alt_ar = edits.alt_ar;
      if (Object.keys(patch).length === 0) return;
      const { error } = await window.sb.from("product_images")
        .update(patch).eq("id", img.id);
      if (error) throw error;
      setAltEdits(a => { const n = { ...a }; delete n[img.id]; return n; });
      onChanged && onChanged();
    } catch (ex) {
      setErr(ex.message || "Failed to save alt text");
    } finally {
      setBusy(null);
    }
  };

  // Upload helper — file validation + storage upload + insert row.
  // Returns the new row id, or throws.
  const uploadFile = async (file, asMain = false) => {
    if (!file) throw new Error("No file");
    if (!/^image\/(jpeg|png|webp|avif)$/.test(file.type)) {
      throw new Error(lang === "en" ? "Only JPEG, PNG, WebP or AVIF." : "JPEG, PNG, WebP أو AVIF فقط.");
    }
    if (file.size > 8 * 1024 * 1024) {
      throw new Error(lang === "en" ? "Max 8 MB per image." : "الحدّ ٨ ميغابايت.");
    }
    const ext = (file.name.split(".").pop() || "jpg").toLowerCase();
    const rand = Math.random().toString(36).slice(2, 8);
    const path = `${piece.id}/${Date.now()}-${rand}.${ext}`;
    const { error: upErr } = await window.sb.storage
      .from("product-images")
      .upload(path, file, { upsert: false, contentType: file.type });
    if (upErr) throw upErr;

    // If this should be main, demote the current main first.
    if (asMain) {
      const currentMain = existing.find(i => i.is_main);
      if (currentMain) {
        const { error: dErr } = await window.sb.from("product_images")
          .update({ is_main: false }).eq("id", currentMain.id);
        if (dErr) throw dErr;
      }
    }
    // First image lands as main automatically.
    const firstImage = existing.length === 0;
    const nextPos = existing.length;
    const { data, error: insErr } = await window.sb.from("product_images")
      .insert({
        product_id: piece.id,
        storage_path: path,
        alt_en: piece.name || "",
        alt_ar: piece.name_ar || piece.name || "",
        position: nextPos,
        is_main: asMain || firstImage,
      })
      .select("id").single();
    if (insErr) throw insErr;
    return data?.id;
  };

  // BrandFileDrop surfaces the chosen File[] (it does NOT upload). We keep the
  // existing uploadFile → storage path → product_images.storage_path insert
  // logic and simply take the first file from the array.
  const onAddFiles = async (files) => {
    const file = files && files[0];
    if (!file) return;
    setBusy("upload"); setErr("");
    try {
      await uploadFile(file, false);
      onChanged && onChanged();
    } catch (ex) {
      setErr(ex.message || "Upload failed");
    } finally {
      setBusy(null);
    }
  };
  const onReplaceMainFiles = async (files) => {
    const file = files && files[0];
    if (!file) return;
    setBusy("replace"); setErr("");
    try {
      await uploadFile(file, true);
      onChanged && onChanged();
    } catch (ex) {
      setErr(ex.message || "Upload failed");
    } finally {
      setBusy(null);
    }
  };

  const eyebrow = { fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--muted)" };
  const sortedImgs = existing.slice().sort((a, b) => {
    if (a.is_main && !b.is_main) return -1;
    if (b.is_main && !a.is_main) return 1;
    return (a.position ?? 0) - (b.position ?? 0);
  });

  return (
    <>
      <div onClick={onClose} style={{ position: "fixed", inset: 0, background: "rgba(28,26,21,0.55)", zIndex: 90 }} />
      <aside role="dialog" aria-modal="true"
        aria-label={lang === "en" ? "Image manager" : "إدارة الصور"}
        style={{
          position: "fixed", top: 0, right: 0, bottom: 0,
          width: "min(760px, 100vw)", background: "var(--paper)", zIndex: 91,
          overflowY: "auto", boxShadow: "-20px 0 60px -20px rgba(28,26,21,0.3)",
        }}>
        <div style={{ padding: "22px 28px", borderBottom: "1px solid var(--line-2)", background: "var(--paper-2)", display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 14 }}>
          <div style={{ minWidth: 0 }}>
            <div style={{ ...eyebrow, color: "var(--terracotta)" }}>
              {lang === "en" ? "Image manager" : "إدارة الصور"}
            </div>
            <h2 style={{ fontFamily: "var(--ff-display)", fontSize: 28, marginTop: 4, letterSpacing: "-0.01em" }}>{piece.name}</h2>
            <div style={{ marginTop: 6, fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.2em", color: "var(--muted)", textTransform: "uppercase" }}>
              {piece.num}{piece.makerName ? ` · ${piece.makerName}` : ""}
            </div>
          </div>
          <button onClick={onClose}
            aria-label={lang === "en" ? "Close image manager" : "إغلاق"}
            style={{ background: "transparent", border: 0, fontSize: 22, cursor: "pointer", color: "var(--muted)", minWidth: 44, minHeight: 44, display: "inline-flex", alignItems: "center", justifyContent: "center", padding: 0, lineHeight: 1 }}>×</button>
        </div>

        <div style={{ padding: "20px 28px", display: "flex", flexDirection: "column", gap: 22 }}>

          {/* Upload — brand dropzone (surfaces File[]; uploadFile keeps the
              storage-path → product_images insert logic). The first image lands
              as main automatically; "Replace main" is a separate dropzone shown
              once at least one image exists. */}
          <section style={{ display: "grid", gridTemplateColumns: existing.length > 0 ? "1fr 1fr" : "1fr", gap: 10 }} className="adm-img-upload">
            <window.BrandFileDrop
              onFiles={onAddFiles}
              accept="image/jpeg,image/png,image/webp,image/avif"
              disabled={!!busy}
              lang={lang}
              name="add"
              showList={false}
              label={busy === "upload"
                ? (lang === "en" ? "Uploading…" : "جاري الرفع…")
                : (lang === "en" ? "Upload a new photo" : "ارفع صورة جديدة")}
              hint={lang === "en" ? "JPEG · PNG · WebP · AVIF — up to 8 MB" : "JPEG · PNG · WebP · AVIF — حتى ٨م.ب"}
              ariaLabel={lang === "en" ? "Upload new image" : "ارفع صورة جديدة"}
            />
            {existing.length > 0 && (
              <window.BrandFileDrop
                onFiles={onReplaceMainFiles}
                accept="image/jpeg,image/png,image/webp,image/avif"
                disabled={!!busy}
                lang={lang}
                name="replace-main"
                showList={false}
                label={busy === "replace"
                  ? (lang === "en" ? "Uploading…" : "جاري الرفع…")
                  : (lang === "en" ? "Replace the main photo" : "استبدل الصورة الرئيسيّة")}
                hint={lang === "en" ? "Becomes the cover image" : "تصبح صورة الغلاف"}
                ariaLabel={lang === "en" ? "Replace main image" : "استبدل الصورة الرئيسيّة"}
              />
            )}
          </section>

          <div style={eyebrow}>
            {lang === "en"
              ? "Admin edits are immediate."
              : "تعديلات الإدارة فوريّة."}
          </div>

          {err && (
            <div role="alert" style={{ padding: "12px 16px", background: "rgba(194,99,66,0.08)", border: "1px solid rgba(194,99,66,0.35)", borderRadius: 10, fontSize: 13, color: "var(--terracotta)" }}>
              {err}
            </div>
          )}

          {/* Image grid */}
          <section>
            <div style={{ ...eyebrow, marginBottom: 10 }}>
              {lang === "en" ? "Photos" : "الصور"} · {sortedImgs.length}
            </div>
            {sortedImgs.length === 0 ? (
              <div style={{ padding: "30px 22px", border: "1px dashed var(--line)", borderRadius: 12, textAlign: "center", color: "var(--muted)", fontSize: 13, background: "var(--paper-2)" }}>
                {lang === "en"
                  ? "No photos yet. Upload the hero shot first — it becomes the main."
                  : "لا توجد صور. ارفع الصورة الرئيسيّة أولًا."}
              </div>
            ) : (
              <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(220px, 1fr))", gap: 14 }}>
                {sortedImgs.map((im, i) => {
                  const isMain = !!im.is_main;
                  const nonMainList = sortedImgs.filter(x => !x.is_main);
                  const nonMainIdx = nonMainList.findIndex(x => x.id === im.id);
                  const canUp = !isMain && nonMainIdx > 0;
                  const canDown = !isMain && nonMainIdx >= 0 && nonMainIdx < nonMainList.length - 1;
                  const editing = altEdits[im.id];
                  const isBusy = busy === im.id;
                  return (
                    <div key={im.id} data-testid="admin-image-card" style={{
                      border: "1px solid var(--line-2)", borderRadius: 12, overflow: "hidden",
                      background: "var(--paper)", display: "flex", flexDirection: "column",
                    }}>
                      <div style={{ position: "relative", aspectRatio: "1" }}>
                        <img src={publicUrl(im.storage_path)}
                          alt={(lang === "ar" ? im.alt_ar : im.alt_en) || piece.name || ""}
                          loading="lazy"
                          style={{ width: "100%", height: "100%", objectFit: "cover", display: "block", background: "var(--paper-2)" }} />
                        {isMain && (
                          <span data-testid="main-badge" style={{
                            position: "absolute", top: 8, left: 8,
                            fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em",
                            color: "var(--paper)", background: "var(--terracotta)",
                            padding: "3px 8px", borderRadius: 999,
                          }}>{lang === "en" ? "MAIN" : "رئيسيّة"}</span>
                        )}
                        <span style={{
                          position: "absolute", top: 8, right: 8,
                          fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.18em",
                          color: "var(--ink)", background: "var(--paper)",
                          padding: "3px 8px", borderRadius: 999, border: "1px solid var(--line-2)",
                        }}>{lang === "en" ? "#" : "ر"}{(im.position ?? 0) + 1}</span>
                      </div>

                      <div style={{ padding: "12px 14px", display: "flex", flexDirection: "column", gap: 10 }}>
                        {/* Alt text editor — collapsed/expanded toggle */}
                        <details>
                          <summary style={{ ...eyebrow, cursor: "pointer", listStyle: "none" }}>
                            {lang === "en" ? "Alt text" : "النص البديل"}
                          </summary>
                          <div style={{ marginTop: 8, display: "flex", flexDirection: "column", gap: 6 }}>
                            <input
                              defaultValue={im.alt_en || ""}
                              onChange={(e) => setAltEdits(a => ({ ...a, [im.id]: { ...(a[im.id] || {}), alt_en: e.target.value } }))}
                              placeholder={lang === "en" ? "Alt (English)" : "النص (إنجليزي)"}
                              aria-label={lang === "en" ? "Alt text (English)" : "النص البديل (إنجليزي)"}
                              style={{ padding: "8px 10px", border: "1px solid var(--line)", borderRadius: 8, fontFamily: "var(--ff-sans)", fontSize: 12, background: "var(--paper)", outline: 0 }} />
                            <input
                              defaultValue={im.alt_ar || ""}
                              onChange={(e) => setAltEdits(a => ({ ...a, [im.id]: { ...(a[im.id] || {}), alt_ar: e.target.value } }))}
                              placeholder={lang === "en" ? "Alt (Arabic)" : "النص (عربي)"}
                              aria-label={lang === "en" ? "Alt text (Arabic)" : "النص البديل (عربي)"}
                              dir="rtl"
                              style={{ padding: "8px 10px", border: "1px solid var(--line)", borderRadius: 8, fontFamily: "var(--ff-sans)", fontSize: 12, background: "var(--paper)", outline: 0 }} />
                            {editing && (
                              <button onClick={() => saveAlt(im)} disabled={isBusy}
                                style={{ marginTop: 4, padding: "6px 12px", borderRadius: 999, border: "1px solid var(--line)", background: "var(--olive)", color: "var(--paper)", fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.18em", textTransform: "uppercase", cursor: "pointer", minHeight: 32 }}>
                                {isBusy ? "…" : (lang === "en" ? "Save alt" : "احفظ")}
                              </button>
                            )}
                          </div>
                        </details>

                        {/* Action row */}
                        <div style={{ display: "flex", gap: 6, flexWrap: "wrap" }}>
                          <button
                            onClick={() => setAsMain(im)}
                            disabled={isBusy || isMain}
                            aria-label={lang === "en" ? "Set as main image" : "اجعلها الرئيسيّة"}
                            data-testid="set-as-main"
                            style={{
                              flex: "1 1 auto", padding: "7px 10px", borderRadius: 999,
                              border: "1px solid var(--line)",
                              background: isMain ? "var(--paper-2)" : "transparent",
                              color: isMain ? "var(--muted)" : "var(--ink)",
                              fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.18em", textTransform: "uppercase",
                              cursor: isMain ? "default" : (isBusy ? "wait" : "pointer"),
                              opacity: isBusy ? 0.5 : 1, minHeight: 32,
                            }}>
                            {isMain ? (lang === "en" ? "Main" : "رئيسيّة") : (lang === "en" ? "Set main" : "اجعلها رئيسيّة")}
                          </button>
                          <button
                            onClick={() => move(im, "up")}
                            disabled={isBusy || !canUp}
                            aria-label={lang === "en" ? "Move up in order" : "أعلى"}
                            style={{
                              padding: "7px 10px", borderRadius: 999, border: "1px solid var(--line)",
                              background: "transparent", color: canUp ? "var(--ink)" : "var(--muted)",
                              fontSize: 12, cursor: canUp ? "pointer" : "default",
                              opacity: isBusy ? 0.5 : 1, minWidth: 34, minHeight: 32,
                            }}>↑</button>
                          <button
                            onClick={() => move(im, "down")}
                            disabled={isBusy || !canDown}
                            aria-label={lang === "en" ? "Move down in order" : "أسفل"}
                            style={{
                              padding: "7px 10px", borderRadius: 999, border: "1px solid var(--line)",
                              background: "transparent", color: canDown ? "var(--ink)" : "var(--muted)",
                              fontSize: 12, cursor: canDown ? "pointer" : "default",
                              opacity: isBusy ? 0.5 : 1, minWidth: 34, minHeight: 32,
                            }}>↓</button>
                          {confirmDeleteId === im.id ? (
                            <button
                              onClick={() => remove(im)}
                              disabled={isBusy}
                              aria-label={lang === "en" ? "Confirm delete" : "أكّد الحذف"}
                              data-testid="confirm-delete"
                              style={{
                                padding: "7px 12px", borderRadius: 999,
                                border: "1px solid var(--terracotta)", background: "var(--terracotta)",
                                color: "var(--paper)",
                                fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.18em", textTransform: "uppercase",
                                cursor: "pointer", minHeight: 32,
                              }}>{lang === "en" ? "Confirm?" : "متأكّد؟"}</button>
                          ) : (
                            <button
                              onClick={() => setConfirmDeleteId(im.id)}
                              disabled={isBusy}
                              aria-label={lang === "en" ? "Delete this image" : "احذف"}
                              data-testid="delete-image"
                              style={{
                                padding: "7px 10px", borderRadius: 999, border: "1px solid var(--line)",
                                background: "transparent", color: "var(--terracotta)",
                                fontSize: 12, cursor: "pointer",
                                opacity: isBusy ? 0.5 : 1, minWidth: 34, minHeight: 32,
                              }}>×</button>
                          )}
                        </div>
                      </div>
                    </div>
                  );
                })}
              </div>
            )}
          </section>
        </div>
      </aside>
    </>
  );
}

// ————————— ORDERS —————————
const MAKER_STATUS_ORDER = [
  "awaiting_admin_review","awaiting_maker_acceptance","maker_confirmed","maker_in_progress",
  "maker_delayed","maker_rejected","quality_check","packed","courier_assigned",
  "handed_to_courier","delivered","delivery_failed","return_under_review","returned","cancelled",
];

const MAKER_STATUS_LABEL = {
  awaiting_admin_review: { en: "Awaiting admin", ar: "بانتظار الإدارة", tone: "muted" },
  awaiting_maker_acceptance: { en: "Awaiting maker", ar: "بانتظار الصانع", tone: "gold" },
  maker_confirmed: { en: "Maker confirmed", ar: "اعتمد الصانع", tone: "olive" },
  maker_in_progress: { en: "In production", ar: "قيد الصنع", tone: "olive" },
  maker_delayed: { en: "Delayed", ar: "متأخر", tone: "terracotta" },
  maker_rejected: { en: "Rejected by maker", ar: "رفضها الصانع", tone: "terracotta" },
  quality_check: { en: "Quality check", ar: "فحص الجودة", tone: "olive" },
  packed: { en: "Packed", ar: "مُغلَّفة", tone: "olive" },
  courier_assigned: { en: "Courier assigned", ar: "خُصِّص مندوب", tone: "olive" },
  handed_to_courier: { en: "Handed to courier", ar: "سُلِّمت للمندوب", tone: "olive" },
  delivered: { en: "Delivered", ar: "وصلت", tone: "olive" },
  delivery_failed: { en: "Delivery failed", ar: "فشلت", tone: "terracotta" },
  return_under_review: { en: "Return review", ar: "مراجعة الإرجاع", tone: "gold" },
  returned: { en: "Returned", ar: "مُرجَعة", tone: "muted" },
  cancelled: { en: "Cancelled", ar: "ألغيت", tone: "muted" },
};

// Per-line operational drawer — shows maker_code / maker_ref / maker_status
// per item, with deadline + priority + admin notes controls. Audit log
// receives a trg_audit_order_item_maker_status entry on every transition.
function AdminOrderDrawer({ orderRow, onClose, lang, onChanged }) {
  const [items, setItems] = React.useState(null);
  const [order, setOrder] = React.useState(null);
  const [events, setEvents] = React.useState([]);
  const [shipments, setShipments] = React.useState([]);
  const [qc, setQc] = React.useState([]);
  const [notifications, setNotifications] = React.useState([]);
  const [busy, setBusy] = React.useState(false);
  const [statusBusy, setStatusBusy] = React.useState(false);
  const [adminNote, setAdminNote] = React.useState("");
  const [shipmentForm, setShipmentForm] = React.useState({ courier: "bosta", tracking: "", url: "", eta: "" });
  const [noteBusy, setNoteBusy] = React.useState(false);

  const loadConsole = React.useCallback(() => {
    if (!orderRow?._uuid) return;
    window.sb.rpc("admin_order_console", { p_order_id: orderRow._uuid })
      .then(({ data, error }) => {
        if (error) { console.warn(error); return; }
        if (!data) return;
        setOrder(data.order);
        setItems(data.items || []);
        setEvents(data.events || []);
        setShipments(data.shipments || []);
        setQc(data.qc || []);
        setNotifications(data.notifications || []);
      });
  }, [orderRow?._uuid]);

  React.useEffect(() => {
    if (!orderRow) return;
    setItems(null); setOrder(null); setEvents([]); setShipments([]); setQc([]); setNotifications([]);
    loadConsole();
  }, [orderRow?._uuid, loadConsole]);

  // ESC closes, body scroll locked.
  React.useEffect(() => {
    if (!orderRow) return;
    const prev = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    window.addEventListener("keydown", onKey);
    return () => {
      document.body.style.overflow = prev;
      window.removeEventListener("keydown", onKey);
    };
  }, [orderRow, onClose]);

  if (!orderRow) return null;
  const addr = order?.shipping_address_json || orderRow.shipping_address_json || {};

  const STATUS_NEXT = {
    pending: "confirmed", pending_confirmation: "confirmed",
    confirmed: "in_preparation", in_preparation: "ready_for_dispatch",
    ready_for_dispatch: "shipped", shipped: "delivered",
  };
  const advanceOrder = async () => {
    if (!order) return;
    const next = STATUS_NEXT[order.status];
    if (!next) return;
    setStatusBusy(true);
    const patch = { status: next };
    if (next === "confirmed") patch.confirmed_at = new Date().toISOString();
    if (next === "shipped") patch.shipped_at = new Date().toISOString();
    if (next === "delivered") patch.delivered_at = new Date().toISOString();
    const { error } = await window.sb.from("orders").update(patch).eq("id", order.id);
    setStatusBusy(false);
    if (error) { alert(error.message); return; }
    setOrder(o => ({ ...o, status: next, ...patch }));
    if (onChanged) onChanged();
  };

  const updateItem = async (item, patch) => {
    setBusy(true);
    const { error } = await window.sb.rpc("admin_update_order_item_op", {
      p_item_id: item.item_id,
      p_maker_status: patch.maker_status ?? null,
      p_maker_due_date: patch.maker_due_date ?? null,
      p_maker_notes: patch.maker_notes ?? null,
      p_admin_delivery_note: patch.admin_delivery_note ?? null,
      p_admin_priority: patch.admin_priority ?? null,
    });
    setBusy(false);
    if (error) { alert(error.message); return; }
    loadConsole();
  };

  const submitNote = async () => {
    if (!order || !adminNote.trim()) return;
    setNoteBusy(true);
    const { error } = await window.sb.rpc("admin_log_order_note", {
      p_order_id: order.id,
      p_note: adminNote.trim(),
    });
    setNoteBusy(false);
    if (error) { alert(error.message); return; }
    setAdminNote("");
    loadConsole();
  };

  const submitShipment = async () => {
    if (!order || !shipmentForm.courier) return;
    setBusy(true);
    const { error } = await window.sb.rpc("admin_upsert_shipment", {
      p_order_id: order.id,
      p_courier_code: shipmentForm.courier,
      p_tracking_number: shipmentForm.tracking || null,
      p_tracking_url: shipmentForm.url || null,
      p_estimated_delivery_at: shipmentForm.eta ? new Date(shipmentForm.eta).toISOString() : null,
      p_notes_internal: null,
    });
    setBusy(false);
    if (error) { alert(error.message); return; }
    loadConsole();
  };

  const openQc = async (item) => {
    setBusy(true);
    const { error } = await window.sb.rpc("admin_open_qc", { p_order_item_id: item.item_id, p_notes: null });
    setBusy(false);
    if (error) { alert(error.message); return; }
    loadConsole();
  };
  const decideQc = async (qcRow, decision) => {
    setBusy(true);
    const { error } = await window.sb.rpc("admin_decide_qc", { p_qc_id: qcRow.id, p_decision: decision, p_notes: null });
    setBusy(false);
    if (error) { alert(error.message); return; }
    loadConsole();
  };

  const eyebrow = { fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--muted)" };
  const fieldVal = { fontSize: 14, color: "var(--ink)", marginTop: 2 };

  return (
    <>
      <div onClick={onClose} style={{ position: "fixed", inset: 0, background: "rgba(28,26,21,0.55)", zIndex: 90 }} />
      <aside role="dialog" aria-modal="true" aria-label={lang === "en" ? "Order operational detail" : "تفاصيل تشغيل الطلب"} style={{ position: "fixed", top: 0, right: 0, bottom: 0, width: "min(720px, 100vw)", background: "var(--paper)", zIndex: 91, overflowY: "auto", boxShadow: "-20px 0 60px -20px rgba(28,26,21,0.3)" }}>
        <div style={{ padding: "22px 28px", borderBottom: "1px solid var(--line-2)", background: "var(--paper-2)", display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 14 }}>
          <div style={{ minWidth: 0 }}>
            <div style={{ ...eyebrow, color: "var(--terracotta)" }}>{lang === "en" ? "Order operations" : "تشغيل الطلب"}</div>
            <h2 style={{ fontFamily: "var(--ff-display)", fontSize: 28, marginTop: 4, letterSpacing: "-0.01em" }}>{orderRow.id}</h2>
            <div style={{ marginTop: 6, display: "flex", gap: 10, flexWrap: "wrap", alignItems: "center" }}>
              <AdminPill tone={_orderStatusTone(order?.status || orderRow.status)}>{_orderStatusLabel(order?.status || orderRow.status, lang)}</AdminPill>
              <span style={{ fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.2em", color: "var(--muted)" }}>{window.fmtDate(orderRow.date, lang, { day: "numeric", month: "short" })} · {window.adminNum(orderRow.total, lang)} EGP</span>
            </div>
          </div>
          <button onClick={onClose} aria-label={lang === "en" ? "Close" : "إغلاق"} style={{ background: "transparent", border: 0, fontSize: 22, cursor: "pointer", color: "var(--muted)", minWidth: 44, minHeight: 44, display: "inline-flex", alignItems: "center", justifyContent: "center", padding: 0, lineHeight: 1 }}>×</button>
        </div>

        <div style={{ padding: "20px 28px", display: "flex", flexDirection: "column", gap: 22 }}>
          {/* Customer */}
          <section>
            <div style={eyebrow}>{lang === "en" ? "Customer" : "العميل"}</div>
            <div style={{ ...fieldVal, fontFamily: "var(--ff-display)", fontSize: 18 }}>{orderRow.buyer}</div>
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12, marginTop: 10 }}>
              <div><div style={eyebrow}>{lang === "en" ? "WhatsApp" : "واتساب"}</div><div style={fieldVal}>{addr.phone || orderRow.phone || "—"}</div></div>
              <div><div style={eyebrow}>{lang === "en" ? "Email" : "البريد"}</div><div style={fieldVal}>{orderRow.email}</div></div>
            </div>
          </section>

          {/* Shipping address — all operational fields */}
          <section style={{ padding: 16, background: "var(--paper-2)", borderRadius: 10 }}>
            <div style={eyebrow}>{lang === "en" ? "Shipping address" : "عنوان الشحن"}</div>
            <div style={{ marginTop: 8, fontSize: 13, lineHeight: 1.65 }}>
              <div><strong>{addr.recipient || orderRow.buyer}</strong></div>
              <div>{addr.line1}{addr.building ? `, ${lang === "en" ? "Bldg" : "عمارة"} ${addr.building}` : ""}</div>
              {(addr.floor || addr.apartment) && (
                <div>
                  {addr.floor ? `${lang === "en" ? "Floor" : "دور"} ${addr.floor}` : ""}
                  {addr.floor && addr.apartment ? " · " : ""}
                  {addr.apartment ? `${lang === "en" ? "Apt" : "شقة"} ${addr.apartment}` : ""}
                </div>
              )}
              <div>{addr.area || addr.city}{addr.area && addr.city ? `, ${addr.city}` : ""} · {addr.governorate}</div>
              {addr.landmark && <div style={{ marginTop: 4, color: "var(--olive)", fontStyle: "italic" }}>{lang === "en" ? "Landmark" : "علامة مميزة"}: {addr.landmark}</div>}
              {addr.notes && <div style={{ marginTop: 4, color: "var(--olive)", fontStyle: "italic" }}>{lang === "en" ? "Notes" : "ملاحظات"}: {addr.notes}</div>}
            </div>
          </section>

          {/* Line items — per-maker operational controls */}
          <section>
            <div style={{ ...eyebrow, marginBottom: 10 }}>{lang === "en" ? "Line items · per maker" : "بنود الطلب · لكل صانع"}</div>
            {items === null ? (
              <div style={{ padding: 20, color: "var(--muted)" }}>{lang === "en" ? "Loading…" : "تحميل…"}</div>
            ) : items.length === 0 ? (
              <div style={{ padding: 20, color: "var(--muted)" }}>{lang === "en" ? "No items." : "لا بنود."}</div>
            ) : items.map((it, i) => {
              const ml = MAKER_STATUS_LABEL[it.maker_status] || { en: it.maker_status, ar: it.maker_status, tone: "muted" };
              return (
                <div key={it.item_id} style={{ marginTop: i === 0 ? 0 : 12, padding: 16, border: "1px solid var(--line-2)", borderRadius: 12 }}>
                  <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 12 }}>
                    <div style={{ minWidth: 0 }}>
                      <div style={{ display: "flex", gap: 8, flexWrap: "wrap", alignItems: "center" }}>
                        <span style={{ fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.22em", color: "var(--paper)", background: "var(--ink)", padding: "3px 8px", borderRadius: 999 }}>{it.maker_code || "—"}</span>
                        <span style={{ fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.22em", color: "var(--terracotta)" }}>{it.maker_ref || ""}</span>
                        <AdminPill tone={ml.tone}>{ml[lang] || ml.en}</AdminPill>
                      </div>
                      <div style={{ marginTop: 6, fontFamily: "var(--ff-display)", fontSize: 18 }}>{it.product_name_en}</div>
                      <div style={{ marginTop: 2, fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.2em", color: "var(--muted)" }}>
                        {it.sku} · {it.maker_name_en || "—"} · {lang === "en" ? "qty" : "كمية"} {it.quantity}
                      </div>
                    </div>
                    <div style={{ fontFamily: "var(--ff-display)", fontSize: 18, whiteSpace: "nowrap" }}>{window.adminNum(Math.round(it.line_total_piastres / 100), lang)} <span style={{ fontFamily: "var(--ff-mono)", fontSize: 10, color: "var(--muted)" }}>EGP</span></div>
                  </div>

                  <div style={{ marginTop: 14, display: "grid", gridTemplateColumns: "1.2fr 1fr 1fr", gap: 10 }}>
                    <div style={{ display: "block" }}>
                      <div style={eyebrow}>{lang === "en" ? "Maker status" : "حالة الصانع"}</div>
                      <window.BrandSelect
                        value={it.maker_status || "awaiting_admin_review"} disabled={busy}
                        onChange={v => v !== (it.maker_status || "awaiting_admin_review") && updateItem(it, { maker_status: v })}
                        lang={lang}
                        ariaLabel={lang === "en" ? "Update maker status" : "تحديث حالة الصانع"}
                        style={{ marginTop: 4 }}
                        options={MAKER_STATUS_ORDER.map(s => ({
                          value: s, label: (MAKER_STATUS_LABEL[s]?.[lang]) || (MAKER_STATUS_LABEL[s]?.en) || s,
                        }))}
                      />
                    </div>
                    <div style={{ display: "block" }}>
                      <div style={eyebrow}>{lang === "en" ? "Deadline" : "الموعد"}</div>
                      <window.BrandDate
                        value={it.maker_due_date || ""} disabled={busy}
                        onChange={v => v !== (it.maker_due_date || "") && updateItem(it, { maker_due_date: v || null })}
                        lang={lang}
                        ariaLabel={lang === "en" ? "Maker due date" : "موعد الصانع"}
                        placeholder={lang === "en" ? "No deadline" : "بلا موعد"}
                        style={{ marginTop: 4 }}
                      />
                    </div>
                    <div style={{ display: "block" }}>
                      <div style={eyebrow}>{lang === "en" ? "Priority" : "الأولوية"}</div>
                      <window.BrandSelect
                        value={String(it.admin_priority_level ?? 0)} disabled={busy}
                        onChange={v => Number(v) !== (it.admin_priority_level ?? 0) && updateItem(it, { admin_priority: Number(v) })}
                        lang={lang}
                        ariaLabel={lang === "en" ? "Admin priority level" : "مستوى الأولوية"}
                        style={{ marginTop: 4 }}
                        options={[
                          { value: "0", label: lang === "en" ? "Normal" : "عادي" },
                          { value: "1", label: lang === "en" ? "High" : "مرتفع" },
                          { value: "2", label: lang === "en" ? "Urgent" : "عاجل" },
                        ]}
                      />
                    </div>
                  </div>

                  <details style={{ marginTop: 12 }}>
                    <summary style={{ ...eyebrow, cursor: "pointer" }}>{lang === "en" ? "Internal notes" : "ملاحظات داخلية"}</summary>
                    <div style={{ marginTop: 8, display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10 }}>
                      <label>
                        <div style={eyebrow}>{lang === "en" ? "Maker notes" : "ملاحظات الصانع"}</div>
                        <textarea defaultValue={it.maker_notes_internal || ""} disabled={busy}
                          onBlur={e => e.target.value !== (it.maker_notes_internal || "") && updateItem(it, { maker_notes: e.target.value })}
                          aria-label={lang === "en" ? "Internal maker notes" : "ملاحظات الصانع الداخلية"}
                          rows={3}
                          style={{ marginTop: 4, width: "100%", padding: "8px 12px", border: "1px solid var(--line)", borderRadius: 8, background: "var(--paper)", fontSize: 13, fontFamily: "var(--ff-sans)", resize: "vertical", boxSizing: "border-box" }} />
                      </label>
                      <label>
                        <div style={eyebrow}>{lang === "en" ? "Delivery note" : "ملاحظات التوصيل"}</div>
                        <textarea defaultValue={it.admin_delivery_note || ""} disabled={busy}
                          onBlur={e => e.target.value !== (it.admin_delivery_note || "") && updateItem(it, { admin_delivery_note: e.target.value })}
                          aria-label={lang === "en" ? "Admin delivery note" : "ملاحظات التوصيل من الإدارة"}
                          rows={3}
                          style={{ marginTop: 4, width: "100%", padding: "8px 12px", border: "1px solid var(--line)", borderRadius: 8, background: "var(--paper)", fontSize: 13, fontFamily: "var(--ff-sans)", resize: "vertical", boxSizing: "border-box" }} />
                      </label>
                    </div>
                  </details>
                </div>
              );
            })}
          </section>

          {/* ─── Shipment block ─── */}
          <section>
            <div style={{ ...eyebrow, marginBottom: 10 }}>{lang === "en" ? "Delivery" : "التوصيل"}</div>
            {shipments.length === 0 ? (
              <div style={{ padding: 14, background: "var(--paper-2)", borderRadius: 10, fontSize: 13, color: "var(--muted)" }}>
                {lang === "en" ? "No shipment assigned yet." : "لم يُعيَّن مندوب بعد."}
              </div>
            ) : (
              shipments.map(s => (
                <div key={s.id} style={{ padding: 14, border: "1px solid var(--line-2)", borderRadius: 10, marginBottom: 10 }}>
                  <div style={{ display: "flex", justifyContent: "space-between", flexWrap: "wrap", gap: 10, alignItems: "center" }}>
                    <div style={{ display: "flex", gap: 10, alignItems: "center" }}>
                      <span style={{ fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.22em", color: "var(--paper)", background: "var(--ink)", padding: "3px 8px", borderRadius: 999 }}>{(s.courier_code || "—").toUpperCase()}</span>
                      <AdminPill tone={s.status === "delivered" ? "olive" : s.status === "delivery_failed" ? "terracotta" : "gold"}>{_enumLabel(SHIPMENT_STATUS_LABEL, s.status, lang)}</AdminPill>
                    </div>
                    {s.tracking_number && (
                      <span style={{ fontFamily: "var(--ff-mono)", fontSize: 11, letterSpacing: "0.06em", color: "var(--terracotta)" }}>{s.tracking_number}</span>
                    )}
                  </div>
                  {s.estimated_delivery_at && (
                    <div style={{ marginTop: 6, fontSize: 12, color: "var(--olive)" }}>
                      {lang === "en" ? "Expected " : "متوقّع "}{window.fmtDate(s.estimated_delivery_at, lang, { day: "numeric", month: "short" })}
                    </div>
                  )}
                </div>
              ))
            )}
            <div style={{ marginTop: 10, padding: 14, background: "var(--paper-2)", borderRadius: 10 }}>
              <div style={{ ...eyebrow, marginBottom: 8 }}>{lang === "en" ? "Assign / update courier" : "تعيين المندوب"}</div>
              <div style={{ display: "grid", gridTemplateColumns: "1fr 1.4fr 1fr auto", gap: 8, alignItems: "end" }}>
                <window.BrandSelect
                  value={shipmentForm.courier}
                  onChange={v => setShipmentForm(f => ({ ...f, courier: v }))}
                  lang={lang} disabled={busy}
                  ariaLabel={lang === "en" ? "Courier" : "المندوب"}
                  options={[
                    { value: "bosta", label: "Bosta" },
                    { value: "aramex", label: "Aramex" },
                    { value: "sanaa-pickup", label: lang === "en" ? "SANAA pickup" : "استلام صَنعة" },
                    { value: "intl", label: lang === "en" ? "International" : "دولي" },
                  ]}
                />
                <input type="text" value={shipmentForm.tracking}
                  onChange={e => setShipmentForm(f => ({ ...f, tracking: e.target.value }))}
                  placeholder={lang === "en" ? "Tracking number" : "رقم التتبّع"}
                  aria-label={lang === "en" ? "Tracking number" : "رقم التتبّع"}
                  style={{ padding: "8px 10px", border: "1px solid var(--line)", borderRadius: 8, background: "var(--paper)", fontSize: 13, fontFamily: "var(--ff-mono)", minHeight: 36 }} />
                <window.BrandDate
                  value={shipmentForm.eta}
                  onChange={v => setShipmentForm(f => ({ ...f, eta: v }))}
                  lang={lang} disabled={busy}
                  ariaLabel={lang === "en" ? "Estimated delivery" : "موعد متوقّع"}
                  placeholder={lang === "en" ? "Est. delivery" : "موعد متوقّع"}
                />
                <button onClick={submitShipment} disabled={busy} className="btn" style={{ padding: "8px 14px", fontSize: 11, minHeight: 36 }}>
                  {busy ? "…" : (lang === "en" ? "Save" : "حفظ")}
                </button>
              </div>
            </div>
          </section>

          {/* ─── QC reports ─── */}
          <section>
            <div style={{ ...eyebrow, marginBottom: 10 }}>{lang === "en" ? "Quality control" : "مراقبة الجودة"}</div>
            {qc.length === 0 ? (
              <div style={{ padding: 14, background: "var(--paper-2)", borderRadius: 10, fontSize: 13, color: "var(--muted)", display: "flex", justifyContent: "space-between", alignItems: "center", gap: 10, flexWrap: "wrap" }}>
                <span>{lang === "en" ? "No QC reports yet." : "لا توجد مراجعات."}</span>
                {items && items.length > 0 && (
                  <div style={{ display: "flex", gap: 6, flexWrap: "wrap" }}>
                    {items.map(it => (
                      <button key={it.item_id} onClick={() => openQc(it)} disabled={busy}
                        style={{ padding: "6px 12px", border: "1px solid var(--line)", borderRadius: 999, background: "transparent", fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.18em", textTransform: "uppercase", cursor: "pointer", minHeight: 32 }}>
                        {lang === "en" ? "Open QC for " : "افتح مراجعة "}{it.maker_ref || it.sku}
                      </button>
                    ))}
                  </div>
                )}
              </div>
            ) : qc.map(q => (
              <div key={q.id} style={{ padding: 14, border: "1px solid var(--line-2)", borderRadius: 10, marginBottom: 8 }}>
                <div style={{ display: "flex", justifyContent: "space-between", flexWrap: "wrap", gap: 10, alignItems: "center" }}>
                  <AdminPill tone={q.status === "passed" ? "olive" : q.status === "failed" ? "terracotta" : "gold"}>{_enumLabel(QC_STATUS_LABEL, q.status, lang)}</AdminPill>
                  <span style={{ fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.18em", color: "var(--muted)" }}>
                    {window.fmtDate(q.created_at, lang)}
                  </span>
                </div>
                {q.notes_internal && <div style={{ marginTop: 8, fontSize: 13, color: "var(--olive)" }}>{q.notes_internal}</div>}
                {q.status === "pending" && (
                  <div style={{ marginTop: 10, display: "flex", gap: 6, flexWrap: "wrap" }}>
                    <button onClick={() => decideQc(q, "passed")} disabled={busy}
                      style={{ padding: "6px 14px", border: "1px solid var(--olive)", borderRadius: 999, background: "var(--olive)", color: "var(--paper)", fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.18em", textTransform: "uppercase", cursor: "pointer", minHeight: 32 }}>
                      {lang === "en" ? "Pass" : "اجتاز"}
                    </button>
                    <button onClick={() => decideQc(q, "revision_requested")} disabled={busy}
                      style={{ padding: "6px 14px", border: "1px solid var(--gold-soft)", borderRadius: 999, background: "transparent", color: "var(--ink)", fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.18em", textTransform: "uppercase", cursor: "pointer", minHeight: 32 }}>
                      {lang === "en" ? "Revision" : "تعديل"}
                    </button>
                    <button onClick={() => decideQc(q, "failed")} disabled={busy}
                      style={{ padding: "6px 14px", border: "1px solid var(--terracotta)", borderRadius: 999, background: "transparent", color: "var(--terracotta)", fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.18em", textTransform: "uppercase", cursor: "pointer", minHeight: 32 }}>
                      {lang === "en" ? "Fail" : "رفض"}
                    </button>
                  </div>
                )}
              </div>
            ))}
          </section>

          {/* ─── Operational timeline ─── */}
          <section>
            <div style={{ ...eyebrow, marginBottom: 10 }}>{lang === "en" ? "Timeline" : "السجلّ"}</div>
            {events.length === 0 ? (
              <div style={{ padding: 14, background: "var(--paper-2)", borderRadius: 10, fontSize: 13, color: "var(--muted)" }}>
                {lang === "en" ? "No events yet." : "لا توجد أحداث."}
              </div>
            ) : (
              <ol style={{ listStyle: "none", padding: 0, margin: 0 }}>
                {events.map((e, i) => (
                  <li key={e.id} style={{ display: "grid", gridTemplateColumns: "12px 1fr", gap: 12, padding: "10px 0", borderTop: i === 0 ? "none" : "1px solid var(--line-2)" }}>
                    <span aria-hidden="true" style={{
                      width: 8, height: 8, borderRadius: "50%",
                      background: e.public_visible ? "var(--terracotta)" : "var(--line)",
                      marginTop: 6, justifySelf: "start",
                    }} />
                    <div style={{ minWidth: 0 }}>
                      <div style={{ display: "flex", justifyContent: "space-between", gap: 10, flexWrap: "wrap" }}>
                        <span style={{ fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", textTransform: "uppercase", color: e.public_visible ? "var(--terracotta)" : "var(--muted)" }}>
                          {_timelineKindLabel(e.kind, lang)}
                        </span>
                        <span style={{ fontFamily: "var(--ff-mono)", fontSize: 9, color: "var(--muted)", letterSpacing: "0.18em" }}>
                          {window.fmtDateTime(e.occurred_at, lang)}
                        </span>
                      </div>
                      {(e.label_en || e.internal_note) && (
                        <div style={{ marginTop: 4, fontSize: 13, lineHeight: 1.5 }}>
                          {e.public_visible ? (e.label_en || "") : null}
                          {e.internal_note && (
                            <span style={{ color: "var(--olive)", fontStyle: "italic" }}>
                              {e.public_visible && e.label_en ? " · " : ""}{e.internal_note}
                            </span>
                          )}
                        </div>
                      )}
                    </div>
                  </li>
                ))}
              </ol>
            )}
          </section>

          {/* ─── Notifications log ─── */}
          {notifications.length > 0 && (
            <section>
              <div style={{ ...eyebrow, marginBottom: 10 }}>{lang === "en" ? "Notifications" : "الإشعارات"}</div>
              <div style={{ border: "1px solid var(--line-2)", borderRadius: 10, overflow: "hidden" }}>
                {notifications.map((n, i) => (
                  <div key={n.id} style={{ padding: "10px 14px", borderTop: i === 0 ? "none" : "1px solid var(--line-2)", display: "grid", gridTemplateColumns: "70px 1fr auto", gap: 10, alignItems: "center", fontSize: 12 }}>
                    <span style={{ fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.2em", textTransform: "uppercase", color: "var(--muted)" }}>{window.notifChannelLabel(n.channel, lang)}</span>
                    <span style={{ fontSize: 12 }}>{window.notifTemplateLabel(n.template_key, lang)}</span>
                    <AdminPill tone={n.status === "sent" ? "olive" : n.status === "failed" ? "terracotta" : "gold"}>{_enumLabel(NOTIF_STATUS_LABEL, n.status, lang)}</AdminPill>
                  </div>
                ))}
              </div>
            </section>
          )}

          {/* ─── Internal admin note ─── */}
          <section style={{ padding: 14, background: "var(--paper-2)", borderRadius: 10 }}>
            <label htmlFor="ops-admin-note" style={{ ...eyebrow }}>
              {lang === "en" ? "Internal note (admin only)" : "ملاحظة داخليّة"}
            </label>
            <textarea id="ops-admin-note" rows={2}
              value={adminNote}
              onChange={e => setAdminNote(e.target.value)}
              placeholder={lang === "en" ? "Operational note for the audit trail…" : "ملاحظة للسجلّ…"}
              style={{ marginTop: 6, width: "100%", padding: "8px 12px", border: "1px solid var(--line)", borderRadius: 8, background: "var(--paper)", fontFamily: "var(--ff-sans)", fontSize: 13, outline: 0, boxSizing: "border-box", resize: "vertical" }} />
            <button onClick={submitNote} disabled={noteBusy || !adminNote.trim()} className="btn ghost"
              style={{ marginTop: 8, padding: "8px 14px", fontSize: 11, minHeight: 36, opacity: (noteBusy || !adminNote.trim()) ? 0.5 : 1 }}>
              {noteBusy ? "…" : (lang === "en" ? "Add to timeline" : "أضف للسجلّ")}
            </button>
          </section>

          {/* Global order status flow */}
          {order && STATUS_NEXT[order.status] && (
            <section style={{ padding: 16, background: "var(--paper-2)", borderRadius: 10, display: "flex", justifyContent: "space-between", alignItems: "center", gap: 14 }}>
              <div>
                <div style={eyebrow}>{lang === "en" ? "Order lifecycle" : "دورة الطلب"}</div>
                <div style={{ marginTop: 4, fontSize: 13 }}>
                  {lang === "en" ? "Advance to" : "تقدّم إلى"}{" "}
                  <strong>{_orderStatusLabel(STATUS_NEXT[order.status], lang)}</strong>
                </div>
              </div>
              <button onClick={advanceOrder} disabled={statusBusy} className="btn" style={{ opacity: statusBusy ? 0.5 : 1 }}>
                {statusBusy ? "…" : `→ ${_orderStatusLabel(STATUS_NEXT[order.status], lang)}`}
              </button>
            </section>
          )}
        </div>
      </aside>
    </>
  );
}

// OR-1 / F23 — tabs grouped over the REAL order-status enum set. Compound
// statuses (e.g. pending_confirmation) are collapsed into a sensible bucket so
// every order falls under a tab; the filter matches the raw lowercase status.
const ORDER_TAB_GROUPS = {
  pending:   ["pending", "pending_confirmation"],
  confirmed: ["confirmed", "in_preparation"],
  ready:     ["ready_for_dispatch", "packed"],
  shipped:   ["shipped", "out_for_delivery"],
  delivered: ["delivered"],
  returned:  ["returned", "refunded", "return_requested", "return_received"],
  cancelled: ["cancelled"],
};
const ORDER_TABS = [
  { k: "all",       en: "All",            ar: "الكل" },
  { k: "pending",   en: "Pending",        ar: "قيد الانتظار" },
  { k: "confirmed", en: "In preparation", ar: "قيد التحضير" },
  { k: "ready",     en: "Ready / packed", ar: "جاهز · مُعبَّأ" },
  { k: "shipped",   en: "Shipped",        ar: "مشحون" },
  { k: "delivered", en: "Delivered",      ar: "تمّ التسليم" },
  { k: "returned",  en: "Returned",       ar: "مُرتجَع" },
  { k: "cancelled", en: "Cancelled",      ar: "ملغى" },
];

function AdminOrdersPage({ lang }) {
  const orders = window.ADMIN_ORDERS;
  const [tab, setTab] = React.useState("all");
  const [activeOrder, setActiveOrder] = React.useState(null);
  const filt = tab === "all"
    ? orders
    : orders.filter(o => (ORDER_TAB_GROUPS[tab] || [tab]).includes(String(o.status || "").toLowerCase()));

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 18 }}>
      <div style={{ display: "flex", gap: 6, padding: 4, background: "var(--paper-2)", borderRadius: 999, alignSelf: "flex-start", flexWrap: "wrap" }}>
        {ORDER_TABS.map(f => (
          <button key={f.k} onClick={() => setTab(f.k)} style={{
            padding: "6px 14px", borderRadius: 999, border: 0,
            background: tab === f.k ? "var(--ink)" : "transparent",
            color: tab === f.k ? "var(--paper)" : "var(--ink)", fontSize: 12, cursor: "pointer",
          }}>{f[lang] || f.en}</button>
        ))}
      </div>
      {/* RESP-1 — 9-col grid would crush below the 980px sidebar breakpoint; the
          inner overflow-x wrapper + minWidth keeps columns legible (scroll) on
          768–980px tablets instead of compressing them. */}
      <div style={{ border: "1px solid var(--line-2)", borderRadius: 14, overflow: "hidden", background: "var(--paper)" }}>
        <div style={{ overflowX: "auto" }}>
          <div style={{ minWidth: 880 }}>
            <div className="adm-tbl-h" style={{
              display: "grid", gridTemplateColumns: "1.1fr 1fr 1.4fr 0.7fr 0.5fr 0.7fr 0.7fr 0.8fr 70px",
              padding: "14px 22px", background: "var(--paper-2)",
              fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--muted)",
            }}>
              <div>{lang === "en" ? "Order" : "الطلب"}</div>
              <div>{lang === "en" ? "Buyer" : "المشتري"}</div>
              <div>{lang === "en" ? "Maker" : "الصانع"}</div>
              <div>{lang === "en" ? "Code" : "الرمز"}</div>
              <div>{lang === "en" ? "Qty" : "الكمية"}</div>
              <div>{lang === "en" ? "Total" : "الإجمالي"}</div>
              <div>{lang === "en" ? "Date" : "التاريخ"}</div>
              <div>{lang === "en" ? "Status" : "الحالة"}</div>
              <div></div>
            </div>
            {filt.length === 0 && (
              <div style={{ padding: "60px 20px", textAlign: "center", color: "var(--muted)", fontSize: 14 }}>{lang === "en" ? "No orders match this filter." : "لا توجد طلبات."}</div>
            )}
            {filt.map((o, i) => (
              <div key={o.id} className="adm-tbl-row" onClick={() => setActiveOrder(o)} style={{
                display: "grid", gridTemplateColumns: "1.1fr 1fr 1.4fr 0.7fr 0.5fr 0.7fr 0.7fr 0.8fr 70px",
                padding: "14px 22px", borderTop: "1px solid var(--line-2)", alignItems: "center", fontSize: 13,
                cursor: "pointer",
              }}>
                <div style={{ fontFamily: "var(--ff-mono)", fontSize: 11 }}>{o.id}</div>
                <div>{o.buyer}<div style={{ fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.18em", color: "var(--muted)" }}>{o.city}</div></div>
                <div style={{ minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{o.makerName}</div>
                <div style={{ fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.18em", color: "var(--ink)" }}>{o.makerCodeDisplay}</div>
                <div>{window.adminNum(o.qty, lang)}</div>
                <div style={{ fontFamily: "var(--ff-display)" }}>{window.adminNum(o.total, lang)} <span style={{ fontFamily: "var(--ff-mono)", fontSize: 9, color: "var(--muted)" }}>EGP</span></div>
                <div style={{ fontFamily: "var(--ff-mono)", fontSize: 10, color: "var(--muted)" }}>{window.fmtDate(o.date, lang, { day: "numeric", month: "short" })}</div>
                <AdminPill tone={_orderStatusTone(o.status)}>{_orderStatusLabel(o.status, lang)}</AdminPill>
                <div style={{ fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.2em", color: "var(--terracotta)", textAlign: "right" }}>→</div>
              </div>
            ))}
          </div>
        </div>
      </div>
      <AdminOrderDrawer
        orderRow={activeOrder}
        onClose={() => setActiveOrder(null)}
        lang={lang}
        onChanged={() => window.loadAdminData && window.loadAdminData()}
      />
    </div>
  );
}

// ————————— RETURNS —————————
const RETURN_STATUS_LABEL = {
  requested:     { en: "Requested",       ar: "مطلوب",       tone: "gold" },
  approved:      { en: "Approved · awaiting pickup", ar: "موافَق · استلام",  tone: "olive" },
  rejected:      { en: "Rejected",        ar: "مرفوض",       tone: "terracotta" },
  received:      { en: "Received",        ar: "استُلمت",     tone: "olive" },
  refunded:      { en: "Refunded",        ar: "مستردّ",      tone: "olive" },
  refund_failed: { en: "Refund failed",   ar: "فشل الاسترداد", tone: "terracotta" },
  cancelled:     { en: "Cancelled",       ar: "ملغى",        tone: "muted" },
};

const REASON_LABEL = {
  damaged:          { en: "Arrived damaged",     ar: "وصلت تالفة" },
  not_as_described: { en: "Not as described",    ar: "لا تطابق الوصف" },
  wrong_item:       { en: "Wrong item",          ar: "قطعة خاطئة" },
  changed_mind:     { en: "Changed mind (14d)",  ar: "غيّر رأيه" },
  other:            { en: "Other",               ar: "آخر" },
};

function _returnActions(status) {
  // Mirror admin_decide_return's allowed-transitions matrix.
  switch (status) {
    case "requested": return ["approved", "rejected", "cancelled"];
    case "approved":  return ["received", "cancelled"];
    case "received":  return ["refunded", "refund_failed", "cancelled"];
    case "refund_failed": return ["refunded", "cancelled"];
    default: return [];
  }
}

function AdminReturnsPage({ lang }) {
  const [rows, setRows] = React.useState(null);
  const [filter, setFilter] = React.useState("open"); // open | all | closed
  const [busy, setBusy] = React.useState(null);
  const [note, setNote] = React.useState({});
  const [refundEdit, setRefundEdit] = React.useState({});

  const load = React.useCallback(() => {
    window.sb.rpc("admin_returns_list", { p_limit: 200 }).then(({ data, error }) => {
      if (error) { console.warn("returns load:", error.message); setRows([]); return; }
      setRows(data || []);
    });
  }, []);
  React.useEffect(load, [load]);

  const decide = async (r, decision) => {
    setBusy(r.id);
    const refund = decision === "refunded" ? (refundEdit[r.id] ?? Math.round((r.order_total_piastres || 0))) : null;
    const { error } = await window.sb.rpc("admin_decide_return", {
      p_return_id: r.id,
      p_decision: decision,
      p_admin_note: note[r.id] || null,
      p_refund_piastres: refund,
    });
    setBusy(null);
    if (error) { alert(error.message); return; }
    setNote(n => ({ ...n, [r.id]: "" }));
    load();
    if (window.loadAdminData) window.loadAdminData();
  };

  if (rows === null) return <div style={{ padding: 40, color: "var(--muted)", fontFamily: "var(--ff-mono)", fontSize: 11, letterSpacing: "0.2em", textTransform: "uppercase" }}>{lang === "en" ? "Loading…" : "تحميل…"}</div>;

  const openSet = new Set(["requested","approved","received","refund_failed"]);
  const filtered = rows.filter(r =>
    filter === "all" ? true :
    filter === "open" ? openSet.has(r.status) :
    !openSet.has(r.status)
  );

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 18 }}>
      <div style={{ display: "flex", gap: 6, padding: 4, background: "var(--paper-2)", borderRadius: 999, alignSelf: "flex-start", flexWrap: "wrap" }}>
        {[
          { k: "open",   l: lang === "en" ? "Open" : "مفتوح",   c: rows.filter(r => openSet.has(r.status)).length },
          { k: "all",    l: lang === "en" ? "All" : "الكل",    c: rows.length },
          { k: "closed", l: lang === "en" ? "Closed" : "مغلق", c: rows.filter(r => !openSet.has(r.status)).length },
        ].map(f => (
          <button key={f.k} onClick={() => setFilter(f.k)} style={{
            padding: "6px 14px", borderRadius: 999, border: 0,
            background: filter === f.k ? "var(--ink)" : "transparent",
            color: filter === f.k ? "var(--paper)" : "var(--ink)", fontSize: 12, cursor: "pointer",
          }}>{f.l} <span style={{ fontFamily: "var(--ff-mono)", fontSize: 10, opacity: 0.6, marginLeft: 6 }}>({f.c})</span></button>
        ))}
      </div>

      {filtered.length === 0 ? (
        <div style={{ padding: "60px 20px", textAlign: "center", border: "1px dashed var(--line)", borderRadius: 14 }}>
          <div style={{ fontFamily: "var(--ff-display)", fontSize: 24 }}>{lang === "en" ? "No returns in this view." : "لا توجد مرتجعات."}</div>
          <div style={{ marginTop: 6, fontSize: 13, color: "var(--muted)" }}>
            {lang === "en" ? "When a customer requests a return from their account, it appears here." : "تظهر هنا عند طلب العميل."}
          </div>
        </div>
      ) : filtered.map(r => {
        const sl = RETURN_STATUS_LABEL[r.status] || { en: r.status, ar: r.status, tone: "muted" };
        const rl = REASON_LABEL[r.reason_code] || { en: r.reason_code, ar: r.reason_code };
        const actions = _returnActions(r.status);
        return (
          <div key={r.id} style={{ padding: "20px 22px", border: "1px solid var(--line-2)", borderRadius: 14, background: "var(--paper)" }}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 14, flexWrap: "wrap" }}>
              <div style={{ minWidth: 0, flex: 1 }}>
                <div style={{ display: "flex", gap: 10, flexWrap: "wrap", alignItems: "center" }}>
                  <span style={{ fontFamily: "var(--ff-mono)", fontSize: 11, letterSpacing: "0.2em", color: "var(--terracotta)" }}>{r.order_number}</span>
                  <AdminPill tone={sl.tone}>{sl[lang] || sl.en}</AdminPill>
                  <span style={{ fontFamily: "var(--ff-mono)", fontSize: 9, color: "var(--muted)", letterSpacing: "0.18em" }}>
                    {window.fmtDate(r.created_at, lang, { day: "numeric", month: "short" })}
                  </span>
                </div>
                <div style={{ marginTop: 8, fontFamily: "var(--ff-display)", fontSize: 22 }}>{r.customer_name}</div>
                <div style={{ marginTop: 2, fontFamily: "var(--ff-mono)", fontSize: 10, color: "var(--muted)", letterSpacing: "0.18em" }}>{r.customer_email}</div>
                <div style={{ marginTop: 10, fontSize: 13, lineHeight: 1.55 }}>
                  <strong style={{ color: "var(--terracotta)" }}>{rl[lang] || rl.en}</strong>
                  {r.reason_text ? ` · ${r.reason_text}` : ""}
                </div>
              </div>
              <div style={{ textAlign: "right" }}>
                <div style={{ fontFamily: "var(--ff-display)", fontSize: 20 }}>
                  {window.adminNum(Math.round((r.order_total_piastres || 0) / 100), lang)} <span style={{ fontFamily: "var(--ff-mono)", fontSize: 10, color: "var(--muted)" }}>EGP</span>
                </div>
                {r.refund_piastres != null && (
                  <div style={{ fontFamily: "var(--ff-mono)", fontSize: 10, color: "var(--olive)", letterSpacing: "0.18em" }}>
                    {lang === "en" ? "refund " : "ردّ "}{window.adminNum(Math.round(r.refund_piastres / 100), lang)} EGP
                  </div>
                )}
              </div>
            </div>

            {actions.length > 0 && (
              <div style={{ marginTop: 16, padding: 14, background: "var(--paper-2)", borderRadius: 10 }}>
                <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10, marginBottom: 12 }}>
                  <div>
                    <label htmlFor={`note-${r.id}`} style={{ fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", color: "var(--muted)", textTransform: "uppercase" }}>
                      {lang === "en" ? "Internal admin note" : "ملاحظة داخلية"}
                    </label>
                    <input id={`note-${r.id}`}
                      value={note[r.id] || ""}
                      onChange={e => setNote(n => ({ ...n, [r.id]: e.target.value }))}
                      placeholder={r.admin_note || (lang === "en" ? "Optional" : "اختياري")}
                      style={{ marginTop: 4, width: "100%", padding: "8px 12px", border: "1px solid var(--line)", borderRadius: 8, background: "var(--paper)", fontSize: 13, minHeight: 36, boxSizing: "border-box" }} />
                  </div>
                  <div>
                    <label htmlFor={`refund-${r.id}`} style={{ fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", color: "var(--muted)", textTransform: "uppercase" }}>
                      {lang === "en" ? "Refund (EGP)" : "مبلغ الاسترداد"}
                    </label>
                    <input id={`refund-${r.id}`}
                      type="number" min="0"
                      value={refundEdit[r.id] != null
                        ? Math.round(refundEdit[r.id] / 100)
                        : Math.round((r.refund_piastres ?? r.order_total_piastres ?? 0) / 100)}
                      onChange={e => setRefundEdit(re => ({ ...re, [r.id]: Math.max(0, Number(e.target.value)) * 100 }))}
                      style={{ marginTop: 4, width: "100%", padding: "8px 12px", border: "1px solid var(--line)", borderRadius: 8, background: "var(--paper)", fontSize: 13, minHeight: 36, boxSizing: "border-box" }} />
                  </div>
                </div>
                <div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
                  {actions.map(a => {
                    const isPrimary = a === "approved" || a === "received" || a === "refunded";
                    const isDanger = a === "rejected" || a === "cancelled" || a === "refund_failed";
                    return (
                      <button
                        key={a}
                        onClick={() => decide(r, a)}
                        disabled={busy === r.id}
                        aria-label={`Mark ${a}`}
                        style={{
                          padding: "8px 16px",
                          borderRadius: 999,
                          border: isDanger ? "1px solid var(--terracotta)" : "1px solid var(--line)",
                          background: isPrimary ? "var(--olive)" : "transparent",
                          color: isPrimary ? "var(--paper)" : (isDanger ? "var(--terracotta)" : "var(--ink)"),
                          fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.18em", textTransform: "uppercase",
                          cursor: busy === r.id ? "wait" : "pointer",
                          opacity: busy === r.id ? 0.5 : 1,
                          minHeight: 36,
                        }}
                      >
                        {RETURN_STATUS_LABEL[a]?.[lang] || RETURN_STATUS_LABEL[a]?.en || a}
                      </button>
                    );
                  })}
                </div>
              </div>
            )}

            {r.admin_note && actions.length === 0 && (
              <div style={{ marginTop: 12, padding: "10px 14px", background: "var(--paper-2)", borderRadius: 8, fontSize: 12, color: "var(--olive)" }}>
                <span style={{ fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", color: "var(--muted)", textTransform: "uppercase", marginRight: 8 }}>
                  {lang === "en" ? "Admin note" : "ملاحظة"}
                </span>
                {r.admin_note}
              </div>
            )}
          </div>
        );
      })}
    </div>
  );
}

// ————————— CUSTOMERS —————————
function AdminCustomersPage({ lang }) {
  const cs = window.ADMIN_CUSTOMERS || [];
  if (cs.length === 0) return (
    <div style={{ padding: "60px 20px", textAlign: "center", border: "1px dashed var(--line)", borderRadius: 14 }}>
      <div style={{ fontFamily: "var(--ff-display)", fontSize: 22 }}>{lang === "en" ? "No customers yet." : "لا يوجد عملاء."}</div>
      <div style={{ marginTop: 6, fontSize: 13, color: "var(--muted)" }}>{lang === "en" ? "Customers appear here after they place their first order." : "يظهر العملاء بعد طلبهم الأول."}</div>
    </div>
  );
  return (
    <div style={{ border: "1px solid var(--line-2)", borderRadius: 14, overflow: "hidden", background: "var(--paper)" }}>
      {/* RESP-1 — keep the 6-col table from crushing on 768–980px tablets. */}
      <div style={{ overflowX: "auto" }}>
        <div style={{ minWidth: 720 }}>
          <div className="adm-tbl-h" style={{
            display: "grid", gridTemplateColumns: "1.5fr 1fr 0.6fr 1fr 0.8fr 1fr",
            padding: "14px 22px", background: "var(--paper-2)",
            fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--muted)",
          }}>
            <div>{lang === "en" ? "Customer" : "العميل"}</div>
            <div>{lang === "en" ? "City" : "المدينة"}</div>
            <div>{lang === "en" ? "Orders" : "الطلبات"}</div>
            <div>{lang === "en" ? "Lifetime" : "إجمالي الإنفاق"}</div>
            <div>{lang === "en" ? "Tier" : "الفئة"}</div>
            <div>{lang === "en" ? "Joined" : "انضمّ"}</div>
          </div>
          {cs.map((c, i) => (
            <div key={i} className="adm-tbl-row" style={{
              display: "grid", gridTemplateColumns: "1.5fr 1fr 0.6fr 1fr 0.8fr 1fr",
              padding: "14px 22px", borderTop: "1px solid var(--line-2)", alignItems: "center", fontSize: 13,
            }}>
              <div>
                <div style={{ fontFamily: "var(--ff-display)", fontSize: 16 }}>{c.name}</div>
                <div style={{ fontFamily: "var(--ff-mono)", fontSize: 10, color: "var(--muted)" }}>{c.email}</div>
              </div>
              <div>{c.city}</div>
              <div style={{ fontFamily: "var(--ff-display)" }}>{window.adminNum(c.orders, lang)}</div>
              <div style={{ fontFamily: "var(--ff-display)" }}>{window.adminNum(c.lifetime, lang)} <span style={{ fontFamily: "var(--ff-mono)", fontSize: 10, color: "var(--muted)" }}>EGP</span></div>
              <AdminPill tone={c.tier === "VIP" ? "gold" : c.tier === "Returning" ? "olive" : "muted"}>
                {lang === "en" ? c.tier : (c.tier === "VIP" ? "مميّز" : c.tier === "Returning" ? "عائد" : "جديد")}
              </AdminPill>
              <div style={{ fontFamily: "var(--ff-mono)", fontSize: 10, color: "var(--muted)" }}>{window.fmtDate(c.joined, lang, { day: "numeric", month: "short" })}</div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

// ————————— FINANCE —————————
function AdminFinancePage({ lang }) {
  const f = window.ADMIN_FINANCE;
  const monthly = f.monthly || [];
  const payouts = f.payouts || [];
  // Guard: Math.max(...[]) is -Infinity, which makes every bar height NaN.
  const max = monthly.length ? Math.max(...monthly.map(m => m.gmv || 0)) : 0;
  // Dynamic payout cycle label — the next month to run, not a hardcoded "May".
  const nextCycle = (() => {
    try {
      const d = new Date(); d.setDate(1);
      return d.toLocaleDateString(lang === "ar" ? "ar-EG" : "en-GB", { month: "long" });
    } catch { return ""; }
  })();
  // Fees are REAL per-maker commission (not a flat 18%), so the blended rate is
  // derived from the actual YTD totals rather than hardcoded "18% / 82%".
  const feePct    = f.ytdGmv > 0 ? Math.round((f.ytdFees / f.ytdGmv) * 100) : 0;
  const payoutPct = f.ytdGmv > 0 ? 100 - feePct : 0;
  // Localize the percent digits in Arabic (e.g. "١٧٪").
  const arNum = (n) => Number(n).toLocaleString("ar-EG");
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 26 }}>
      <div className="adm-grid-4">
        {[
          { l: lang === "en" ? "GMV · YTD" : `إجمالي · ${new Date().getFullYear().toLocaleString("ar-EG", { useGrouping: false })}`, v: window.adminThousandsK(f.ytdGmv, lang), sub: "EGP", c: "var(--terracotta)" },
          { l: lang === "en" ? "Platform fees" : "رسوم المنصّة", v: window.adminThousandsK(f.ytdFees, lang), sub: lang === "en" ? `${feePct}% blended` : `${arNum(feePct)}٪ مُجمَّع`, c: "var(--gold)" },
          { l: lang === "en" ? "Maker payouts" : "صرفيّات الصنّاع", v: window.adminThousandsK(f.ytdPayouts, lang), sub: lang === "en" ? `${payoutPct}% to makers` : `${arNum(payoutPct)}٪ للصنّاع`, c: "var(--olive)" },
          { l: lang === "en" ? "Refunds & returns" : "استرجاعات", v: window.adminThousandsK(f.ytdReturns, lang, 1), sub: lang === "en" ? `${f.returnRate}% rate` : `معدّل ${arNum(f.returnRate)}٪`, c: "var(--ink)" },
        ].map((s, i) => (
          <div key={i} style={{ padding: "22px 24px", borderRadius: 14, background: "var(--paper)", border: "1px solid var(--line-2)", borderLeft: `3px solid ${s.c}` }}>
            <div style={{ fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--muted)" }}>{s.l}</div>
            <div style={{ marginTop: 10, fontFamily: "var(--ff-display)", fontSize: 36 }}>{s.v}</div>
            <div style={{ marginTop: 4, fontSize: 12, color: "var(--muted)" }}>{s.sub}</div>
          </div>
        ))}
      </div>

      <div style={{ padding: 26, border: "1px solid var(--line-2)", borderRadius: 14, background: "var(--paper)" }}>
        <h3 style={{ fontFamily: "var(--ff-display)", fontSize: 22, marginBottom: 18 }}>{lang === "en" ? "GMV · monthly" : "الإجمالي · شهريًّا"}</h3>
        {monthly.length === 0 || max === 0 ? (
          <div style={{ padding: "40px 20px", textAlign: "center", border: "1px dashed var(--line-2)", borderRadius: 12, color: "var(--muted)" }}>
            <div style={{ fontFamily: "var(--ff-display)", fontSize: 20, color: "var(--ink)" }}>{lang === "en" ? "No data yet." : "لا توجد بيانات بعد."}</div>
            <div style={{ marginTop: 6, fontSize: 13 }}>{lang === "en" ? "Monthly GMV appears here once orders are placed." : "يظهر الإجمالي الشهري بعد أول الطلبات."}</div>
          </div>
        ) : (
          <div style={{ display: "flex", alignItems: "flex-end", gap: 14, height: 200 }}>
            {monthly.map((m, i) => (
              <div key={i} style={{ flex: 1, display: "flex", flexDirection: "column", alignItems: "center", gap: 6 }}>
                <div style={{ fontFamily: "var(--ff-mono)", fontSize: 9, color: "var(--muted)" }}>{window.adminThousandsK(m.gmv || 0, lang)}</div>
                {/* Highlight the CURRENT calendar month (the RPC returns all 12,
                    so "last index" would mark empty December, not this month). */}
                <div style={{ width: "100%", height: Math.max(2, ((m.gmv || 0) / max) * 150), borderRadius: "6px 6px 0 0", background: (m.d && m.d.getMonth() === new Date().getMonth() && m.d.getFullYear() === new Date().getFullYear()) ? "var(--terracotta)" : "var(--ink)" }} />
                <div style={{ fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.18em", textTransform: "uppercase", color: "var(--muted)" }}>{m.d ? window.fmtDate(m.d, lang, { month: "short" }) : m.m}</div>
              </div>
            ))}
          </div>
        )}
      </div>

      <div>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 12, gap: 12, flexWrap: "wrap" }}>
          <h3 style={{ fontFamily: "var(--ff-display)", fontSize: 22 }}>{lang === "en" ? "Pending payouts" : "صرفيّات معلّقة"}</h3>
          {/* Payouts run on a monthly cron (payouts_run_cycle Edge Function),
              gated by a server-only secret. The admin UI cannot — and must not —
              trigger it directly, so this is an honest static note, not a button. */}
          <div style={{ display: "inline-flex", alignItems: "center", gap: 8, padding: "8px 14px", border: "1px dashed var(--line-2)", borderRadius: 999, color: "var(--muted)" }}>
            <span style={{ display: "inline-flex", color: "var(--gold)" }}><Icon name="calendar" size={15} /></span>
            <span style={{ fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.18em", textTransform: "uppercase" }}>
              {lang === "en" ? `${nextCycle} cycle runs on the monthly cron` : `دورة ${nextCycle} تُصرف آليًّا شهريًّا`}
            </span>
          </div>
        </div>
        {payouts.length === 0 ? (
          <div style={{ padding: "40px 20px", textAlign: "center", border: "1px dashed var(--line-2)", borderRadius: 14, background: "var(--paper)" }}>
            <div style={{ fontFamily: "var(--ff-display)", fontSize: 20 }}>{lang === "en" ? "No payouts pending." : "لا توجد صرفيّات معلّقة."}</div>
            <div style={{ marginTop: 6, fontSize: 13, color: "var(--muted)" }}>{lang === "en" ? "Maker payouts appear here when an order settles." : "تظهر الصرفيّات هنا عند تسوية الطلبات."}</div>
          </div>
        ) : (
          // RESP-1 — 6-col payouts table; scroll on tablet rather than crush.
          <div style={{ border: "1px solid var(--line-2)", borderRadius: 14, overflow: "hidden", background: "var(--paper)" }}>
           <div style={{ overflowX: "auto" }}>
            <div style={{ minWidth: 760 }}>
            <div className="adm-tbl-h" style={{ display: "grid", gridTemplateColumns: "1.5fr 1fr 1fr 1fr 1fr 0.8fr", padding: "14px 22px", background: "var(--paper-2)", fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--muted)" }}>
              <div>{lang === "en" ? "Maker" : "الصانع"}</div>
              <div>{lang === "en" ? "Period" : "الفترة"}</div>
              <div>{lang === "en" ? "Gross" : "الإجمالي"}</div>
              <div>{lang === "en" ? "Split" : "حصّة الصانع"}</div>
              <div>{lang === "en" ? "Bank" : "البنك"}</div>
              <div>{lang === "en" ? "Status" : "الحالة"}</div>
            </div>
            {payouts.map((p, i) => (
              <div key={i} className="adm-tbl-row" style={{ display: "grid", gridTemplateColumns: "1.5fr 1fr 1fr 1fr 1fr 0.8fr", padding: "14px 22px", borderTop: "1px solid var(--line-2)", alignItems: "center", fontSize: 13 }}>
                <div>{p.maker}</div>
                <div>{window.fmtDate(p.period, lang, { month: "short", year: "numeric" })}</div>
                <div>{window.adminNum(p.gross || 0, lang)} <span style={{ fontFamily: "var(--ff-mono)", fontSize: 9, color: "var(--muted)" }}>EGP</span></div>
                <div style={{ fontFamily: "var(--ff-display)", color: "var(--olive)" }}>{window.adminNum(p.split || 0, lang)} <span style={{ fontFamily: "var(--ff-mono)", fontSize: 9, color: "var(--muted)" }}>EGP</span></div>
                <div style={{ fontFamily: "var(--ff-mono)", fontSize: 11 }}>{p.bank}</div>
                <AdminPill tone={p.status === "Paid" ? "olive" : "gold"}>
                  {lang === "en" ? p.status : (p.status === "Paid" ? "مدفوع" : "معلّق")}
                </AdminPill>
              </div>
            ))}
            </div>
           </div>
          </div>
        )}
      </div>
    </div>
  );
}

// ————————— AUDIT LOG —————————
function AdminAuditPage({ lang }) {
  const log = window.ADMIN_AUDIT;
  return (
    <div style={{ border: "1px solid var(--line-2)", borderRadius: 14, overflow: "hidden", background: "var(--paper)" }}>
      {log.map((e, i) => {
        const m = _auditMeta(e.kind);
        return (
          <div key={i} style={{ display: "grid", gridTemplateColumns: "44px 1fr auto auto", gap: 14, padding: "16px 22px", borderTop: i === 0 ? "none" : "1px solid var(--line-2)", alignItems: "center" }}>
            <div style={{ width: 32, height: 32, borderRadius: "50%", background: "var(--paper-2)", color: m.color, display: "grid", placeItems: "center" }}><Icon name={m.icon} size={16} /></div>
            <div style={{ fontSize: 14 }}><strong style={{ fontWeight: 500 }}>{e.actor}</strong> {window.auditActionLabel(e.action, lang)}</div>
            <div style={{ fontFamily: "var(--ff-mono)", fontSize: 10, color: "var(--muted)" }} className="adm-hide-mobile">{e.ip}</div>
            <div style={{ fontFamily: "var(--ff-mono)", fontSize: 10, color: "var(--muted)" }}>{window.fmtAge(e.age, lang)}</div>
          </div>
        );
      })}
    </div>
  );
}

// ————————— TEAM —————————
function AdminTeamPage({ lang }) {
  const team = window.ADMIN_TEAM || [];
  const [busy, setBusy] = React.useState(null);

  const setRole = async (t, role) => {
    if (!t.id) return;
    const roleLabel = { admin: lang === "en" ? "admin" : "إداري", superadmin: lang === "en" ? "owner" : "مالك", customer: lang === "en" ? "customer (remove)" : "عميل (إزالة)" }[role] || role;
    if (!confirm(lang === "en" ? `Set ${t.name}'s role to ${roleLabel}?` : `تعيين دور ${t.name} إلى ${roleLabel}؟`)) return;
    setBusy(t.id);
    const { error } = await window.sb.from("profiles").update({ role }).eq("id", t.id);
    setBusy(null);
    if (error) { alert(error.message); return; }
    if (window.loadAdminData) window.loadAdminData();
  };

  if (team.length === 0) {
    return (
      <div style={{ padding: "60px 20px", textAlign: "center", border: "1px dashed var(--line)", borderRadius: 14 }}>
        <div style={{ fontFamily: "var(--ff-display)", fontSize: 22 }}>{lang === "en" ? "No admin members yet." : "لا يوجد إداريّون."}</div>
        <div style={{ marginTop: 6, fontSize: 13, color: "var(--muted)" }}>{lang === "en" ? "Promote a profile to 'admin' or 'superadmin' role to add team members." : "ارفع حسابًا لدور إداري لإضافته."}</div>
      </div>
    );
  }

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 18 }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", flexWrap: "wrap", gap: 10 }}>
        <div style={{ fontSize: 13, color: "var(--muted)" }}>{lang === "en" ? `${team.length} admin seat${team.length === 1 ? "" : "s"}. Access is granted by role.` : `${team.length} مقعد إداري. الصلاحيات بحسب الدور.`}</div>
      </div>
      <div className="adm-grid-2">
        {team.map((t) => (
          <div key={t.id} style={{ padding: 22, border: "1px solid var(--line-2)", borderRadius: 14, background: "var(--paper)", display: "flex", gap: 16, alignItems: "center" }}>
            <div style={{ width: 56, height: 56, borderRadius: "50%", background: "var(--paper-2)", display: "grid", placeItems: "center", fontFamily: "var(--ff-display)", fontSize: 22, color: "var(--ink)", border: "1px solid var(--line-2)" }}>
              {t.name[0].toUpperCase()}
            </div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontFamily: "var(--ff-display)", fontSize: 20 }}>{t.name}</div>
              <div style={{ fontSize: 12, color: "var(--muted)" }}>{t.email}</div>
              <div style={{ marginTop: 6, display: "flex", gap: 6, flexWrap: "wrap" }}>
                <AdminPill tone={t.role === "Owner" ? "ink" : "olive"}>
                  {lang === "en" ? t.role : (t.role === "Owner" ? "المالك" : "مراجِع")}
                </AdminPill>
              </div>
            </div>
            <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
              <button onClick={() => setRole(t, t.role === "Owner" ? "admin" : "superadmin")} disabled={busy === t.id} style={{ padding: "5px 12px", borderRadius: 999, border: "1px solid var(--line)", background: "transparent", fontSize: 10, cursor: "pointer", textTransform: "uppercase", letterSpacing: "0.18em" }}>
                {busy === t.id ? "…" : (t.role === "Owner" ? (lang === "en" ? "Demote" : "تخفيض") : (lang === "en" ? "Promote owner" : "ترقية"))}
              </button>
              <button onClick={() => setRole(t, "customer")} disabled={busy === t.id} style={{ padding: "5px 12px", borderRadius: 999, border: "1px solid var(--terracotta)", background: "transparent", color: "var(--terracotta)", fontSize: 10, cursor: "pointer", textTransform: "uppercase", letterSpacing: "0.18em" }}>
                {lang === "en" ? "Remove" : "إزالة"}
              </button>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

// ————————— SETTINGS —————————
function AdminSettingsPage({ lang }) {
  const [settings, setSettings] = React.useState(null);
  const [form, setForm] = React.useState({ contact_email: "", contact_phone: "", announcement_en: "", announcement_ar: "", egp_per_usd: "" });
  const [saving, setSaving] = React.useState(false);
  const [msg, setMsg] = React.useState("");
  const [saveOk, setSaveOk] = React.useState(false);

  React.useEffect(() => {
    window.sb.from("site_settings").select("*").eq("id", 1).single()
      .then(({ data }) => {
        setSettings(data || null);
        if (data) {
          setForm({
            contact_email: data.contact_email || "",
            contact_phone: data.contact_phone || "",
            announcement_en: data.announcement_en || "",
            announcement_ar: data.announcement_ar || "",
            egp_per_usd: data.egp_per_usd ?? "",
          });
        }
      });
  }, []);

  const save = async (e) => {
    e.preventDefault();
    setSaving(true); setMsg(""); setSaveOk(false);
    const payload = {
      id: 1,
      contact_email: form.contact_email || null,
      contact_phone: form.contact_phone || null,
      announcement_en: form.announcement_en || null,
      announcement_ar: form.announcement_ar || null,
      egp_per_usd: form.egp_per_usd === "" ? null : Number(form.egp_per_usd),
    };
    const { error } = settings
      ? await window.sb.from("site_settings").update(payload).eq("id", 1)
      : await window.sb.from("site_settings").insert(payload);
    setSaving(false);
    // ST-2 — track success with an explicit boolean, not by sniffing the
    // localized message text.
    if (error) { setSaveOk(false); setMsg(error.message); return; }
    setSaveOk(true);
    setMsg(lang === "en" ? "Saved." : "تمّ الحفظ.");
    setTimeout(() => { setMsg(""); setSaveOk(false); }, 2500);
  };

  const inp = { display: "block", width: "100%", marginTop: 6, padding: "11px 14px", border: "1px solid var(--line)", borderRadius: 10, background: "var(--paper)", fontFamily: "var(--ff-sans)", fontSize: 14, outline: 0, boxSizing: "border-box" };
  const lbl = { fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--muted)" };

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 20 }}>
      {/* Editable site settings */}
      <form onSubmit={save} style={{ border: "1px solid var(--line-2)", borderRadius: 14, overflow: "hidden", background: "var(--paper)" }}>
        <div style={{ padding: "14px 22px", background: "var(--paper-2)", fontFamily: "var(--ff-mono)", fontSize: 11, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--muted)" }}>
          {lang === "en" ? "Site settings" : "إعدادات الموقع"}
        </div>
        <div style={{ padding: 22, display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16 }}>
          <div><label style={lbl}>{lang === "en" ? "Contact email" : "بريد التواصل"}</label><input type="email" value={form.contact_email} onChange={e => setForm(f => ({ ...f, contact_email: e.target.value }))} placeholder="hello@sanaa.eg" style={inp} /></div>
          <div><label style={lbl}>{lang === "en" ? "Contact phone" : "هاتف التواصل"}</label><input value={form.contact_phone} onChange={e => setForm(f => ({ ...f, contact_phone: e.target.value }))} placeholder="+20..." style={inp} /></div>
          <div style={{ gridColumn: "span 2" }}><label style={lbl}>{lang === "en" ? "Top-bar announcement (English)" : "إعلان شريط العنوان"}</label><input value={form.announcement_en} onChange={e => setForm(f => ({ ...f, announcement_en: e.target.value }))} style={inp} /></div>
          <div style={{ gridColumn: "span 2" }}><label style={lbl}>{lang === "en" ? "Top-bar announcement (Arabic)" : "إعلان (عربي)"}</label><input value={form.announcement_ar} onChange={e => setForm(f => ({ ...f, announcement_ar: e.target.value }))} dir="rtl" style={inp} /></div>
          <div><label style={lbl}>{lang === "en" ? "EGP per USD" : "ج.م لكل دولار"}</label><input type="number" step="0.0001" value={form.egp_per_usd} onChange={e => setForm(f => ({ ...f, egp_per_usd: e.target.value }))} placeholder="48.5" style={inp} /></div>
          <div style={{ gridColumn: "span 2", display: "flex", gap: 12, alignItems: "center" }}>
            <button type="submit" disabled={saving} className="btn" style={{ opacity: saving ? 0.6 : 1 }}>{saving ? "…" : (lang === "en" ? "Save settings" : "احفظ")} →</button>
            {msg && <span style={{ fontSize: 13, color: saveOk ? "var(--olive)" : "var(--terracotta)" }}>{msg}</span>}
          </div>
        </div>
      </form>

      {/* Read-only operational rules */}
      <div style={{ border: "1px solid var(--line-2)", borderRadius: 14, overflow: "hidden", background: "var(--paper)" }}>
        <div style={{ padding: "14px 22px", background: "var(--paper-2)", fontFamily: "var(--ff-mono)", fontSize: 11, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--muted)" }}>
          {lang === "en" ? "Operational rules (read-only)" : "قواعد العمليات"}
        </div>
        {[
          [lang === "en" ? "Approval — new piece" : "موافقة قطعة جديدة", lang === "en" ? "Always required" : "مطلوبة دائمًا"],
          [lang === "en" ? "Approval — price/stock change" : "موافقة سعر/مخزون", lang === "en" ? "Always required" : "مطلوبة دائمًا"],
          [lang === "en" ? "Approval — profile/payout change" : "موافقة الملف", lang === "en" ? "Always required" : "مطلوبة دائمًا"],
          [lang === "en" ? "Default commission" : "العمولة الافتراضية", lang === "en" ? "18% — set individually per maker" : "١٨٪ — تُضبط لكل صانع على حدة"],
          [lang === "en" ? "Free shipping threshold" : "حد الشحن المجاني", lang === "en" ? "EGP 1,800" : "١٬٨٠٠ ج.م"],
          [lang === "en" ? "Activity log" : "سجل النشاط", lang === "en" ? "Every admin action is recorded; 365-day retention" : "تُسجَّل كل إجراءات الإدارة؛ تُحفظ ٣٦٥ يومًا"],
          [lang === "en" ? "Account roles" : "أدوار الحسابات", lang === "en" ? "Customer · Maker · Admin · Owner" : "عميل · صانع · إداري · مالك"],
        ].map(([k, v], j) => (
          <div key={j} style={{ display: "grid", gridTemplateColumns: "minmax(0,1fr) minmax(0,1.2fr)", gap: 16, padding: "14px 22px", borderTop: "1px solid var(--line-2)", alignItems: "center" }}>
            <div style={{ fontSize: 13, color: "var(--muted)" }}>{k}</div>
            <div style={{ fontSize: 13 }}>{v}</div>
          </div>
        ))}
      </div>
    </div>
  );
}

// ————————— WORKSHOPS — operations console with attendee drawer —————————
function AdminWorkshopsPage({ lang }) {
  const [list, setList] = React.useState(window.ADMIN_WORKSHOPS || []);
  const [busy, setBusy] = React.useState(null);
  const [filter, setFilter] = React.useState("all");
  const [drawerFor, setDrawerFor] = React.useState(null);

  React.useEffect(() => { setList(window.ADMIN_WORKSHOPS || []); }, [window.ADMIN_WORKSHOPS]);

  const transitionTo = async (w, status) => {
    setBusy(w.id);
    const { error } = await window.sb.rpc("workshop_set_status", { p_workshop_id: w.id, p_status: status });
    setBusy(null);
    if (error) { alert(error.message); return; }
    if (window.loadAdminData) window.loadAdminData();
  };

  const filtered = React.useMemo(() => {
    if (filter === "all") return list;
    if (filter === "upcoming") return list.filter(w => w.starts_at && new Date(w.starts_at) > new Date() && !["cancelled","archived"].includes(w.status_key));
    if (filter === "past") return list.filter(w => w.starts_at && new Date(w.starts_at) < new Date());
    if (filter === "draft") return list.filter(w => w.status_key === "draft");
    if (filter === "live") return list.filter(w => w.status_key === "published" || w.status_key === "fully_booked");
    return list;
  }, [list, filter]);

  const totals = React.useMemo(() => {
    const upcoming = list.filter(w => w.starts_at && new Date(w.starts_at) > new Date() && !["cancelled","archived"].includes(w.status_key));
    const totalSeats = upcoming.reduce((s, w) => s + (w.seats_total || 0), 0);
    const takenSeats = upcoming.reduce((s, w) => s + (w.seats_taken || 0), 0);
    const totalRev = upcoming.reduce((s, w) => s + (w.rev || 0), 0);
    return {
      count: upcoming.length,
      occupancy: totalSeats > 0 ? Math.round(100 * takenSeats / totalSeats) : 0,
      revenue: totalRev,
    };
  }, [list]);

  if (list.length === 0) {
    return (
      <div style={{ padding: "60px 20px", textAlign: "center", border: "1px dashed var(--line)", borderRadius: 14 }}>
        <div style={{ fontFamily: "var(--ff-display)", fontSize: 22 }}>{lang === "en" ? "No workshops yet." : "لا توجد ورش بعد."}</div>
        <div style={{ marginTop: 6, fontSize: 13, color: "var(--muted)" }}>{lang === "en" ? "Drafts submitted by makers will appear here for approval." : "ستظهر مسودّات الصنّاع هنا."}</div>
      </div>
    );
  }

  return (
    <>
      {/* Operational summary cards */}
      <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 16, marginBottom: 22 }}>
        <div style={{ padding: 18, background: "var(--paper)", border: "1px solid var(--line-2)", borderRadius: 14 }}>
          <div style={{ fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--muted)" }}>{lang === "en" ? "Upcoming" : "القادمة"}</div>
          <div style={{ fontFamily: "var(--ff-display)", fontSize: 40, marginTop: 6 }}>{window.adminNum(totals.count, lang)}</div>
        </div>
        <div style={{ padding: 18, background: "var(--paper)", border: "1px solid var(--line-2)", borderRadius: 14 }}>
          <div style={{ fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--muted)" }}>{lang === "en" ? "Seat occupancy" : "إشغال المقاعد"}</div>
          <div style={{ fontFamily: "var(--ff-display)", fontSize: 40, marginTop: 6 }}>{window.adminNum(totals.occupancy, lang)}%</div>
        </div>
        <div style={{ padding: 18, background: "var(--paper)", border: "1px solid var(--line-2)", borderRadius: 14 }}>
          <div style={{ fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--muted)" }}>{lang === "en" ? "Pipeline (EGP)" : "المتوقّع (ج.م)"}</div>
          <div style={{ fontFamily: "var(--ff-display)", fontSize: 40, marginTop: 6 }}>{window.adminNum(totals.revenue, lang)}</div>
        </div>
      </div>

      <div style={{ display: "flex", gap: 8, marginBottom: 14, flexWrap: "wrap" }}>
        {[
          ["all", lang === "en" ? "All" : "الكل", list.length],
          ["upcoming", lang === "en" ? "Upcoming" : "القادمة", list.filter(w => w.starts_at && new Date(w.starts_at) > new Date() && !["cancelled","archived"].includes(w.status_key)).length],
          ["live", lang === "en" ? "Live" : "منشورة", list.filter(w => w.status_key === "published" || w.status_key === "fully_booked").length],
          ["draft", lang === "en" ? "Draft" : "مسوّدة", list.filter(w => w.status_key === "draft").length],
          ["past", lang === "en" ? "Past" : "ماضية", list.filter(w => w.starts_at && new Date(w.starts_at) < new Date()).length],
        ].map(([k, label, c]) => (
          <button key={k} onClick={() => setFilter(k)} style={{
            padding: "6px 14px", border: "1px solid var(--line)", borderRadius: 999,
            background: filter === k ? "var(--ink)" : "transparent",
            color: filter === k ? "var(--paper)" : "var(--ink)",
            fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.2em", cursor: "pointer", textTransform: "uppercase",
          }}>{label} <span style={{ opacity: 0.6, marginLeft: 6 }}>({window.adminNum(c, lang)})</span></button>
        ))}
      </div>

      {/* RESP-1 — 7-col table with a fixed 140px action column; scroll on tablet. */}
      <div style={{ border: "1px solid var(--line-2)", borderRadius: 14, overflow: "hidden", background: "var(--paper)" }}>
       <div style={{ overflowX: "auto" }}>
        <div style={{ minWidth: 880 }}>
        <div className="adm-tbl-h" style={{ display: "grid", gridTemplateColumns: "1.6fr 1fr 1fr 0.9fr 0.7fr 0.9fr 140px", padding: "14px 22px", background: "var(--paper-2)", fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--muted)" }}>
          <div>{lang === "en" ? "Workshop" : "الورشة"}</div>
          <div>{lang === "en" ? "Host" : "المضيف"}</div>
          <div>{lang === "en" ? "Date" : "التاريخ"}</div>
          <div>{lang === "en" ? "Occupancy" : "الإشغال"}</div>
          <div>{lang === "en" ? "Revenue" : "الإيراد"}</div>
          <div>{lang === "en" ? "Status" : "الحالة"}</div>
          <div></div>
        </div>
        {filtered.map((x) => (
          <div key={x.id} className="adm-tbl-row" style={{ display: "grid", gridTemplateColumns: "1.6fr 1fr 1fr 0.9fr 0.7fr 0.9fr 140px", padding: "14px 22px", borderTop: "1px solid var(--line-2)", alignItems: "center", fontSize: 13 }}>
            <div>
              <div style={{ fontFamily: "var(--ff-display)", fontSize: 16 }}>{x.t}</div>
              {x.title_ar && <div className="ar" style={{ fontSize: 12, color: "var(--terracotta)" }}>{x.title_ar}</div>}
            </div>
            <div>{x.host}{x.host_code ? <span style={{ fontFamily: "var(--ff-mono)", fontSize: 9, color: "var(--muted)", marginLeft: 6 }}>· {x.host_code}</span> : null}</div>
            <div style={{ fontFamily: "var(--ff-mono)", fontSize: 11, color: "var(--muted)" }}>{window.fmtDate(x.date, lang, { weekday: "short", day: "numeric", month: "short" })}</div>
            <div>
              <div style={{ fontSize: 13 }}>{x.seats}</div>
              <div style={{ marginTop: 4, height: 3, background: "var(--paper-2)", borderRadius: 999, overflow: "hidden" }}>
                <div style={{ width: `${x.occupancy_pct}%`, height: "100%", background: x.occupancy_pct >= 100 ? "var(--terracotta)" : "var(--olive)" }} />
              </div>
            </div>
            <div style={{ fontFamily: "var(--ff-display)" }}>{window.adminNum(x.rev, lang)} <span style={{ fontFamily: "var(--ff-mono)", fontSize: 9, color: "var(--muted)" }}>EGP</span></div>
            <div>
              <AdminPill tone={
                x.status_key === "published" ? "olive"
                : x.status_key === "fully_booked" ? "gold"
                : x.status_key === "cancelled" ? "terracotta"
                : x.status_key === "archived" ? "muted"
                : "gold"
              }>{_workshopStatusLabel(x.status_key, x.status, lang)}</AdminPill>
            </div>
            <div style={{ display: "flex", flexDirection: "column", gap: 5, alignItems: "flex-end" }}>
              <button onClick={() => setDrawerFor(x)} style={{ background: "transparent", border: "1px solid var(--line)", padding: "4px 10px", borderRadius: 999, fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.2em", cursor: "pointer", color: "var(--ink)", textTransform: "uppercase" }}>
                {lang === "en" ? "Attendees →" : "الحضور →"}
              </button>
              {x.status_key === "draft" && (
                <button disabled={busy === x.id} onClick={() => transitionTo(x, "published")} style={{ background: "var(--olive)", color: "var(--paper)", border: 0, padding: "4px 10px", borderRadius: 999, fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.2em", cursor: "pointer", textTransform: "uppercase", opacity: busy === x.id ? 0.5 : 1 }}>
                  {lang === "en" ? "Publish" : "نشر"}
                </button>
              )}
              {(x.status_key === "published" || x.status_key === "fully_booked") && (
                <button disabled={busy === x.id} onClick={() => transitionTo(x, "draft")} style={{ background: "transparent", border: "1px solid var(--line)", padding: "4px 10px", borderRadius: 999, fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.2em", cursor: "pointer", color: "var(--muted)", textTransform: "uppercase" }}>
                  {lang === "en" ? "Unpublish" : "إخفاء"}
                </button>
              )}
              {x.status_key !== "cancelled" && x.status_key !== "archived" && x.starts_at && new Date(x.starts_at) > new Date() && (
                <button
                  disabled={busy === x.id}
                  onClick={() => {
                    if (!confirm(lang === "en"
                      ? `Cancel workshop "${x.t}"? All active bookings will be cancelled and refund-eligibility evaluated.`
                      : `إلغاء ورشة «${x.t}»؟ ستُلغى كل الحجوزات النشطة وتُقيَّم أحقّية الاسترداد.`)) return;
                    transitionTo(x, "cancelled");
                  }}
                  style={{ background: "transparent", border: "1px solid var(--line)", padding: "4px 10px", borderRadius: 999, fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.2em", cursor: "pointer", color: "var(--terracotta)", textTransform: "uppercase" }}>
                  {lang === "en" ? "Cancel" : "إلغاء"}
                </button>
              )}
            </div>
          </div>
        ))}
        </div>
       </div>
      </div>

      <AdminWorkshopAttendeeDrawer
        workshop={drawerFor}
        open={!!drawerFor}
        onClose={() => setDrawerFor(null)}
        lang={lang}
      />
    </>
  );
}

// Attendee roster drawer — admin view: cancel any booking, mark attendance,
// export to CSV.
function AdminWorkshopAttendeeDrawer({ workshop, open, onClose, lang }) {
  const [bookings, setBookings] = React.useState([]);
  const [loading, setLoading] = React.useState(false);
  const [busy, setBusy] = React.useState(null);

  const load = React.useCallback(() => {
    if (!workshop) return;
    setLoading(true);
    window.sb.from("workshop_bookings")
      .select("id, booking_ref, status, seats, total_piastres, waitlist_position, guest_name, guest_email, guest_phone, notes_customer, placed_at, refund_status, profiles:user_id(full_name, email, phone)")
      .eq("workshop_id", workshop.id)
      .order("placed_at", { ascending: true })
      .then(({ data }) => { setBookings(data || []); setLoading(false); });
  }, [workshop]);

  React.useEffect(() => { if (open) load(); }, [open, load]);

  if (!open || !workshop) return null;

  const markAttendance = async (b, attended) => {
    setBusy(b.id);
    const { error } = await window.sb.rpc("workshop_mark_attendance", { p_booking_id: b.id, p_attended: attended });
    setBusy(null);
    if (error) { alert(error.message); return; }
    load();
  };
  const cancelBooking = async (b) => {
    if (!confirm(lang === "en"
      ? `Cancel ${b.booking_ref}? Refund will follow the workshop's policy.`
      : `إلغاء ${b.booking_ref}؟ سيتبع الاسترداد سياسة الورشة.`)) return;
    setBusy(b.id);
    const { error } = await window.sb.rpc("workshop_cancel_booking", { p_booking_id: b.id, p_reason: "admin_cancellation", p_actor_role: "admin" });
    setBusy(null);
    if (error) { alert(error.message); return; }
    load();
  };
  const exportCsv = () => {
    const rows = [["ref","name","email","phone","status","seats","total_egp","waitlist","placed_at"]];
    for (const b of bookings) {
      rows.push([
        b.booking_ref || "",
        (b.profiles?.full_name || b.guest_name || "").replace(/,/g, " "),
        b.profiles?.email || b.guest_email || "",
        b.profiles?.phone || b.guest_phone || "",
        b.status,
        b.seats,
        Math.round((b.total_piastres || 0) / 100),
        b.waitlist_position || "",
        b.placed_at,
      ]);
    }
    const csv = rows.map(r => r.map(x => `"${String(x).replace(/"/g, '""')}"`).join(",")).join("\n");
    const blob = new Blob([csv], { type: "text/csv;charset=utf-8" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url; a.download = `workshop-${workshop.slug || workshop.id}-attendees.csv`;
    a.click(); URL.revokeObjectURL(url);
  };

  return (
    <div onClick={onClose} style={{ position: "fixed", inset: 0, background: "rgba(28,26,21,0.6)", zIndex: 9000, display: "flex", justifyContent: "flex-end" }}>
      <div onClick={e => e.stopPropagation()} style={{ background: "var(--paper)", width: 720, maxWidth: "100%", height: "100%", overflowY: "auto", padding: 32 }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline" }}>
          <div>
            <div style={{ fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.22em", color: "var(--muted)", textTransform: "uppercase" }}>{window.fmtDate(workshop.date, lang, { weekday: "short", day: "numeric", month: "short" })} · {workshop.host}</div>
            <h2 style={{ fontFamily: "var(--ff-display)", fontSize: 32, marginTop: 6 }}>{workshop.t}</h2>
          </div>
          <button onClick={onClose} style={{ background: "transparent", border: 0, fontSize: 24, cursor: "pointer", color: "var(--muted)" }}>×</button>
        </div>

        <div style={{ marginTop: 16, padding: 14, background: "var(--paper-2)", borderRadius: 10, display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 12 }}>
          {[
            [lang === "en" ? "Seats" : "المقاعد", `${workshop.seats_taken} / ${workshop.seats_total}`],
            [lang === "en" ? "Occupancy" : "الإشغال", `${workshop.occupancy_pct}%`],
            [lang === "en" ? "Confirmed" : "مؤكَّد", bookings.filter(b => b.status === "confirmed" || b.status === "attended").length],
            [lang === "en" ? "Waitlist" : "قائمة الانتظار", bookings.filter(b => b.status === "waitlisted").length],
          ].map(([k, v]) => (
            <div key={k}>
              <div style={{ fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", color: "var(--muted)", textTransform: "uppercase" }}>{k}</div>
              <div style={{ fontFamily: "var(--ff-display)", fontSize: 20, marginTop: 2 }}>{v}</div>
            </div>
          ))}
        </div>

        <div style={{ marginTop: 18, display: "flex", justifyContent: "space-between", alignItems: "center" }}>
          <div style={{ fontFamily: "var(--ff-display)", fontSize: 18 }}>{lang === "en" ? "Attendees" : "الحضور"}</div>
          <button onClick={exportCsv} style={{ background: "transparent", border: "1px solid var(--line)", padding: "5px 12px", borderRadius: 999, fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", cursor: "pointer", textTransform: "uppercase" }}>
            {lang === "en" ? "Export CSV" : "تصدير CSV"}
          </button>
        </div>

        {loading && <div style={{ padding: 40, textAlign: "center", color: "var(--muted)", fontFamily: "var(--ff-mono)", fontSize: 12 }}>{lang === "en" ? "Loading…" : "تحميل…"}</div>}
        {!loading && bookings.length === 0 && (
          <div style={{ padding: 40, textAlign: "center", color: "var(--muted)" }}>{lang === "en" ? "No bookings yet." : "لا توجد حجوزات بعد."}</div>
        )}
        <div style={{ marginTop: 12 }}>
          {bookings.map(b => {
            const name = b.profiles?.full_name || b.guest_name || "—";
            const email = b.profiles?.email || b.guest_email || "—";
            const phone = b.profiles?.phone || b.guest_phone || "—";
            const isActive = ["pending","pending_payment","confirmed","waitlisted"].includes(b.status);
            return (
              <div key={b.id} style={{ padding: "14px 0", borderTop: "1px solid var(--line-2)" }}>
                <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", gap: 14 }}>
                  <div style={{ flex: 1 }}>
                    <div style={{ fontFamily: "var(--ff-display)", fontSize: 17 }}>{name}</div>
                    <div style={{ fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.18em", color: "var(--muted)", marginTop: 2 }}>
                      {b.booking_ref} · {email} · {phone}
                    </div>
                    {b.notes_customer && <div style={{ marginTop: 6, fontSize: 12, fontStyle: "italic", color: "var(--olive)" }}>"{b.notes_customer}"</div>}
                  </div>
                  <div style={{ textAlign: "right", display: "flex", flexDirection: "column", gap: 4, alignItems: "flex-end" }}>
                    <AdminPill tone={
                      b.status === "confirmed" ? "olive"
                      : b.status === "attended" ? "olive"
                      : b.status === "waitlisted" ? "gold"
                      : b.status === "no_show" ? "terracotta"
                      : b.status === "cancelled" ? "muted"
                      : "gold"
                    }>{_enumLabel(BOOKING_STATUS_LABEL, b.status, lang)}</AdminPill>
                    <div style={{ fontFamily: "var(--ff-mono)", fontSize: 10, color: "var(--muted)" }}>
                      {b.seats} {lang === "en" ? (b.seats === 1 ? "seat" : "seats") : "مقعد"} · {Math.round((b.total_piastres || 0) / 100)} EGP
                      {b.waitlist_position ? ` · #${b.waitlist_position}` : ""}
                    </div>
                  </div>
                </div>
                {isActive && (
                  <div style={{ marginTop: 8, display: "flex", gap: 8, justifyContent: "flex-end" }}>
                    {b.status === "confirmed" && (
                      <>
                        <button disabled={busy === b.id} onClick={() => markAttendance(b, true)} style={{ background: "var(--olive)", color: "var(--paper)", border: 0, padding: "5px 12px", borderRadius: 999, fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.2em", cursor: "pointer", textTransform: "uppercase", opacity: busy === b.id ? 0.5 : 1 }}>
                          {lang === "en" ? "Attended" : "حضر"}
                        </button>
                        <button disabled={busy === b.id} onClick={() => markAttendance(b, false)} style={{ background: "transparent", border: "1px solid var(--line)", padding: "5px 12px", borderRadius: 999, fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.2em", cursor: "pointer", color: "var(--terracotta)", textTransform: "uppercase" }}>
                          {lang === "en" ? "No-show" : "لم يحضر"}
                        </button>
                      </>
                    )}
                    <button disabled={busy === b.id} onClick={() => cancelBooking(b)} style={{ background: "transparent", border: "1px solid var(--line)", padding: "5px 12px", borderRadius: 999, fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.2em", cursor: "pointer", color: "var(--muted)", textTransform: "uppercase" }}>
                      {lang === "en" ? "Cancel" : "إلغاء"}
                    </button>
                  </div>
                )}
                {b.refund_status && (
                  <div style={{ marginTop: 6, fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.18em", color: "var(--muted)", textTransform: "uppercase", textAlign: "right" }}>
                    {lang === "en" ? "Refund" : "استرداد"} · {_enumLabel(REFUND_STATUS_LABEL, b.refund_status, lang)}
                  </div>
                )}
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
}

// ————————— CONTENT — live journal_posts —————————
function AdminContentPage({ lang }) {
  const [list, setList] = React.useState(window.ADMIN_CONTENT || []);
  const [busy, setBusy] = React.useState(null);
  React.useEffect(() => { setList(window.ADMIN_CONTENT || []); }, [window.ADMIN_CONTENT]);

  const togglePublish = async (p) => {
    setBusy(p.id);
    const isPub = p.status === "Published";
    const { error } = await window.sb.from("journal_posts").update({ is_published: !isPub, published_at: isPub ? null : new Date().toISOString() }).eq("id", p.id);
    setBusy(null);
    if (error) { alert(error.message); return; }
    if (window.loadAdminData) window.loadAdminData();
  };

  if (list.length === 0) {
    return (
      <div style={{ padding: "60px 20px", textAlign: "center", border: "1px dashed var(--line)", borderRadius: 14 }}>
        <div style={{ fontFamily: "var(--ff-display)", fontSize: 22 }}>{lang === "en" ? "No journal articles yet." : "لا توجد مقالات بعد."}</div>
        <div style={{ marginTop: 6, fontSize: 13, color: "var(--muted)" }}>{lang === "en" ? "Editorial content is managed in the journal." : "يُدار المحتوى التحريري من اليوميّات."}</div>
      </div>
    );
  }
  return (
    <div style={{ border: "1px solid var(--line-2)", borderRadius: 14, overflow: "hidden", background: "var(--paper)" }}>
      <div className="adm-tbl-h" style={{ display: "grid", gridTemplateColumns: "0.6fr 2fr 1.1fr 0.8fr 0.7fr 110px", padding: "14px 22px", background: "var(--paper-2)", fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--muted)" }}>
        <div>{lang === "en" ? "Type" : "النوع"}</div>
        <div>{lang === "en" ? "Title" : "العنوان"}</div>
        <div>{lang === "en" ? "Author" : "الكاتب"}</div>
        <div>{lang === "en" ? "Date" : "التاريخ"}</div>
        <div>{lang === "en" ? "Status" : "الحالة"}</div>
        <div></div>
      </div>
      {list.map((x, i) => (
        <div key={x.id} className="adm-tbl-row" style={{ display: "grid", gridTemplateColumns: "0.6fr 2fr 1.1fr 0.8fr 0.7fr 110px", padding: "14px 22px", borderTop: "1px solid var(--line-2)", alignItems: "center", fontSize: 13 }}>
          <div style={{ fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--muted)" }}>{x.kind === "Article" ? (lang === "en" ? "Article" : "مقال") : x.kind}</div>
          <div style={{ fontFamily: "var(--ff-display)", fontSize: 16 }}>{x.title}</div>
          <div>{x.author}</div>
          <div style={{ fontFamily: "var(--ff-mono)", fontSize: 11, color: "var(--muted)" }}>{window.fmtDate(x.date, lang, { day: "numeric", month: "short" })}</div>
          <AdminPill tone={x.status === "Published" ? "olive" : x.status === "Review" ? "gold" : "muted"}>
            {lang === "en" ? x.status : (x.status === "Published" ? "منشور" : x.status === "Review" ? "مراجعة" : "مسوّدة")}
          </AdminPill>
          <button onClick={() => togglePublish(x)} disabled={busy === x.id} style={{ padding: "5px 12px", borderRadius: 999, border: "1px solid var(--line)", background: x.status === "Published" ? "transparent" : "var(--olive)", color: x.status === "Published" ? "var(--ink)" : "var(--paper)", fontSize: 11, cursor: "pointer", opacity: busy === x.id ? 0.5 : 1 }}>
            {busy === x.id ? "…" : (x.status === "Published" ? (lang === "en" ? "Unpublish" : "إخفاء") : (lang === "en" ? "Publish" : "نشر"))}
          </button>
        </div>
      ))}
    </div>
  );
}

Object.assign(window, { OverviewPage, ApplicationsPage, ApplicationDrawer, AdminMakersPage, AdminPiecesPage, AdminPiecesImagesPage, AdminOrdersPage, AdminReturnsPage, AdminCustomersPage, AdminFinancePage, AdminAuditPage, AdminTeamPage, AdminSettingsPage, AdminWorkshopsPage, AdminContentPage });
