/* Maker Admin Dashboard — fully data-driven from Supabase. */

// Locale-aware numeric/currency formatter. Arabic shows Arabic-Indic digits
// (ar-EG) to match the date formatting already used across the dashboard, so
// money/stats never render Latin digits next to Arabic-Indic dates.
const fmtNum = (n, lang) => Number(n || 0).toLocaleString(lang === "ar" ? "ar-EG" : "en-US");

// Tiny viewport-width hook so we can swap dense tables for stacked cards on
// phones without touching styles.css. Returns the current innerWidth.
function useWidth() {
  const [w, setW] = React.useState(typeof window !== "undefined" ? window.innerWidth : 1200);
  React.useEffect(() => {
    const onResize = () => setW(window.innerWidth);
    window.addEventListener("resize", onResize);
    return () => window.removeEventListener("resize", onResize);
  }, []);
  return w;
}

// Quality (rubric) score as a small on-brand arc gauge. 270° sweep, gold→olive
// fill, ink value in the centre. Reads as a score with scale rather than a
// bare number. score may be null (renders an empty track + em-dash).
function RubricGauge({ score, size = 86, lang }) {
  const r = (size - 12) / 2;
  const cx = size / 2, cy = size / 2;
  const start = 135;            // degrees, sweep 270° clockwise
  const sweep = 270;
  const pct = score == null ? 0 : Math.max(0, Math.min(100, score)) / 100;
  const toXY = (deg) => {
    const a = (deg - 90) * Math.PI / 180;
    return [cx + r * Math.cos(a), cy + r * Math.sin(a)];
  };
  const arcPath = (fromDeg, toDeg) => {
    const [x1, y1] = toXY(fromDeg);
    const [x2, y2] = toXY(toDeg);
    const large = (toDeg - fromDeg) % 360 > 180 ? 1 : 0;
    return `M ${x1} ${y1} A ${r} ${r} 0 ${large} 1 ${x2} ${y2}`;
  };
  const valColor = score == null ? "var(--muted)" : score >= 80 ? "var(--olive)" : "var(--gold)";
  return (
    <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`} role="img"
      aria-label={lang === "en" ? `Quality score ${score == null ? "not set" : score + " out of 100"}` : `معيار الجودة ${score == null ? "غير محدّد" : score + " من ١٠٠"}`}>
      <path d={arcPath(start, start + sweep)} fill="none" stroke="var(--line)" strokeWidth="7" strokeLinecap="round" />
      {pct > 0 && (
        <path d={arcPath(start, start + sweep * pct)} fill="none" stroke={valColor} strokeWidth="7" strokeLinecap="round" />
      )}
      <text x={cx} y={cy + 1} textAnchor="middle" dominantBaseline="central"
        style={{ fontFamily: "var(--ff-display)", fontSize: size * 0.34, fill: "var(--ink)" }}>
        {score == null ? "—" : fmtNum(score, lang)}
      </text>
      <text x={cx} y={cy + size * 0.22} textAnchor="middle" dominantBaseline="central"
        style={{ fontFamily: "var(--ff-mono)", fontSize: size * 0.1, letterSpacing: "0.12em", fill: "var(--muted)" }}>
        {lang === "en" ? "/ 100" : "/ ١٠٠"}
      </text>
    </svg>
  );
}

function StatCard({ label, value, sub }) {
  return (
    <div style={{ padding: "22px 24px", border: "1px solid var(--line-2)", borderRadius: 14, background: "var(--paper)" }}>
      <div style={{ fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--muted)" }}>{label}</div>
      <div style={{ marginTop: 10, display: "flex", alignItems: "baseline", gap: 10 }}>
        <div style={{ fontFamily: "var(--ff-display)", fontSize: 38, lineHeight: 1 }}>{value}</div>
      </div>
      {sub && <div style={{ marginTop: 6, fontSize: 12, color: "var(--muted)" }}>{sub}</div>}
    </div>
  );
}

const OLIVE = { bg: "rgba(123,132,99,0.12)", fg: "var(--olive)" };
const GOLD = { bg: "rgba(212,170,97,0.18)", fg: "var(--gold)" };
const TERRA = { bg: "rgba(194,99,66,0.12)", fg: "var(--terracotta)" };
const MUTED = { bg: "var(--paper-2)", fg: "var(--muted)" };

const statusPill = (st) => {
  const map = {
    // pieces
    Live: OLIVE, Draft: MUTED, Review: GOLD, Archived: MUTED,
    // orders / fulfillment lifecycle
    Pending: GOLD, Confirmed: OLIVE, Paid: OLIVE, Packed: GOLD,
    Shipped: TERRA, Delivered: OLIVE, Cancelled: TERRA, Refunded: TERRA, Returned: TERRA,
    // payout cycle
    Approved: GOLD,
    // workshops
    Full: TERRA, "In progress": GOLD, Completed: OLIVE, Suspended: TERRA,
  };
  return map[st] || MUTED;
};

// Bilingual labels for every status string the maker dashboard renders, keyed by
// the capitalized order/piece/workshop status OR the lowercase booking status.
const STATUS_LABELS = {
  Live: { en: "Live", ar: "منشور" },
  Draft: { en: "Draft", ar: "مسوّدة" },
  Review: { en: "In review", ar: "قيد المراجعة" },
  Archived: { en: "Archived", ar: "مؤرشف" },
  Pending: { en: "Pending", ar: "قيد الانتظار" },
  Confirmed: { en: "Confirmed", ar: "مؤكَّد" },
  Approved: { en: "Approved", ar: "معتمَد" },
  Paid: { en: "Paid", ar: "مدفوع" },
  Packed: { en: "Packed", ar: "مُغلَّف" },
  Shipped: { en: "Shipped", ar: "مشحون" },
  Delivered: { en: "Delivered", ar: "تمّ التسليم" },
  Cancelled: { en: "Cancelled", ar: "مُلغى" },
  Refunded: { en: "Refunded", ar: "مُسترَد" },
  Returned: { en: "Returned", ar: "مُرتجَع" },
  Full: { en: "Full", ar: "مكتمل" },
  "In progress": { en: "In progress", ar: "قيد التنفيذ" },
  Completed: { en: "Completed", ar: "اكتمل" },
  Suspended: { en: "Suspended", ar: "موقوف" },
  // maker tiers (shown in the dashboard header pill)
  "Senior Master": { en: "Senior Master", ar: "أستاذ أوّل" },
  "Verified House": { en: "Verified House", ar: "بيت موثّق" },
  Emerging: { en: "Emerging", ar: "صاعد" },
  // workshop booking statuses (lowercase from the DB)
  confirmed: { en: "Confirmed", ar: "مؤكَّد" },
  waitlisted: { en: "Waitlisted", ar: "قائمة الانتظار" },
  attended: { en: "Attended", ar: "حضر" },
  "no_show": { en: "No-show", ar: "لم يحضر" },
  cancelled: { en: "Cancelled", ar: "مُلغى" },
};
const statusText = (st, lang) => (STATUS_LABELS[st] && STATUS_LABELS[st][lang === "ar" ? "ar" : "en"]) || st;

// When `children` is omitted, the pill localizes `st` itself.
function Pill({ children, st, lang }) {
  const c = statusPill(st);
  const label = children != null ? children : statusText(st, lang || "en");
  return <span style={{ padding: "4px 10px", borderRadius: 999, background: c.bg, color: c.fg, fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", textTransform: "uppercase" }}>{label}</span>;
}

// Generic, calm bilingual failure copy for the maker dashboard. The raw backend
// error is logged to the console (for debugging) but never shown to the maker.
function makerFail(lang, raw) {
  if (raw) console.warn("[maker]", raw);
  return lang === "en" ? "Something went wrong. Please try again." : "حدث خطأ ما. حاول مرّة أخرى.";
}

// ───── Skeleton blocks for loading states ─────────────────────────────
function Skeleton({ h = 16, w = "100%", r = 6 }) {
  return <div style={{ height: h, width: w, borderRadius: r, background: "linear-gradient(90deg, var(--paper-2) 0%, #e8dfcd 50%, var(--paper-2) 100%)", backgroundSize: "200% 100%", animation: "sk 1.5s linear infinite" }} />;
}
function StatSkeleton() {
  return (
    <div style={{ padding: "22px 24px", border: "1px solid var(--line-2)", borderRadius: 14, background: "var(--paper)" }}>
      <Skeleton h={10} w={120} />
      <div style={{ marginTop: 14 }}><Skeleton h={32} w={100} /></div>
      <div style={{ marginTop: 10 }}><Skeleton h={10} w={60} /></div>
    </div>
  );
}

// ───── Modal shell ────────────────────────────────────────────────────
function ModalShell({ open, onClose, children, width = 560 }) {
  // ESC closes; background scroll is locked while a modal is open.
  React.useEffect(() => {
    if (!open) 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);
    };
  }, [open, onClose]);

  if (!open) return null;
  return (
    <>
      <div onClick={onClose} style={{ position: "fixed", inset: 0, background: "rgba(28,26,21,0.6)", zIndex: 90 }} />
      <div role="dialog" aria-modal="true" style={{ position: "fixed", top: "50%", left: "50%", transform: "translate(-50%,-50%)", zIndex: 91, width, maxWidth: "96vw", maxHeight: "92vh", overflowY: "auto", background: "var(--paper)", borderRadius: 18, padding: "32px 32px 28px", boxShadow: "0 30px 80px -20px rgba(28,26,21,0.5)" }}>
        <button onClick={onClose} aria-label="Close" style={{ position: "absolute", top: 10, right: 14, 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>
        {children}
      </div>
    </>
  );
}

// ───── Upload New Piece — submits approval_request kind=piece.create ─
function NewPieceModal({ open, onClose, lang, makerId, userId, onSubmitted }) {
  const [cats, setCats] = React.useState([]);
  const [form, setForm] = React.useState({ name_en: "", name_ar: "", category_id: "", price: "", stock: 1, edition_size: "", description_en: "", description_ar: "", materials_en: "", materials_ar: "", dimensions_en: "", dimensions_ar: "" });
  const [status, setStatus] = React.useState("idle");
  const [err, setErr] = React.useState("");
  const set = (k) => (e) => setForm(f => ({ ...f, [k]: e.target.value }));

  React.useEffect(() => {
    if (!open) return;
    setStatus("idle"); setErr("");
    window.sb.from("categories").select("id, slug, name_en, name_ar").eq("is_active", true).order("position")
      .then(({ data }) => {
        setCats(data || []);
        if (data && data.length && !form.category_id) setForm(f => ({ ...f, category_id: data[0].id }));
      });
  }, [open]);

  const submit = async (e) => {
    e.preventDefault();
    if (!form.name_en || !form.name_ar || !form.category_id || !form.price) {
      setErr(lang === "en" ? "Name (both languages), category and price are required." : "الاسم (لغتين) والفئة والسعر مطلوبة.");
      return;
    }
    const priceNum = Number(form.price);
    if (!Number.isFinite(priceNum) || priceNum <= 0) { setErr(lang === "en" ? "Price must be a positive number." : "السعر يجب أن يكون رقمًا موجبًا."); return; }
    const stockNum = Number(form.stock) || 0;
    const ed = form.edition_size ? Number(form.edition_size) : null;

    // Generate sku/slug — admin can adjust on approval
    const baseSlug = form.name_en.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 60) || "piece";
    const suffix = Math.random().toString(36).slice(2, 6);
    const slug = `${baseSlug}-${suffix}`;
    const sku = `№${Math.floor(100 + Math.random() * 900)}`;

    setStatus("submitting"); setErr("");
    const { error } = await window.sb.from("approval_requests").insert({
      maker_id: makerId,
      requested_by: userId,
      kind: "piece.create",
      target_table: "products",
      target_id: null,
      diff_json: {
        new: {
          sku, slug,
          name_en: form.name_en,
          name_ar: form.name_ar,
          category_id: form.category_id,
          price_piastres: Math.round(priceNum * 100),
          stock: stockNum,
          edition_kind: ed ? "limited" : (stockNum === 1 ? "unique" : "open"),
          edition_size: ed,
          description_en: form.description_en || null,
          description_ar: form.description_ar || null,
          materials_en: form.materials_en || null,
          materials_ar: form.materials_ar || null,
          dimensions_en: form.dimensions_en || null,
          dimensions_ar: form.dimensions_ar || null,
        },
      },
      note: "New piece submitted by maker",
      priority: "normal",
    });
    if (error) { setErr(makerFail(lang, error.message)); setStatus("error"); return; }
    setStatus("done");
    if (onSubmitted) onSubmitted();
  };

  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, boxSizing: "border-box" };
  const lbl = { fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--muted)" };

  return (
    <ModalShell open={open} onClose={onClose} width={620}>
      {status === "done" ? (
        <div style={{ textAlign: "center", padding: "20px 0" }}>
          <Star8 size={32} color="var(--olive)" />
          <h2 style={{ fontFamily: "var(--ff-display)", fontSize: 36, marginTop: 16 }}>{lang === "en" ? "Sent for review" : "أُرسلت للمراجعة"}</h2>
          <p style={{ marginTop: 10, color: "var(--olive)" }}>
            {lang === "en" ? "Your new piece is in the approval queue. We'll notify you once it's reviewed." : "قطعتك الجديدة في طابور المراجعة."}
          </p>
          <button className="btn" onClick={onClose} style={{ marginTop: 20 }}>{lang === "en" ? "Done" : "تمام"}</button>
        </div>
      ) : (
        <form onSubmit={submit}>
          <h2 style={{ fontFamily: "var(--ff-display)", fontSize: 32, marginBottom: 6 }}>{lang === "en" ? "New piece" : "قطعة جديدة"}</h2>
          <p style={{ fontSize: 13, color: "var(--olive)", marginBottom: 20 }}>
            {lang === "en" ? "Submit for SANAA review. You can add photos after approval." : "تُراجع من فريق صَنعة قبل النشر."}
          </p>
          <div className="mk-form-2" style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 14 }}>
            <div><label style={lbl}>{lang === "en" ? "Name (English)" : "الاسم (إنجليزي)"} *</label><input required value={form.name_en} onChange={set("name_en")} style={inp} placeholder={lang === "en" ? "Knotted wall hanging" : "معلّقة مكرمية"} /></div>
            <div><label style={lbl}>{lang === "en" ? "Name (Arabic)" : "الاسم (عربي)"} *</label><input required value={form.name_ar} onChange={set("name_ar")} style={inp} dir="rtl" placeholder={lang === "en" ? "Knotted wall hanging" : "معلّقة مكرمية"} /></div>
            <div><label style={lbl}>{lang === "en" ? "Category" : "الفئة"} *</label>
              <BrandSelect
                value={form.category_id}
                onChange={(v) => setForm(f => ({ ...f, category_id: v }))}
                options={cats.map(c => ({ value: c.id, label: lang === "ar" ? (c.name_ar || c.name_en) : c.name_en }))}
                placeholder={lang === "en" ? "Choose a category" : "اختر فئة"}
                lang={lang} ariaLabel={lang === "en" ? "Category" : "الفئة"}
                style={{ marginTop: 6 }}
              />
            </div>
            <div><label style={lbl}>{lang === "en" ? "Price (EGP)" : "السعر (ج.م)"} *</label><input required type="number" min="1" step="1" value={form.price} onChange={set("price")} style={inp} placeholder={lang === "en" ? "e.g. 1200" : "مثال: ١٢٠٠"} /></div>
            <div><label style={lbl}>{lang === "en" ? "Stock" : "الكمية"}</label><input type="number" min="0" value={form.stock} onChange={set("stock")} style={inp} /></div>
            <div><label style={lbl}>{lang === "en" ? "Edition size (optional)" : "حجم الإصدار (اختياري)"}</label><input type="number" min="1" value={form.edition_size} onChange={set("edition_size")} style={inp} placeholder={lang === "en" ? "e.g. 6" : "مثال: ٦"} /></div>
            <div style={{ gridColumn: "span 2" }}><label style={lbl}>{lang === "en" ? "Description (English)" : "الوصف (إنجليزي)"}</label><textarea rows={3} value={form.description_en} onChange={set("description_en")} style={{ ...inp, resize: "vertical" }} placeholder={lang === "en" ? "What it is, how it's made, the feeling it carries." : "What it is, how it's made, the feeling it carries."} /></div>
            <div style={{ gridColumn: "span 2" }}><label style={lbl}>{lang === "en" ? "Description (Arabic)" : "الوصف (عربي)"}</label><textarea rows={3} value={form.description_ar} onChange={set("description_ar")} dir="rtl" style={{ ...inp, resize: "vertical" }} placeholder={lang === "en" ? "ما هي القطعة، كيف صُنعت، وما تحمله من إحساس." : "ما هي القطعة، كيف صُنعت، وما تحمله من إحساس."} /></div>
            <div><label style={lbl}>{lang === "en" ? "Materials (English)" : "الخامات (إنجليزي)"}</label><input value={form.materials_en} onChange={set("materials_en")} style={inp} placeholder={lang === "en" ? "Egyptian cotton, palm fibre" : "Egyptian cotton, palm fibre"} /></div>
            <div><label style={lbl}>{lang === "en" ? "Materials (Arabic)" : "الخامات (عربي)"}</label><input value={form.materials_ar} onChange={set("materials_ar")} dir="rtl" style={inp} placeholder={lang === "en" ? "قطن مصري، ليف نخيل" : "قطن مصري، ليف نخيل"} /></div>
            <div><label style={lbl}>{lang === "en" ? "Dimensions (English)" : "المقاسات (إنجليزي)"}</label><input value={form.dimensions_en} onChange={set("dimensions_en")} style={inp} placeholder={lang === "en" ? "92 × 64 cm" : "92 × 64 cm"} /></div>
            <div><label style={lbl}>{lang === "en" ? "Dimensions (Arabic)" : "المقاسات (عربي)"}</label><input value={form.dimensions_ar} onChange={set("dimensions_ar")} dir="rtl" style={inp} placeholder={lang === "en" ? "٩٢ × ٦٤ سم" : "٩٢ × ٦٤ سم"} /></div>
          </div>
          {err && <div style={{ marginTop: 14, color: "var(--terracotta)", fontSize: 13 }}>{err}</div>}
          <button type="submit" disabled={status === "submitting"} className="btn" style={{ marginTop: 22, opacity: status === "submitting" ? 0.6 : 1 }}>
            {status === "submitting" ? (lang === "en" ? "Submitting…" : "جاري الإرسال…") : (lang === "en" ? "Submit for approval" : "أرسل للمراجعة")} →
          </button>
        </form>
      )}
    </ModalShell>
  );
}

// ───── Piece actions: Archive (via approval) ──────────────────────────
function ArchiveConfirmModal({ open, onClose, lang, piece, makerId, userId, onSubmitted }) {
  const [status, setStatus] = React.useState("idle");
  const [err, setErr] = React.useState("");

  React.useEffect(() => { if (open) { setStatus("idle"); setErr(""); } }, [open]);

  const submit = async () => {
    if (!piece) return;
    setStatus("submitting"); setErr("");
    const { error } = await window.sb.from("approval_requests").insert({
      maker_id: makerId,
      requested_by: userId,
      kind: "piece.archive",
      target_table: "products",
      target_id: piece.id,
      diff_json: { is_published: { old: true, new: false } },
      note: `Archive ${piece.num} — ${piece.name}`,
      priority: "normal",
    });
    if (error) { setErr(makerFail(lang, error.message)); setStatus("error"); return; }
    setStatus("done");
    if (onSubmitted) onSubmitted();
    setTimeout(onClose, 1500);
  };

  return (
    <ModalShell open={open} onClose={onClose} width={460}>
      {status === "done" ? (
        <div style={{ textAlign: "center", padding: "10px 0" }}>
          <h2 style={{ fontFamily: "var(--ff-display)", fontSize: 28 }}>{lang === "en" ? "Sent for review" : "أُرسلت"}</h2>
          <p style={{ marginTop: 8, color: "var(--olive)", fontSize: 13 }}>{lang === "en" ? "Admin will confirm the archive." : "سيقوم المسؤول بالتأكيد."}</p>
        </div>
      ) : (
        <>
          <h2 style={{ fontFamily: "var(--ff-display)", fontSize: 28, marginBottom: 10 }}>{lang === "en" ? "Archive piece?" : "أرشفة القطعة؟"}</h2>
          <p style={{ color: "var(--olive)", fontSize: 14, marginBottom: 20 }}>
            {lang === "en"
              ? `Send "${piece?.name}" to the approval queue for archiving. The piece will be hidden from the shop after approval.`
              : `إرسال "${piece?.name}" للمراجعة لأرشفتها.`}
          </p>
          {err && <div style={{ color: "var(--terracotta)", fontSize: 13, marginBottom: 12 }}>{err}</div>}
          <div style={{ display: "flex", gap: 10 }}>
            <button onClick={submit} disabled={status === "submitting"} className="btn" style={{ background: "var(--terracotta)", borderColor: "var(--terracotta)" }}>{status === "submitting" ? "…" : (lang === "en" ? "Submit archive request" : "إرسال")}</button>
            <button onClick={onClose} className="btn ghost">{lang === "en" ? "Cancel" : "إلغاء"}</button>
          </div>
        </>
      )}
    </ModalShell>
  );
}

// ───── Maker-side per-line status pill + action set ───────────────────
const MAKER_STATUS_PILL = {
  awaiting_admin_review:     { en: "Awaiting admin",     ar: "بانتظار الإدارة",  tone: "muted" },
  awaiting_maker_acceptance: { en: "Awaiting you",        ar: "بانتظارك",         tone: "gold" },
  maker_confirmed:           { en: "You confirmed",       ar: "اعتمدتها",         tone: "olive" },
  maker_in_progress:         { en: "In production",       ar: "قيد الصنع",        tone: "olive" },
  maker_delayed:             { en: "Delayed",             ar: "متأخر",            tone: "terracotta" },
  maker_rejected:            { en: "You declined",        ar: "رفضت",             tone: "muted" },
  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" },
  cancelled:                 { en: "Cancelled",           ar: "ألغيت",            tone: "muted" },
};

// Returns the list of action buttons the maker can use against this status.
// Mirrors the whitelist in maker_update_order_item_status() so we never
// show a button that would fail server-side.
function _makerActions(status, lang) {
  switch (status) {
    case "awaiting_admin_review":
    case "awaiting_maker_acceptance":
      return [
        { to: "maker_confirmed",   label: lang === "en" ? "Accept" : "قبول",   tone: "olive" },
        { to: "maker_rejected",    label: lang === "en" ? "Decline" : "رفض",  tone: "terracotta" },
      ];
    case "maker_confirmed":
      return [
        { to: "maker_in_progress", label: lang === "en" ? "Start production" : "ابدأ الصنع", tone: "olive" },
        { to: "maker_delayed",     label: lang === "en" ? "Mark delayed" : "تأخّر",          tone: "terracotta" },
      ];
    case "maker_in_progress":
      return [
        { to: "quality_check",     label: lang === "en" ? "Ready for QC" : "جاهز للفحص",   tone: "olive" },
        { to: "maker_delayed",     label: lang === "en" ? "Mark delayed" : "تأخّر",         tone: "terracotta" },
      ];
    case "maker_delayed":
      return [
        { to: "maker_in_progress", label: lang === "en" ? "Resume production" : "استئناف", tone: "olive" },
      ];
    case "quality_check":
      return [
        { to: "packed",            label: lang === "en" ? "Mark packed" : "مُغلَّفة",      tone: "olive" },
      ];
    default:
      return [];
  }
}

// ───── Order detail drawer ────────────────────────────────────────────
function OrderDetailDrawer({ open, onClose, lang, orderRow, makerId }) {
  const [items, setItems] = React.useState(null);
  const [busy, setBusy] = React.useState(null); // item.id while pending

  // Makers no longer read the orders row directly (buyer PII is RLS-protected).
  // Ship-to comes from the RPC row (orderRow); only the maker's own order_items
  // — which the maker is allowed to read — are fetched here.
  const refreshItems = React.useCallback((orderId) => {
    if (!orderId) return Promise.resolve();
    return window.sb.from("order_items").select("*").eq("order_id", orderId).eq("maker_id", makerId)
      .then(({ data: rows }) => setItems(rows || []));
  }, [makerId]);

  React.useEffect(() => {
    if (!open || !orderRow) return;
    setItems(null);
    refreshItems(orderRow.order_id);
  }, [open, orderRow?.order_id, refreshItems]);

  const act = async (item, toStatus) => {
    if (!item || !toStatus) return;
    setBusy(item.id);
    const { error } = await window.sb.rpc("maker_update_order_item_status", {
      p_item_id: item.id,
      p_status: toStatus,
    });
    setBusy(null);
    if (error) {
      console.warn("maker_update_order_item_status:", error.message);
      window.toast(lang === "en" ? "We couldn't update that item. Please try again." : "تعذّر تحديث القطعة. حاول مرّة أخرى.", { type: "error", lang });
      return;
    }
    refreshItems(orderRow?.order_id);
  };

  // ESC closes; body scroll locked while open.
  React.useEffect(() => {
    if (!open) 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);
    };
  }, [open, onClose]);

  if (!open) return null;

  const isRtl = lang === "ar";
  return (
    <>
      <div onClick={onClose} style={{ position: "fixed", inset: 0, background: "rgba(28,26,21,0.55)", zIndex: 90 }} />
      <aside dir={isRtl ? "rtl" : "ltr"} style={{
        position: "fixed", top: 0, bottom: 0,
        // Mirror in RTL: drawer slides in from the LEFT, shadow flipped.
        ...(isRtl ? { left: 0, right: "auto", boxShadow: "20px 0 60px -20px rgba(28,26,21,0.3)" }
                  : { right: 0, left: "auto", boxShadow: "-20px 0 60px -20px rgba(28,26,21,0.3)" }),
        width: 460, maxWidth: "100vw", background: "var(--paper)", zIndex: 91, overflowY: "auto",
      }}>
        <div style={{ padding: "22px 26px", borderBottom: "1px solid var(--line-2)", background: "var(--paper-2)" }}>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start" }}>
            <div>
              <div style={{ fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.22em", color: "var(--terracotta)" }}>{lang === "en" ? "Order" : "طلب"}</div>
              <h2 style={{ fontFamily: "var(--ff-display)", fontSize: 28, marginTop: 4 }}>{orderRow?.id}</h2>
              <div style={{ fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.2em", color: "var(--muted)", marginTop: 6 }}>{window.fmtDate(orderRow?.created_at, lang, { day: "numeric", month: "short" })} · {statusText(orderRow?.status, lang)}</div>
            </div>
            <button onClick={onClose} aria-label={lang === "en" ? "Close order detail" : "إغلاق"} 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>
        <div style={{ padding: "20px 26px", display: "flex", flexDirection: "column", gap: 22 }}>
          <div>
            <div style={{ fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--muted)", marginBottom: 6 }}>{lang === "en" ? "Ship to" : "المُرسَل إليه"}</div>
            <div style={{ fontSize: 14 }}>{orderRow?.shipRecipient || orderRow?.buyer}</div>
            <div style={{ fontSize: 13, lineHeight: 1.5, color: "var(--olive)", marginTop: 2 }}>
              {[orderRow?.shipCity, orderRow?.shipGovernorate].filter(Boolean).join(", ")}
              {orderRow?.shipPhone ? <><br />{orderRow.shipPhone}</> : null}
            </div>
          </div>
          <div>
            <div style={{ fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--muted)", marginBottom: 8 }}>{lang === "en" ? "Your items in this order" : "قطعك في الطلب"}</div>
            {items === null ? (
              <Skeleton h={80} />
            ) : items.length === 0 ? (
              <div style={{ color: "var(--muted)", fontSize: 13 }}>{lang === "en" ? "No items found." : "لا توجد عناصر."}</div>
            ) : (
              <div style={{ border: "1px solid var(--line-2)", borderRadius: 10, overflow: "hidden" }}>
                {items.map((it, i) => {
                  const pill = MAKER_STATUS_PILL[it.maker_status] || { en: it.maker_status, ar: it.maker_status, tone: "muted" };
                  const actions = _makerActions(it.maker_status, lang);
                  const due = it.maker_due_date
                    ? window.fmtDate(it.maker_due_date, lang, { day: "numeric", month: "short" })
                    : null;
                  return (
                    <div key={it.id} style={{ padding: "14px 14px", borderTop: i === 0 ? "none" : "1px solid var(--line-2)" }}>
                      <div style={{ display: "flex", justifyContent: "space-between", gap: 10, alignItems: "flex-start" }}>
                        <div style={{ minWidth: 0 }}>
                          <div style={{ display: "flex", gap: 8, flexWrap: "wrap", alignItems: "center" }}>
                            {it.maker_ref && (
                              <span style={{ fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", color: "var(--terracotta)" }}>{it.maker_ref}</span>
                            )}
                            <Pill st={pill.tone === "olive" ? "Live" : pill.tone === "terracotta" ? "Pending" : pill.tone === "gold" ? "Pending" : "Draft"}>
                              {pill[lang] || pill.en}
                            </Pill>
                          </div>
                          <div style={{ fontFamily: "var(--ff-display)", fontSize: 16, marginTop: 6 }}>{it.product_name_en}</div>
                          <div style={{ fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.2em", color: "var(--muted)" }}>
                            {it.sku} · ×{it.quantity}{due ? ` · ${lang === "en" ? "due" : "موعد"} ${due}` : ""}
                          </div>
                        </div>
                        <div style={{ textAlign: "end" }}>
                          <div style={{ fontFamily: "var(--ff-display)", fontSize: 16 }}>{fmtNum(Math.round(it.line_total_piastres / 100), lang)}</div>
                          <div style={{ fontFamily: "var(--ff-mono)", fontSize: 9, color: "var(--olive)" }}>{lang === "en" ? "split " : "حصّتك "}{fmtNum(Math.round((it.line_total_piastres * (1 - it.commission_pct / 100)) / 100), lang)}</div>
                        </div>
                      </div>
                      {actions.length > 0 && (
                        <div style={{ marginTop: 10, display: "flex", flexWrap: "wrap", gap: 8 }}>
                          {actions.map((a, j) => (
                            <button
                              key={j}
                              onClick={() => act(it, a.to)}
                              disabled={busy === it.id}
                              aria-label={a.label}
                              style={{
                                padding: "7px 14px",
                                borderRadius: 999,
                                border: `1px solid ${a.tone === "terracotta" ? "var(--terracotta)" : "var(--line)"}`,
                                background: a.tone === "olive" ? "var(--olive)" : "transparent",
                                color: a.tone === "olive" ? "var(--paper)" : a.tone === "terracotta" ? "var(--terracotta)" : "var(--ink)",
                                fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.18em", textTransform: "uppercase",
                                cursor: busy === it.id ? "wait" : "pointer",
                                opacity: busy === it.id ? 0.5 : 1,
                                minHeight: 34,
                              }}
                            >
                              {busy === it.id ? "…" : a.label}
                            </button>
                          ))}
                        </div>
                      )}
                    </div>
                  );
                })}
              </div>
            )}
          </div>
          {orderRow && (
            <div style={{ padding: "14px 16px", background: "var(--paper-2)", borderRadius: 10, fontSize: 12, color: "var(--olive)", lineHeight: 1.55 }}>
              {lang === "en"
                ? "Your production status is logged with SANAA ops. Customer-facing updates (shipping, delivery, returns) are handled by the SANAA team."
                : "حالتك الإنتاجيّة تُسجَّل لدى فريق العمليات. حالات العميل (شحن، تسليم، إرجاع) يديرها فريق صَنعة."}
            </div>
          )}
        </div>
      </aside>
    </>
  );
}

// ───── CSV download helper ────────────────────────────────────────────
function downloadCsv(filename, headers, rows) {
  const esc = (v) => {
    if (v == null) return "";
    const s = String(v);
    return /[",\n]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s;
  };
  const csv = [headers.join(","), ...rows.map(r => r.map(esc).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 = filename;
  document.body.appendChild(a); a.click(); document.body.removeChild(a);
  URL.revokeObjectURL(url);
}

// ───── Payout settings — owner-only bank/iban/tax (maker_payout_details) ────────
function PayoutSettingsForm({ lang, maker, onChanged }) {
  const [form, setForm] = React.useState({ bank_name: "", iban_full: "", tax_id: "", payout_phone: "", pickup_address_en: "" });
  const [status, setStatus] = React.useState("idle");
  const [msg, setMsg] = React.useState("");
  const [msgOk, setMsgOk] = React.useState(true);

  React.useEffect(() => {
    if (!maker) return;
    // Payout/tax details live in the owner/admin-only maker_payout_details table
    // (not on the public-read makers row). RLS lets the owning maker read it.
    window.sb.from("maker_payout_details")
      .select("bank_name, iban_full, tax_id, payout_phone, pickup_address_en")
      .eq("maker_id", maker.id).maybeSingle()
      .then(({ data }) => setForm({
        bank_name: data?.bank_name || "",
        iban_full: data?.iban_full || "",
        tax_id: data?.tax_id || "",
        payout_phone: data?.payout_phone || "",
        pickup_address_en: data?.pickup_address_en || "",
      }));
  }, [maker?.id]);

  const submit = async (e) => {
    e.preventDefault();
    if (!maker) return;
    // A maker owns their own payout details, so they write them directly —
    // RLS (is_maker_of) gates the row. No admin approval is needed for a
    // maker's own bank info.
    setStatus("submitting"); setMsg("");
    const { error } = await window.sb.from("maker_payout_details").upsert({
      maker_id: maker.id,
      bank_name: form.bank_name || null,
      iban_full: form.iban_full || null,
      tax_id: form.tax_id || null,
      payout_phone: form.payout_phone || null,
      pickup_address_en: form.pickup_address_en || null,
      updated_at: new Date().toISOString(),
    }, { onConflict: "maker_id" });
    setStatus("idle");
    if (error) { setMsgOk(false); setMsg(makerFail(lang, error.message)); return; }
    setMsgOk(true); setMsg(lang === "en" ? "Saved." : "تم الحفظ.");
    if (onChanged) onChanged();
    setTimeout(() => setMsg(""), 3000);
  };

  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, boxSizing: "border-box" };
  const lbl = { fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--muted)" };

  return (
    <div style={{ marginBottom: 22, 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" ? "Payout & tax details" : "بيانات الصرف"}
      </div>
      <form onSubmit={submit} style={{ padding: 22, display: "grid", gridTemplateColumns: "1fr 1fr", gap: 14 }}>
        <div><label style={lbl}>{lang === "en" ? "Bank name" : "اسم البنك"}</label><input value={form.bank_name} onChange={e => setForm(f => ({ ...f, bank_name: e.target.value }))} placeholder={lang === "en" ? "CIB" : "البنك التجاري الدولي"} style={inp} /></div>
        <div><label style={lbl}>{lang === "en" ? "IBAN" : "آيبان"}</label><input value={form.iban_full} onChange={e => setForm(f => ({ ...f, iban_full: e.target.value }))} placeholder="EG..." style={inp} /></div>
        <div><label style={lbl}>{lang === "en" ? "Tax ID" : "الرقم الضريبي"}</label><input value={form.tax_id} onChange={e => setForm(f => ({ ...f, tax_id: e.target.value }))} style={inp} /></div>
        <div><label style={lbl}>{lang === "en" ? "Payout phone" : "هاتف الصرف"}</label><input value={form.payout_phone} onChange={e => setForm(f => ({ ...f, payout_phone: e.target.value }))} placeholder="+20..." style={inp} dir="ltr" /></div>
        <div style={{ gridColumn: "span 2" }}><label style={lbl}>{lang === "en" ? "Pickup address" : "عنوان الاستلام"}</label><input value={form.pickup_address_en} onChange={e => setForm(f => ({ ...f, pickup_address_en: e.target.value }))} placeholder={lang === "en" ? "Flat 4, Sharia Sariya, Zamalek" : "شقة ٤، شارع سرايا، الزمالك"} style={inp} /></div>
        <div style={{ gridColumn: "span 2", display: "flex", gap: 12, alignItems: "center" }}>
          <button type="submit" disabled={status === "submitting"} className="btn" style={{ opacity: status === "submitting" ? 0.6 : 1 }}>
            {status === "submitting" ? "…" : (lang === "en" ? "Save payout details" : "حفظ بيانات الصرف")} →
          </button>
          {msg && <span style={{ fontSize: 13, color: msgOk ? "var(--olive)" : "var(--terracotta)" }}>{msg}</span>}
        </div>
        <div style={{ gridColumn: "span 2", fontSize: 12, color: "var(--muted)" }}>
          {lang === "en" ? "Only you and SANAA admins can see these details. They're saved securely." : "تظهر هذه البيانات لك ولإدارة صَنعة فقط، وتُحفظ بأمان."}
        </div>
      </form>
    </div>
  );
}

// ───── Maker Settings — profile (auth.profiles) + maker basics ────────
function MakerSettings({ lang, userId, userEmail, maker, onChanged }) {
  const [profile, setProfile] = React.useState(null);
  const [form, setForm] = React.useState({ full_name: "", phone: "" });
  const [saving, setSaving] = React.useState(false);
  const [msg, setMsg] = React.useState("");
  const [msgOk, setMsgOk] = React.useState(true);
  const [signingOut, setSigningOut] = React.useState(false);
  const fileRef = React.useRef(null);

  React.useEffect(() => {
    if (!userId) return;
    window.sb.from("profiles").select("full_name, phone, avatar_url").eq("id", userId).single()
      .then(({ data }) => {
        if (data) {
          setProfile(data);
          setForm({ full_name: data.full_name || "", phone: data.phone || "" });
        }
      });
  }, [userId]);

  const save = async (e) => {
    e.preventDefault();
    setSaving(true); setMsg("");
    const { error } = await window.sb.from("profiles").update({
      full_name: form.full_name || null,
      phone: form.phone || null,
    }).eq("id", userId);
    setSaving(false);
    if (error) { setMsgOk(false); setMsg(makerFail(lang, error.message)); return; }
    setMsgOk(true); setMsg(lang === "en" ? "Saved." : "تمّ الحفظ.");
    setTimeout(() => setMsg(""), 2200);
    if (onChanged) onChanged();
  };

  const onPickAvatar = async (e) => {
    const file = e.target.files?.[0];
    if (!file || !maker?.id) return;
    setMsgOk(true); setMsg(lang === "en" ? "Uploading…" : "جاري الرفع…");
    const ext = (file.name.split(".").pop() || "jpg").toLowerCase();
    const path = `${maker.id}/avatar-${Date.now()}.${ext}`;
    const { error: upErr } = await window.sb.storage.from("maker-images").upload(path, file, { upsert: false, contentType: file.type });
    if (upErr) { setMsgOk(false); setMsg(makerFail(lang, upErr.message)); return; }
    const { data: pub } = window.sb.storage.from("maker-images").getPublicUrl(path);
    const url = pub?.publicUrl;
    const { error: profErr } = await window.sb.from("profiles").update({ avatar_url: url }).eq("id", userId);
    if (profErr) { setMsgOk(false); setMsg(makerFail(lang, profErr.message)); return; }
    setProfile(p => ({ ...(p || {}), avatar_url: url }));
    setMsgOk(true); setMsg(lang === "en" ? "Avatar updated." : "تمّ تحديث الصورة.");
    setTimeout(() => setMsg(""), 2400);
    if (onChanged) onChanged();
  };

  const signOut = async () => {
    setSigningOut(true);
    await window.sb.auth.signOut();
    window.location.hash = "#/";
  };

  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, boxSizing: "border-box" };
  const lbl = { fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--muted)" };

  return (
    <div>
      <h2 style={{ fontFamily: "var(--ff-display)", fontSize: 40, marginBottom: 20 }}>{lang === "en" ? "Settings" : "الإعدادات"}</h2>

      {/* Personal account */}
      <div style={{ marginBottom: 22, 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" ? "Personal account" : "الحساب الشخصي"}</div>
        <form onSubmit={save} style={{ padding: 22, display: "grid", gridTemplateColumns: "120px 1fr", gap: 22, alignItems: "start" }}>
          <div>
            <div style={{ width: 100, height: 100, borderRadius: "50%", overflow: "hidden", background: "var(--paper-2)", border: "1px solid var(--line-2)" }}>
              {profile?.avatar_url
                ? <img src={profile.avatar_url} alt="" style={{ width: "100%", height: "100%", objectFit: "cover" }} />
                : <Placeholder tone={maker?.tone || "sand"} label={maker?.name_en?.split(" ")[0]?.toLowerCase() || "you"} />}
            </div>
            <input ref={fileRef} type="file" accept="image/*" onChange={onPickAvatar} style={{ display: "none" }} />
            <button type="button" onClick={() => fileRef.current?.click()} style={{ marginTop: 10, fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--terracotta)", background: "transparent", border: 0, cursor: "pointer" }}>
              {lang === "en" ? "Change avatar" : "تغيير الصورة"}
            </button>
          </div>
          <div style={{ display: "grid", gap: 14 }}>
            <div><label style={lbl}>{lang === "en" ? "Email" : "البريد"}</label><input value={userEmail || ""} readOnly style={{ ...inp, background: "var(--paper-2)", color: "var(--muted)" }} type="email" /></div>
            <div className="mk-form-2" style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 14 }}>
              <div><label style={lbl}>{lang === "en" ? "Full name" : "الاسم الكامل"}</label><input value={form.full_name} onChange={e => setForm(f => ({ ...f, full_name: e.target.value }))} style={inp} /></div>
              <div><label style={lbl}>{lang === "en" ? "Phone" : "الهاتف"}</label><input value={form.phone} onChange={e => setForm(f => ({ ...f, phone: e.target.value }))} style={inp} placeholder="+20 ..." dir="ltr" /></div>
            </div>
            <div style={{ display: "flex", gap: 10, alignItems: "center" }}>
              <button type="submit" disabled={saving} className="btn" style={{ opacity: saving ? 0.6 : 1 }}>
                {saving ? (lang === "en" ? "Saving…" : "حفظ…") : (lang === "en" ? "Save changes" : "حفظ")} →
              </button>
              {msg && <span style={{ fontSize: 13, color: msgOk ? "var(--olive)" : "var(--terracotta)" }}>{msg}</span>}
            </div>
          </div>
        </form>
      </div>

      {/* Public profile shortcut */}
      <div style={{ marginBottom: 22, padding: "16px 22px", border: "1px solid var(--line-2)", borderRadius: 14, display: "flex", justifyContent: "space-between", alignItems: "center", gap: 12 }}>
        <div>
          <div style={{ fontFamily: "var(--ff-display)", fontSize: 18 }}>{lang === "en" ? "Public profile" : "الصفحة العامّة"}</div>
          <div style={{ fontSize: 13, color: "var(--muted)", marginTop: 2 }}>{lang === "en" ? "Edit your name, story, and craft (requires admin approval)." : "تعديل اسمك وقصتك وحرفتك (يتطلب موافقة)."}</div>
        </div>
        <a href="#/makers/admin?tab=profile" onClick={(e) => { e.preventDefault(); window.dispatchEvent(new CustomEvent("maker-tab", { detail: "profile" })); }} className="btn ghost">
          {lang === "en" ? "Edit" : "تعديل"} →
        </a>
      </div>

      <PayoutSettingsForm lang={lang} maker={maker} onChanged={onChanged} />

      <button onClick={signOut} disabled={signingOut} style={{ marginTop: 8, color: "var(--terracotta)", background: "transparent", border: "1px solid var(--terracotta)", borderRadius: 999, padding: "10px 20px", cursor: "pointer", fontSize: 13, opacity: signingOut ? 0.6 : 1 }}>
        {signingOut ? "…" : (lang === "en" ? "Sign out" : "تسجيل الخروج")}
      </button>
    </div>
  );
}

// ───── MESSAGES (real conversations) ─────────────────────────────────
function MessagesPanel({ lang, makerId, userId }) {
  const [convs, setConvs] = React.useState(null);
  const [active, setActive] = React.useState(null);
  const [messages, setMessages] = React.useState([]);
  const [reply, setReply] = React.useState("");
  const [sending, setSending] = React.useState(false);
  const [refresh, setRefresh] = React.useState(0);
  const messagesEndRef = React.useRef(null);

  // Load conversation list
  React.useEffect(() => {
    if (!makerId) return;
    window.sb.from("conversations").select("*").eq("maker_id", makerId).order("last_message_at", { ascending: false })
      .then(({ data }) => setConvs(data || []));
  }, [makerId, refresh]);

  // Realtime: any conversation update for this maker → refresh list (new conv, last_message bumped)
  window.useRealtimeConversations("maker_id", makerId, () => setRefresh(r => r + 1));

  // Load messages when active conversation opens; clear unread
  React.useEffect(() => {
    if (!active) { setMessages([]); return; }
    window.sb.from("messages").select("*").eq("conversation_id", active.id).order("created_at")
      .then(({ data }) => setMessages(data || []));
    if (active.unread_for_maker > 0) {
      window.sb.from("conversations").update({ unread_for_maker: 0 }).eq("id", active.id)
        .then(() => setRefresh(r => r + 1));
    }
  }, [active?.id]);

  // Realtime: live append when a new message lands in active conversation (de-duped by id)
  window.useRealtimeMessages(active?.id, (row) => {
    setMessages(m => m.find(x => x.id === row.id) ? m : [...m, row]);
    // If it's from the customer and we're on the conversation, mark read immediately
    if (row.sender_role !== "maker") {
      window.sb.from("conversations").update({ unread_for_maker: 0 }).eq("id", active.id)
        .then(({ error }) => { if (!error) setRefresh(r => r + 1); });
    }
  });

  // Auto-scroll to bottom on new messages
  React.useEffect(() => {
    if (messagesEndRef.current) {
      messagesEndRef.current.scrollIntoView({ behavior: "smooth", block: "end" });
    }
  }, [messages.length]);

  const send = async (e) => {
    e.preventDefault();
    const text = reply.trim();
    if (!text || !active || sending) return;
    setSending(true);
    setReply("");
    // Optimistic UI: append a placeholder with a temp id; replace on confirm
    const tempId = "_tmp_" + Date.now();
    const optimistic = {
      id: tempId,
      conversation_id: active.id,
      sender_role: "maker",
      sender_id: userId,
      body: text,
      created_at: new Date().toISOString(),
      _pending: true,
    };
    setMessages(m => [...m, optimistic]);

    const { data, error } = await window.sb.from("messages").insert({
      conversation_id: active.id,
      sender_role: "maker",
      sender_id: userId,
      body: text,
    }).select().single();
    setSending(false);

    if (error) {
      // Mark optimistic as failed; allow retry by clicking
      setMessages(m => m.map(x => x.id === tempId ? { ...x, _failed: true, _pending: false } : x));
      setReply(text); // restore so user can fix and retry
      return;
    }
    // Replace optimistic with confirmed (de-duped against realtime delivery)
    setMessages(m => {
      const without = m.filter(x => x.id !== tempId && x.id !== data.id);
      return [...without, data];
    });
    setRefresh(r => r + 1);
  };

  // Retry a failed message bubble (tap / keyboard activation).
  const retry = async (failed) => {
    if (!failed || !active || sending) return;
    setSending(true);
    setMessages(m => m.map(x => x.id === failed.id ? { ...x, _failed: false, _pending: true } : x));
    const { data, error } = await window.sb.from("messages").insert({
      conversation_id: active.id,
      sender_role: "maker",
      sender_id: userId,
      body: failed.body,
    }).select().single();
    setSending(false);
    if (error) {
      setMessages(m => m.map(x => x.id === failed.id ? { ...x, _failed: true, _pending: false } : x));
      return;
    }
    setMessages(m => {
      const without = m.filter(x => x.id !== failed.id && x.id !== data.id);
      return [...without, data];
    });
    setRefresh(r => r + 1);
  };

  const totalUnread = (convs || []).reduce((s, c) => s + (c.unread_for_maker || 0), 0);

  return (
    <div>
      <div style={{ marginBottom: 6, fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--terracotta)" }}>
        <span className="dot" style={{ display: "inline-block", width: 6, height: 6, background: "var(--terracotta)", borderRadius: "50%", marginInlineEnd: 10, verticalAlign: "middle" }}></span>
        {lang === "en" ? "From your customers" : "من عملائك"}
      </div>
      <h2 style={{ fontFamily: "var(--ff-display)", fontSize: 40, marginBottom: 4, letterSpacing: "-0.01em" }}>
        {lang === "en" ? "Inbox" : "صندوق الرسائل"}
        {totalUnread > 0 && <span style={{ fontSize: "0.5em", color: "var(--terracotta)", marginInlineStart: 14, fontStyle: "italic", fontWeight: 400 }}>{fmtNum(totalUnread, lang)} {lang === "en" ? (totalUnread === 1 ? "new" : "new") : "جديد"}</span>}
      </h2>
      <p style={{ marginTop: 6, marginBottom: 24, fontSize: 13, color: "var(--olive)", fontStyle: "italic", maxWidth: 560 }}>
        {lang === "en" ? "Buyer questions about your pieces, custom requests, and workshop inquiries." : "أسئلة العملاء عن قطعك والطلبات الخاصة."}
      </p>
      {convs === null ? (
        <Skeleton h={200} />
      ) : convs.length === 0 ? (
        <div style={{ padding: "70px 24px", textAlign: "center", border: "1px solid var(--line-2)", borderRadius: 14, background: "var(--paper)" }}>
          <Star8 size={24} color="var(--gold-soft)" />
          <h3 style={{ marginTop: 18, fontFamily: "var(--ff-display)", fontSize: 28, color: "var(--ink)", letterSpacing: "-0.01em" }}>
            {lang === "en" ? "Your inbox is quiet." : "صندوقك هادئ."}
          </h3>
          <p style={{ marginTop: 10, fontSize: 14, color: "var(--olive)", maxWidth: 380, marginLeft: "auto", marginRight: "auto", lineHeight: 1.6, fontStyle: "italic" }}>
            {lang === "en" ? "Customers reach out from your maker page and from each piece. Replies appear here in real time." : "تظهر رسائل العملاء هنا فور وصولها."}
          </p>
        </div>
      ) : (
        <div className="mk-conv-grid" data-thread-open={active ? "true" : "false"} style={{ display: "grid", gridTemplateColumns: "320px 1fr", gap: 0, border: "1px solid var(--line-2)", borderRadius: 14, overflow: "hidden", minHeight: 520, background: "var(--paper)" }}>
          {/* Conversation list */}
          <div className="mk-conv-list" style={{ borderRight: "1px solid var(--line-2)", overflowY: "auto", maxHeight: 620 }}>
            {convs.map((c, i) => {
              const isActive = active?.id === c.id;
              const isUnread = c.unread_for_maker > 0;
              return (
              <button key={c.id} onClick={() => setActive(c)} style={{
                width: "100%", textAlign: "start", padding: "18px 18px 18px 16px",
                border: 0,
                borderTop: i === 0 ? "none" : "1px solid var(--line-2)",
                borderInlineStart: isActive ? "3px solid var(--terracotta)" : "3px solid transparent",
                background: isActive ? "var(--paper-2)" : "var(--paper)",
                cursor: "pointer", display: "block",
                transition: "background .15s",
              }}>
                <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", gap: 8 }}>
                  <div style={{ display: "flex", alignItems: "center", gap: 8, minWidth: 0 }}>
                    {isUnread && !isActive && <span style={{ width: 6, height: 6, borderRadius: "50%", background: "var(--terracotta)", flexShrink: 0 }} />}
                    <div style={{ fontFamily: "var(--ff-display)", fontSize: 17, fontWeight: isUnread ? 500 : 400, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
                      {c.guest_name || (lang === "en" ? "Customer" : "عميل")}
                    </div>
                  </div>
                  <div style={{ fontFamily: "var(--ff-mono)", fontSize: 9, color: "var(--muted)", letterSpacing: "0.18em", flexShrink: 0 }}>
                    {window.fmtDate(c.last_message_at, lang)}
                  </div>
                </div>
                <div style={{ marginTop: 6, fontSize: 13, color: isUnread ? "var(--ink)" : "var(--muted)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", marginInlineStart: isUnread && !isActive ? 14 : 0, fontStyle: c.subject ? "normal" : "italic" }}>
                  {c.subject || (lang === "en" ? "Untitled thread" : "بدون موضوع")}
                </div>
              </button>
              );
            })}
          </div>
          {/* Detail + reply */}
          <div className="mk-conv-thread" style={{ display: "flex", flexDirection: "column", maxHeight: 620 }}>
            {!active ? (
              <div style={{ flex: 1, display: "grid", placeItems: "center", padding: "40px 20px" }}>
                <div style={{ textAlign: "center", maxWidth: 320 }}>
                  <Star8 size={18} color="var(--gold-soft)" />
                  <div style={{ marginTop: 14, fontFamily: "var(--ff-display)", fontSize: 22, color: "var(--ink)" }}>
                    {lang === "en" ? "Select a thread" : "اختر محادثة"}
                  </div>
                  <div style={{ marginTop: 6, fontSize: 13, color: "var(--muted)", lineHeight: 1.55 }}>
                    {lang === "en" ? "Tap any customer message on the left to read or reply." : "اضغط على محادثة لتقرأ وتردّ."}
                  </div>
                </div>
              </div>
            ) : (
              <>
                <div style={{ padding: "16px 22px", borderBottom: "1px solid var(--line-2)", background: "var(--paper-2)" }}>
                  <button onClick={() => setActive(null)} className="mk-conv-back" style={{ display: "none", background: "transparent", border: 0, padding: 0, marginBottom: 8, fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--terracotta)", cursor: "pointer" }}>
                    ← {lang === "en" ? "All threads" : "كل المحادثات"}
                  </button>
                  <div style={{ fontFamily: "var(--ff-display)", fontSize: 20, letterSpacing: "-0.01em" }}>{active.subject || (lang === "en" ? "Untitled thread" : "بدون موضوع")}</div>
                  <div style={{ fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.2em", color: "var(--muted)", marginTop: 4, textTransform: "uppercase" }}>
                    {active.guest_name || (lang === "en" ? "Customer" : "عميل")}{active.guest_email ? ` · ${active.guest_email}` : ""}
                  </div>
                </div>
                <div style={{ flex: 1, overflowY: "auto", padding: "20px 22px", display: "flex", flexDirection: "column", gap: 12 }}>
                  {messages.map(m => {
                    const isFailed = !!m._failed;
                    const bubbleStyle = {
                      maxWidth: "78%",
                      alignSelf: m.sender_role === "maker" ? "flex-end" : "flex-start",
                      padding: "10px 14px", borderRadius: 14,
                      background: m.sender_role === "maker" ? "var(--ink)" : "var(--paper-2)",
                      color: m.sender_role === "maker" ? "var(--paper)" : "var(--ink)",
                      fontSize: 14, lineHeight: 1.45,
                      opacity: m._pending ? 0.55 : 1,
                      border: isFailed ? "1px solid var(--terracotta)" : "none",
                      whiteSpace: "pre-wrap", wordBreak: "break-word",
                      cursor: isFailed ? "pointer" : "default",
                      font: "inherit", textAlign: "inherit",
                    };
                    const meta = (
                      <div style={{ marginTop: 4, fontFamily: "var(--ff-mono)", fontSize: 8, opacity: 0.6, letterSpacing: "0.18em" }}>
                        {isFailed
                          ? (lang === "en" ? "Not sent — tap to retry" : "لم تُرسل — اضغط للإعادة")
                          : m._pending
                            ? (lang === "en" ? "Sending…" : "يرسل…")
                            : window.fmtDateTime(m.created_at, lang)}
                      </div>
                    );
                    if (isFailed) {
                      return (
                        <button key={m.id} type="button" onClick={() => retry(m)}
                          aria-label={lang === "en" ? "Message failed — tap to retry" : "فشل الإرسال — اضغط للإعادة"}
                          style={bubbleStyle}>
                          {m.body}
                          {meta}
                        </button>
                      );
                    }
                    return (
                      <div key={m.id} style={bubbleStyle}>
                        {m.body}
                        {meta}
                      </div>
                    );
                  })}
                  <div ref={messagesEndRef} />
                </div>
                <form onSubmit={send} style={{ padding: "14px 18px", borderTop: "1px solid var(--line-2)", display: "flex", gap: 10 }}>
                  <input value={reply} onChange={e => setReply(e.target.value)} placeholder={lang === "en" ? "Reply…" : "ردّ…"} style={{ flex: 1, padding: "10px 14px", border: "1px solid var(--line)", borderRadius: 999, background: "var(--paper)", fontSize: 14 }} />
                  <button type="submit" disabled={sending || !reply.trim()} className="btn" style={{ opacity: (sending || !reply.trim()) ? 0.5 : 1 }}>{sending ? "…" : "→"}</button>
                </form>
              </>
            )}
          </div>
        </div>
      )}
    </div>
  );
}

// ───── ANALYTICS (real, from order_items + analytics_events) ──────────
function AnalyticsPanel({ lang, makerId, orders, pieces }) {
  const [views, setViews] = React.useState({ products: {}, profile: 0, total: 0 });
  const [loading, setLoading] = React.useState(true);

  React.useEffect(() => {
    if (!makerId) return;
    setLoading(true);
    window.sb.from("analytics_events").select("event_type, product_id").eq("maker_id", makerId)
      .then(({ data }) => {
        const products = {};
        let profileViews = 0;
        for (const e of (data || [])) {
          if (e.event_type === "product_view" && e.product_id) {
            products[e.product_id] = (products[e.product_id] || 0) + 1;
          } else if (e.event_type === "maker_profile_view") {
            profileViews += 1;
          }
        }
        setViews({ products, profile: profileViews, total: (data || []).length });
        setLoading(false);
      });
  }, [makerId]);

  const totalOrders = orders.length;
  const totalRevenue = orders.reduce((s, o) => s + (o.gross || 0), 0);
  const aov = totalOrders ? Math.round(totalRevenue / totalOrders) : 0;
  const lowStock = pieces.filter(p => p.status === "Live" && p.stock > 0 && p.stock <= 2);
  const outOfStock = pieces.filter(p => p.status === "Live" && p.stock === 0);

  // Best-selling pieces by qty sold
  const bestSellers = [...pieces].sort((a, b) => (b.sold || 0) - (a.sold || 0)).slice(0, 5);

  // Product views attribution
  const piecesWithViews = pieces.map(p => ({ ...p, viewCount: views.products[p.id] || 0 }));
  const topViewed = [...piecesWithViews].sort((a, b) => b.viewCount - a.viewCount).slice(0, 5);

  return (
    <div>
      <h2 style={{ fontFamily: "var(--ff-display)", fontSize: 40, marginBottom: 20 }}>{lang === "en" ? "Analytics" : "التحليلات"}</h2>
      <div className="maker-stats" style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 18, marginBottom: 28 }}>
        <StatCard label={lang === "en" ? "Total revenue" : "الإيراد"} value={fmtNum(totalRevenue, lang)} sub="EGP" />
        <StatCard label={lang === "en" ? "Avg. order value" : "متوسط الطلب"} value={fmtNum(aov, lang)} sub="EGP" />
        <StatCard label={lang === "en" ? "Profile views" : "زيارات الصفحة"} value={fmtNum(views.profile, lang)} sub={lang === "en" ? "all-time" : "كل الوقت"} />
        <StatCard label={lang === "en" ? "Low / out of stock" : "مخزون منخفض"} value={`${fmtNum(lowStock.length, lang)} / ${fmtNum(outOfStock.length, lang)}`} sub={lang === "en" ? "low / zero" : "منخفض / نفد"} />
      </div>

      <div className="maker-twocol" style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 24 }}>
        {/* Best sellers */}
        <div style={{ padding: 22, border: "1px solid var(--line-2)", borderRadius: 14 }}>
          <h3 style={{ fontFamily: "var(--ff-display)", fontSize: 22, marginBottom: 14 }}>{lang === "en" ? "Best sellers" : "الأكثر مبيعًا"}</h3>
          {bestSellers.length === 0 || bestSellers.every(p => !p.sold) ? (
            <div style={{ color: "var(--muted)", fontSize: 13 }}>{lang === "en" ? "No sales yet." : "لا مبيعات."}</div>
          ) : bestSellers.filter(p => p.sold > 0).map((p, i) => (
            <div key={i} style={{ display: "flex", justifyContent: "space-between", padding: "10px 0", borderTop: i === 0 ? "none" : "1px solid var(--line-2)" }}>
              <div>
                <div style={{ fontFamily: "var(--ff-display)", fontSize: 16 }}>{p.name}</div>
                <div style={{ fontFamily: "var(--ff-mono)", fontSize: 9, color: "var(--muted)", letterSpacing: "0.18em" }}>{p.num}</div>
              </div>
              <div style={{ textAlign: "end" }}>
                <div style={{ fontFamily: "var(--ff-display)", fontSize: 18 }}>{fmtNum(p.sold, lang)}</div>
                <div style={{ fontFamily: "var(--ff-mono)", fontSize: 9, color: "var(--olive)", letterSpacing: "0.18em" }}>{lang === "en" ? "sold" : "مباع"}</div>
              </div>
            </div>
          ))}
        </div>

        {/* Most viewed */}
        <div style={{ padding: 22, border: "1px solid var(--line-2)", borderRadius: 14 }}>
          <h3 style={{ fontFamily: "var(--ff-display)", fontSize: 22, marginBottom: 14 }}>{lang === "en" ? "Most viewed pieces" : "الأكثر مشاهدة"}</h3>
          {loading ? <Skeleton h={120} /> : topViewed.length === 0 || topViewed.every(p => !p.viewCount) ? (
            <div style={{ color: "var(--muted)", fontSize: 13 }}>{lang === "en" ? "No view data yet — share your shop to start tracking." : "لا توجد مشاهدات."}</div>
          ) : topViewed.filter(p => p.viewCount > 0).map((p, i) => (
            <div key={i} style={{ display: "flex", justifyContent: "space-between", padding: "10px 0", borderTop: i === 0 ? "none" : "1px solid var(--line-2)" }}>
              <div style={{ fontFamily: "var(--ff-display)", fontSize: 16 }}>{p.name}</div>
              <div style={{ fontFamily: "var(--ff-display)", fontSize: 16 }}>{fmtNum(p.viewCount, lang)}</div>
            </div>
          ))}
        </div>

        {/* Low stock */}
        <div style={{ padding: 22, border: "1px solid var(--line-2)", borderRadius: 14, gridColumn: "span 2" }}>
          <h3 style={{ fontFamily: "var(--ff-display)", fontSize: 22, marginBottom: 14 }}>{lang === "en" ? "Stock attention" : "حالة المخزون"}</h3>
          {lowStock.length === 0 && outOfStock.length === 0 ? (
            <div style={{ color: "var(--olive)", fontSize: 13, display: "inline-flex", alignItems: "center", gap: 6 }}><Icon name="check" size={13} color="var(--olive)" /> {lang === "en" ? "All pieces are in healthy stock." : "كل القطع في حالة جيدة."}</div>
          ) : (
            [...outOfStock, ...lowStock].map((p, i) => (
              <div key={i} style={{ display: "flex", justifyContent: "space-between", padding: "10px 0", borderTop: i === 0 ? "none" : "1px solid var(--line-2)" }}>
                <div>
                  <div style={{ fontFamily: "var(--ff-display)", fontSize: 16 }}>{p.name}</div>
                  <div style={{ fontFamily: "var(--ff-mono)", fontSize: 9, color: "var(--muted)", letterSpacing: "0.18em" }}>{p.num}</div>
                </div>
                <div style={{ fontFamily: "var(--ff-mono)", fontSize: 11, letterSpacing: "0.18em", textTransform: "uppercase", color: p.stock === 0 ? "var(--terracotta)" : "var(--gold)", alignSelf: "center" }}>
                  {p.stock === 0 ? (lang === "en" ? "Out of stock" : "نفد") : `${fmtNum(p.stock, lang)} ${lang === "en" ? "left" : "متبقّي"}`}
                </div>
              </div>
            ))
          )}
        </div>
      </div>
    </div>
  );
}

// ───── Maker workshop card — with expandable attendee roster + attendance marking
function MakerWorkshopCard({ w, lang }) {
  const [expanded, setExpanded] = React.useState(false);
  const [bookings, setBookings] = React.useState([]);
  const [loading, setLoading] = React.useState(false);
  const [busy, setBusy] = React.useState(null);

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

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

  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) { window.toast(makerFail(lang, error.message), { type: "error", lang }); return; }
    load();
  };

  return (
    <div style={{ padding: 22, border: "1px solid var(--line-2)", borderRadius: 14 }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", gap: 10 }}>
        <div style={{ flex: 1 }}>
          <h3 style={{ fontFamily: "var(--ff-display)", fontSize: 22 }}>{w.t}</h3>
          {w.ar && <div className="ar" style={{ fontSize: 14, color: "var(--terracotta)" }}>{w.ar}</div>}
        </div>
        <Pill st={w.st} lang={lang} />
      </div>
      <div style={{ marginTop: 10, fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.2em", textTransform: "uppercase", color: "var(--muted)" }}>
        {window.fmtDateTime(w.starts_at, lang, { weekday: "short", day: "numeric", month: "short", hour: "2-digit", minute: "2-digit" })} · {w.seats} {lang === "en" ? "seats" : "مقاعد"} · {fmtNum(w.occupancy_pct, lang)}%
      </div>
      <div style={{ marginTop: 8, height: 3, background: "var(--paper-2)", borderRadius: 999, overflow: "hidden" }}>
        <div style={{ width: `${w.occupancy_pct}%`, height: "100%", background: w.occupancy_pct >= 100 ? "var(--terracotta)" : "var(--olive)" }} />
      </div>
      {w.rev > 0 && (
        <div style={{ marginTop: 14, fontFamily: "var(--ff-display)", fontSize: 24 }}>
          {fmtNum(w.rev, lang)} {lang === "en" ? "EGP" : "ج.م"}
          <span style={{ fontFamily: "var(--ff-mono)", fontSize: 10, color: "var(--muted)", marginInlineStart: 8 }}>{lang === "en" ? "Booked" : "محجوز"}</span>
        </div>
      )}
      <button onClick={() => setExpanded(e => !e)} style={{ marginTop: 14, width: "100%", background: "transparent", border: "1px solid var(--line)", padding: "8px 12px", borderRadius: 999, cursor: "pointer", fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--ink)" }}>
        {expanded
          ? (lang === "en" ? "Hide attendees ↑" : "إخفاء ↑")
          : (lang === "en" ? `View attendees (${w.seats_taken}) ↓` : `الحضور (${fmtNum(w.seats_taken, lang)}) ↓`)}
      </button>

      {expanded && (
        <div style={{ marginTop: 14, paddingTop: 14, borderTop: "1px solid var(--line-2)" }}>
          {loading && <div style={{ fontFamily: "var(--ff-mono)", fontSize: 10, color: "var(--muted)", textAlign: "center", padding: 20 }}>{lang === "en" ? "Loading…" : "جارٍ التحميل…"}</div>}
          {!loading && bookings.length === 0 && (
            <div style={{ textAlign: "center", padding: 20, color: "var(--muted)", fontSize: 13 }}>
              {lang === "en" ? "No bookings yet." : "لا حجوزات بعد."}
            </div>
          )}
          {bookings.map(b => {
            const name = b.profiles?.full_name || b.guest_name || "—";
            const phone = b.profiles?.phone || b.guest_phone || "";
            const isConfirmed = b.status === "confirmed";
            return (
              <div key={b.id} style={{ padding: "10px 0", borderTop: "1px solid var(--line-2)", display: "grid", gridTemplateColumns: "1fr auto", gap: 8, alignItems: "center" }}>
                <div>
                  <div style={{ fontFamily: "var(--ff-display)", fontSize: 15 }}>{name}</div>
                  <div style={{ fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.18em", color: "var(--muted)" }}>
                    {b.booking_ref} · {fmtNum(b.seats, lang)} {b.seats === 1 ? (lang === "en" ? "seat" : "مقعد") : (lang === "en" ? "seats" : "مقاعد")}{phone ? ` · ${phone}` : ""}
                  </div>
                </div>
                <div style={{ display: "flex", gap: 6, alignItems: "center" }}>
                  <Pill st={isConfirmed ? "Live" : b.status === "attended" ? "Live" : b.status === "waitlisted" ? "Draft" : "Draft"}>
                    {statusText(b.status, lang)}
                  </Pill>
                  {isConfirmed && (
                    <>
                      <button disabled={busy === b.id} onClick={() => markAttendance(b, true)}
                        title={lang === "en" ? "Mark attended" : "حضر"} aria-label={lang === "en" ? "Mark attended" : "تسجيل الحضور"}
                        style={{ background: "var(--olive)", color: "var(--paper)", border: 0, padding: "4px 8px", borderRadius: 999, cursor: "pointer", opacity: busy === b.id ? 0.5 : 1, display: "inline-flex", alignItems: "center", justifyContent: "center" }}>
                        <Icon name="check" size={13} color="var(--paper)" />
                      </button>
                      <button disabled={busy === b.id} onClick={() => markAttendance(b, false)}
                        title={lang === "en" ? "Mark no-show" : "لم يحضر"} aria-label={lang === "en" ? "Mark no-show" : "تسجيل عدم الحضور"}
                        style={{ background: "transparent", color: "var(--terracotta)", border: "1px solid var(--terracotta)", padding: "4px 8px", borderRadius: 999, cursor: "pointer", opacity: busy === b.id ? 0.5 : 1, display: "inline-flex", alignItems: "center", justifyContent: "center" }}>
                        <Icon name="no-water" size={13} color="var(--terracotta)" />
                      </button>
                    </>
                  )}
                </div>
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
}

// ───── WORKSHOP create modal — direct insert as draft ─────────────────
function NewWorkshopModal({ open, onClose, lang, makerId, makerCity, makerGovernorate, onSubmitted }) {
  const [form, setForm] = React.useState({ title_en: "", title_ar: "", starts_at: "", duration: 90, level: "beginner", price: 350, seats_total: 6, address: "", governorate: "" });
  const [status, setStatus] = React.useState("idle");
  const [err, setErr] = React.useState("");
  const set = (k) => (e) => setForm(f => ({ ...f, [k]: e.target.value }));

  // Prefill governorate from the maker's own record (real value, not the city).
  React.useEffect(() => {
    if (open) { setStatus("idle"); setErr(""); setForm(f => ({ ...f, governorate: makerGovernorate || "" })); }
  }, [open, makerGovernorate]);

  const submit = async (e) => {
    e.preventDefault();
    if (!form.title_en || !form.starts_at || !form.price || !form.seats_total) {
      setErr(lang === "en" ? "Title, date/time, price, and seats are required." : "الحقول مطلوبة.");
      return;
    }
    setStatus("submitting"); setErr("");
    const slug = form.title_en.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 60) + "-" + Math.random().toString(36).slice(2, 6);
    const { error } = await window.sb.from("workshops").insert({
      slug,
      host_maker_id: makerId,
      title_en: form.title_en,
      title_ar: form.title_ar || null,
      starts_at: new Date(form.starts_at).toISOString(),
      duration_minutes: Number(form.duration) || 90,
      level: form.level,
      price_piastres: Math.round(Number(form.price) * 100),
      seats_total: Number(form.seats_total),
      seats_taken: 0,
      city_en: makerCity || "Cairo",
      governorate: (form.governorate || makerGovernorate || "").trim() || null,
      address_en: form.address || null,
      is_published: false,  // RLS only allows insert as draft
    });
    if (error) { setErr(makerFail(lang, error.message)); setStatus("error"); return; }
    setStatus("done");
    if (onSubmitted) onSubmitted();
    setTimeout(onClose, 1500);
  };

  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, boxSizing: "border-box" };
  const lbl = { fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--muted)" };

  return (
    <ModalShell open={open} onClose={onClose} width={580}>
      {status === "done" ? (
        <div style={{ textAlign: "center", padding: "20px 0" }}>
          <Star8 size={28} color="var(--olive)" />
          <h2 style={{ fontFamily: "var(--ff-display)", fontSize: 30, marginTop: 14 }}>{lang === "en" ? "Workshop created" : "تمّ الإنشاء"}</h2>
          <p style={{ marginTop: 8, color: "var(--olive)", fontSize: 13 }}>
            {lang === "en" ? "Your workshop is saved as draft. SANAA admins will review and publish it." : "تمّ الحفظ كمسودة."}
          </p>
        </div>
      ) : (
        <form onSubmit={submit}>
          <h2 style={{ fontFamily: "var(--ff-display)", fontSize: 30, marginBottom: 18 }}>{lang === "en" ? "New workshop" : "ورشة جديدة"}</h2>
          <div className="mk-form-2" style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 14 }}>
            <div><label style={lbl}>{lang === "en" ? "Title (English)" : "العنوان (إنجليزي)"} *</label><input required value={form.title_en} onChange={set("title_en")} style={inp} placeholder={lang === "en" ? "An afternoon at the loom" : "An afternoon at the loom"} /></div>
            <div><label style={lbl}>{lang === "en" ? "Title (Arabic)" : "العنوان (عربي)"}</label><input value={form.title_ar} onChange={set("title_ar")} style={inp} dir="rtl" placeholder={lang === "en" ? "أصيلة على النول" : "أصيلة على النول"} /></div>
            <div><label style={lbl}>{lang === "en" ? "Date & time" : "الموعد"} *</label>
              <BrandDateTime
                value={form.starts_at}
                onChange={(v) => setForm(f => ({ ...f, starts_at: v }))}
                lang={lang}
                ariaLabel={lang === "en" ? "Date & time" : "الموعد"}
                placeholder={lang === "en" ? "Pick date & time" : "اختر التاريخ والوقت"}
                style={{ marginTop: 6 }}
              />
            </div>
            <div><label style={lbl}>{lang === "en" ? "Duration (min)" : "المدة (دقيقة)"}</label><input type="number" min="30" value={form.duration} onChange={set("duration")} style={inp} /></div>
            <div><label style={lbl}>{lang === "en" ? "Level" : "المستوى"}</label>
              <BrandSelect
                value={form.level}
                onChange={(v) => setForm(f => ({ ...f, level: v }))}
                options={[
                  { value: "beginner", label: lang === "en" ? "Beginner" : "مبتدئ" },
                  { value: "intermediate", label: lang === "en" ? "Intermediate" : "متوسّط" },
                  { value: "private", label: lang === "en" ? "Private" : "خاص" },
                ]}
                lang={lang} ariaLabel={lang === "en" ? "Level" : "المستوى"}
                style={{ marginTop: 6 }}
              />
            </div>
            <div><label style={lbl}>{lang === "en" ? "Price (EGP)" : "السعر (ج.م)"} *</label><input required type="number" min="0" value={form.price} onChange={set("price")} style={inp} /></div>
            <div><label style={lbl}>{lang === "en" ? "Total seats" : "المقاعد"} *</label><input required type="number" min="1" value={form.seats_total} onChange={set("seats_total")} style={inp} /></div>
            <div><label style={lbl}>{lang === "en" ? "Governorate" : "المحافظة"}</label><input value={form.governorate} onChange={set("governorate")} style={inp} placeholder={lang === "en" ? "Cairo" : "القاهرة"} /></div>
            <div><label style={lbl}>{lang === "en" ? "Location address" : "العنوان"}</label><input value={form.address} onChange={set("address")} style={inp} placeholder={lang === "en" ? "14 Abou el-Feda · Zamalek" : "١٤ أبو الفدا · الزمالك"} /></div>
          </div>
          {err && <div style={{ marginTop: 12, color: "var(--terracotta)", fontSize: 13 }}>{err}</div>}
          <button type="submit" disabled={status === "submitting"} className="btn" style={{ marginTop: 20, opacity: status === "submitting" ? 0.6 : 1 }}>
            {status === "submitting" ? (lang === "en" ? "Saving…" : "جاري الحفظ…") : (lang === "en" ? "Create workshop" : "إنشاء")} →
          </button>
        </form>
      )}
    </ModalShell>
  );
}

// ───── Edit Piece (price/stock change via approval) ──────────────────
// ───── Piece photos: upload via storage + image.add approval request ──
function PiecePhotosModal({ open, onClose, lang, piece, makerId, userId, onSubmitted }) {
  const [imgs, setImgs] = React.useState(null);
  const [pending, setPending] = React.useState([]);
  const [uploading, setUploading] = React.useState(false);
  const [err, setErr] = React.useState("");

  // Resolve a public URL from a storage_path (cached lookup — same value
  // regardless of how many times we call it, but Supabase wraps it in an
  // RPC-like call so we memoise here).
  const publicUrl = React.useCallback((p) => {
    if (!p) return "";
    const { data } = window.sb.storage.from("product-images").getPublicUrl(p);
    return data?.publicUrl || "";
  }, []);

  const refresh = React.useCallback(() => {
    if (!piece?.id) return;
    window.sb.from("product_images")
      .select("id, storage_path, alt_en, alt_ar, is_main, position")
      .eq("product_id", piece.id)
      .order("position", { ascending: true })
      .then(({ data }) => setImgs(data || []));
    window.sb.from("approval_requests")
      .select("id, kind, diff_json, status, created_at")
      .eq("maker_id", makerId)
      .eq("target_id", piece.id)
      .in("kind", ["image.add", "image.remove"])
      .eq("status", "pending")
      .then(({ data }) => setPending(data || []));
  }, [piece?.id, makerId]);

  React.useEffect(() => { if (open) { setErr(""); refresh(); } }, [open, refresh]);

  const onPickFile = async (e) => {
    const file = e.target.files?.[0];
    e.target.value = "";  // reset so the same file can be re-picked
    if (!file || !piece?.id) return;
    if (!/^image\/(jpeg|png|webp|avif)$/.test(file.type)) {
      setErr(lang === "en" ? "Only JPEG, PNG, WebP or AVIF." : "JPEG, PNG, WebP أو AVIF فقط.");
      return;
    }
    if (file.size > 8 * 1024 * 1024) {
      setErr(lang === "en" ? "Max 8 MB per image." : "الحدّ ٨ ميغابايت.");
      return;
    }
    setErr(""); setUploading(true);
    try {
      const ext = (file.name.split(".").pop() || "jpg").toLowerCase();
      const path = `${piece.id}/${Date.now()}-${Math.random().toString(36).slice(2, 8)}.${ext}`;
      const { error: upErr } = await window.sb.storage
        .from("product-images")
        .upload(path, file, { upsert: false, contentType: file.type });
      if (upErr) throw upErr;
      // Submit the image.add approval request. Position = current length so
      // photos queue in upload order until admin reorders. storage_path
      // (not a full URL) is what's stored — the public URL is resolved at
      // render time so we can swap buckets / CDNs later without rewriting
      // every product_images row.
      const nextPos = (imgs || []).length;
      const { error: aErr } = await window.sb.from("approval_requests").insert({
        maker_id: makerId,
        requested_by: userId,
        kind: "image.add",
        target_table: "product_images",
        target_id: piece.id,
        diff_json: { storage_path: path, alt_en: piece.name || "", position: nextPos, is_main: nextPos === 0 },
        note: `Photo for ${piece.num}`,
        priority: "normal",
      });
      if (aErr) throw aErr;
      refresh();
      if (onSubmitted) onSubmitted();
    } catch (ex) {
      setErr(ex.message || "Upload failed");
    } finally {
      setUploading(false);
    }
  };

  const onRemoveExisting = async (img) => {
    if (!piece?.id) return;
    if (!confirm(lang === "en" ? "Submit a request to remove this photo?" : "إرسال طلب لإزالة الصورة؟")) return;
    setErr("");
    const { error } = await window.sb.from("approval_requests").insert({
      maker_id: makerId,
      requested_by: userId,
      kind: "image.remove",
      target_table: "product_images",
      target_id: piece.id,
      diff_json: { image_id: img.id, storage_path: img.storage_path },
      note: `Remove photo from ${piece.num}`,
      priority: "normal",
    });
    if (error) { setErr(makerFail(lang, error.message)); return; }
    refresh();
    if (onSubmitted) onSubmitted();
  };

  return (
    <ModalShell open={open} onClose={onClose} width={620}>
      <div style={{ fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--terracotta)" }}>
        {piece?.num}
      </div>
      <h2 style={{ fontFamily: "var(--ff-display)", fontSize: 30, marginTop: 6, marginBottom: 18, letterSpacing: "-0.01em" }}>
        {lang === "en" ? "Photos for this piece" : "صور القطعة"}
      </h2>

      {imgs === null ? (
        <Skeleton h={140} />
      ) : imgs.length === 0 && pending.length === 0 ? (
        <div style={{ padding: "28px 20px", textAlign: "center", border: "1px dashed var(--line)", borderRadius: 12, background: "var(--paper-2)" }}>
          <Star8 size={18} color="var(--gold-soft)" />
          <div style={{ marginTop: 12, fontSize: 14, color: "var(--olive)", lineHeight: 1.55 }}>
            {lang === "en"
              ? "No photos yet. Upload your best three: a clear hero, the maker's hand at work, and a detail."
              : "لا توجد صور. ارفع ثلاثًا: واضحة، يد الصانع، وتفصيل."}
          </div>
        </div>
      ) : (
        <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(140px, 1fr))", gap: 12 }}>
          {imgs.map((im) => (
            <div key={im.id} style={{ position: "relative", aspectRatio: "1", borderRadius: 10, overflow: "hidden", border: "1px solid var(--line-2)" }}>
              <img src={publicUrl(im.storage_path)} alt={im.alt_en || piece?.name || ""} loading="lazy"
                style={{ width: "100%", height: "100%", objectFit: "cover", display: "block" }} />
              {im.is_main && (
                <span 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>
              )}
              <button onClick={() => onRemoveExisting(im)} aria-label={lang === "en" ? "Request removal" : "اطلب الإزالة"}
                style={{ position: "absolute", top: 8, right: 8, width: 28, height: 28, borderRadius: "50%", background: "rgba(28,26,21,0.7)", color: "var(--paper)", border: 0, cursor: "pointer", fontSize: 14, lineHeight: 1, display: "inline-flex", alignItems: "center", justifyContent: "center" }}>×</button>
            </div>
          ))}
          {pending.filter(p => p.kind === "image.add").map((p) => (
            <div key={p.id} style={{ position: "relative", aspectRatio: "1", borderRadius: 10, overflow: "hidden", border: "1px dashed var(--gold-soft)", background: "var(--paper-2)" }}>
              <img src={publicUrl((p.diff_json || {}).storage_path)} alt={lang === "en" ? "Pending approval" : "بانتظار الموافقة"} loading="lazy"
                style={{ width: "100%", height: "100%", objectFit: "cover", display: "block", opacity: 0.7 }} />
              <span style={{ position: "absolute", bottom: 8, left: 8, fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", color: "var(--ink)", background: "var(--gold-soft)", padding: "3px 8px", borderRadius: 999 }}>
                {lang === "en" ? "PENDING" : "قيد المراجعة"}
              </span>
            </div>
          ))}
        </div>
      )}

      <div style={{ marginTop: 22 }}>
        <label style={{
          display: "inline-flex", alignItems: "center", gap: 8,
          padding: "10px 18px", borderRadius: 999, cursor: uploading ? "wait" : "pointer",
          border: "1px solid var(--ink)", background: uploading ? "var(--paper-2)" : "var(--ink)",
          color: uploading ? "var(--muted)" : "var(--paper)",
          fontFamily: "var(--ff-mono)", fontSize: 11, letterSpacing: "0.2em", textTransform: "uppercase",
        }}>
          <input type="file" accept="image/jpeg,image/png,image/webp,image/avif" onChange={onPickFile}
            disabled={uploading}
            style={{ position: "absolute", width: 1, height: 1, opacity: 0, pointerEvents: "none" }}
            aria-label={lang === "en" ? "Upload a photo" : "ارفع صورة"} />
          {uploading ? (lang === "en" ? "Uploading…" : "جاري الرفع…") : (lang === "en" ? "Upload photo" : "ارفع صورة")} +
        </label>
        <div style={{ marginTop: 10, fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.18em", textTransform: "uppercase", color: "var(--muted)" }}>
          {lang === "en" ? "JPEG · PNG · WebP · AVIF — up to 8 MB" : "JPEG · PNG · WebP · AVIF — حتى ٨م.ب."}
        </div>
        {err && <div style={{ marginTop: 10, color: "var(--terracotta)", fontSize: 13 }}>{err}</div>}
        <div style={{ marginTop: 14, padding: "10px 14px", background: "var(--paper-2)", borderRadius: 8, fontSize: 12, color: "var(--olive)", lineHeight: 1.55 }}>
          {lang === "en"
            ? "Photos go through SANAA review before they appear on the public page. Usually within 24 hours."
            : "تمرّ الصور بمراجعة صَنعة قبل ظهورها للعموم. عادةً خلال ٢٤ ساعة."}
        </div>
      </div>
    </ModalShell>
  );
}

function EditPieceModal({ open, onClose, lang, piece, makerId, userId, onSubmitted }) {
  const [form, setForm] = React.useState({ price: "", stock: "" });
  const [status, setStatus] = React.useState("idle");
  const [err, setErr] = React.useState("");

  React.useEffect(() => {
    if (open && piece) { setForm({ price: String(piece.price), stock: String(piece.stock) }); setStatus("idle"); setErr(""); }
  }, [open, piece?.id]);

  const submit = async (e) => {
    e.preventDefault();
    if (!piece) return;
    const newPrice = Number(form.price);
    const newStock = Number(form.stock);
    if (!Number.isFinite(newPrice) || newPrice <= 0) { setErr(lang === "en" ? "Invalid price." : "سعر غير صحيح."); return; }
    if (!Number.isFinite(newStock) || newStock < 0) { setErr(lang === "en" ? "Invalid stock." : "كمية غير صحيحة."); return; }
    const diff = {};
    // Diff price in piastres against the ORIGINAL stored value (price_piastres),
    // not a rounded EGP echo — avoids drift in the approval record.
    const oldPiastres = piece.price_piastres != null ? piece.price_piastres : Math.round(piece.price * 100);
    const newPiastres = Math.round(newPrice * 100);
    if (newPiastres !== oldPiastres) diff.price_piastres = { old: oldPiastres, new: newPiastres };
    if (newStock !== piece.stock) diff.stock = { old: piece.stock, new: newStock };
    if (Object.keys(diff).length === 0) { setErr(lang === "en" ? "No changes." : "لا توجد تغييرات."); return; }
    setStatus("submitting"); setErr("");
    const kind = diff.price_piastres ? "price.change" : "stock.change";
    const { error } = await window.sb.from("approval_requests").insert({
      maker_id: makerId,
      requested_by: userId,
      kind,
      target_table: "products",
      target_id: piece.id,
      diff_json: diff,
      note: `${kind} for ${piece.num}`,
      priority: "normal",
    });
    if (error) { setErr(makerFail(lang, error.message)); setStatus("error"); return; }
    setStatus("done");
    if (onSubmitted) onSubmitted();
    setTimeout(onClose, 1500);
  };

  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, boxSizing: "border-box" };
  const lbl = { fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--muted)" };

  return (
    <ModalShell open={open} onClose={onClose} width={460}>
      {status === "done" ? (
        <div style={{ textAlign: "center", padding: "10px 0" }}>
          <h2 style={{ fontFamily: "var(--ff-display)", fontSize: 26 }}>{lang === "en" ? "Sent for review" : "أُرسلت"}</h2>
          <p style={{ marginTop: 6, color: "var(--olive)", fontSize: 13 }}>{lang === "en" ? "Admin will approve the change." : "سيقوم المسؤول بالاعتماد."}</p>
        </div>
      ) : (
        <form onSubmit={submit}>
          <h2 style={{ fontFamily: "var(--ff-display)", fontSize: 26, marginBottom: 6 }}>{lang === "en" ? "Edit piece" : "تعديل القطعة"}</h2>
          <p style={{ fontSize: 12, color: "var(--muted)", marginBottom: 18 }}>{piece?.num} · {piece?.name}</p>
          <div className="mk-form-2" style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 14 }}>
            <div><label style={lbl}>{lang === "en" ? "Price (EGP)" : "السعر"}</label><input type="number" min="1" value={form.price} onChange={e => setForm(f => ({ ...f, price: e.target.value }))} style={inp} /></div>
            <div><label style={lbl}>{lang === "en" ? "Stock" : "الكمية"}</label><input type="number" min="0" value={form.stock} onChange={e => setForm(f => ({ ...f, stock: e.target.value }))} style={inp} /></div>
          </div>
          {err && <div style={{ marginTop: 12, color: "var(--terracotta)", fontSize: 13 }}>{err}</div>}
          <button type="submit" disabled={status === "submitting"} className="btn" style={{ marginTop: 18, opacity: status === "submitting" ? 0.6 : 1 }}>
            {status === "submitting" ? "…" : (lang === "en" ? "Submit changes" : "إرسال")} →
          </button>
        </form>
      )}
    </ModalShell>
  );
}

function ProfileEditor({ lang, maker, userId, onSubmitted }) {
  const [form, setForm] = React.useState({
    name_en: maker?.name_en || "",
    name_ar: maker?.name_ar || "",
    city_en: maker?.city_en || "",
    city_ar: maker?.city_ar || "",
    trade_en: maker?.trade_en || "",
    trade_ar: maker?.trade_ar || "",
    story_en: maker?.story_en || "",
    story_ar: maker?.story_ar || "",
    quote_en: maker?.quote_en || "",
    quote_ar: maker?.quote_ar || "",
  });
  const [pending, setPending] = React.useState([]);
  const [status, setStatus] = React.useState("idle"); // idle | submitting | done | error
  const [err, setErr] = React.useState("");
  const set = (k) => (e) => setForm(f => ({ ...f, [k]: e.target.value }));

  React.useEffect(() => {
    if (!maker) return;
    window.sb.from("approval_requests")
      .select("id, kind, status, diff_json, created_at")
      .eq("maker_id", maker.id)
      .eq("kind", "profile.update")
      .eq("status", "pending")
      .then(({ data }) => setPending(data || []));
  }, [maker?.id]);

  const submit = async (e) => {
    e.preventDefault();
    if (!maker) return;
    const diff = {};
    const keys = ["name_en", "name_ar", "city_en", "city_ar", "trade_en", "trade_ar", "story_en", "story_ar", "quote_en", "quote_ar"];
    for (const k of keys) {
      const cur = maker[k] || "";
      const next = form[k] || "";
      if (cur !== next) diff[k] = { old: cur, new: next };
    }
    if (Object.keys(diff).length === 0) {
      setErr(lang === "en" ? "No changes to submit." : "لا توجد تغييرات.");
      return;
    }
    setStatus("submitting"); setErr("");
    const { error } = await window.sb.from("approval_requests").insert({
      maker_id: maker.id,
      requested_by: userId,
      kind: "profile.update",
      target_table: "makers",
      target_id: maker.id,
      diff_json: diff,
      note: "Profile change requested by maker",
      priority: "normal",
    });
    if (error) {
      setErr(makerFail(lang, error.message));
      setStatus("error");
      return;
    }
    setStatus("done");
    if (onSubmitted) onSubmitted();
  };

  if (!maker) return <div style={{ color: "var(--muted)" }}>{lang === "en" ? "Loading…" : "جارٍ التحميل…"}</div>;

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

  return (
    <div>
      <h2 style={{ fontFamily: "var(--ff-display)", fontSize: 40, marginBottom: 16 }}>{lang === "en" ? "Your public page" : "صفحتك العامّة"}</h2>
      <p style={{ marginBottom: 20, fontSize: 13, color: "var(--olive)", maxWidth: 640 }}>
        {lang === "en"
          ? "Edits are reviewed by the SANAA team before going live. Submit a change here to add it to the approval queue."
          : "تُراجع التعديلات من فريق صَنعة قبل النشر. أرسل التغيير هنا ليُضاف لقائمة الموافقات."}
      </p>

      {pending.length > 0 && (
        <div style={{ marginBottom: 20, padding: "12px 16px", background: "rgba(212,170,97,0.14)", borderRadius: 10, fontSize: 13, color: "#7d6635" }}>
          {lang === "en"
            ? `You have ${pending.length} profile change${pending.length === 1 ? "" : "s"} pending review.`
            : `لديك ${fmtNum(pending.length, lang)} تغيير في انتظار المراجعة.`}
        </div>
      )}

      {status === "done" ? (
        <div style={{ padding: "30px 24px", border: "1px solid var(--olive)", borderRadius: 14, background: "rgba(123,132,99,0.08)" }}>
          <div style={{ fontFamily: "var(--ff-display)", fontSize: 24 }}>{lang === "en" ? "Submitted for review." : "أُرسلت للمراجعة."}</div>
          <p style={{ marginTop: 8, color: "var(--olive)" }}>
            {lang === "en" ? "We'll let you know once approved. The current public page stays live until then." : "سنعلمك بمجرد الاعتماد."}
          </p>
          <button type="button" onClick={() => { setStatus("idle"); setErr(""); }} className="btn ghost" style={{ marginTop: 18 }}>
            {lang === "en" ? "Make another edit" : "تعديل آخر"} →
          </button>
        </div>
      ) : (
        <form onSubmit={submit} style={{ padding: 24, border: "1px solid var(--line-2)", borderRadius: 14, display: "grid", gridTemplateColumns: "1fr 1fr", gap: 20 }}>
          <div>
            <label style={lbl}>{lang === "en" ? "Display name (English)" : "الاسم (إنجليزي)"}</label>
            <input value={form.name_en} onChange={set("name_en")} style={inp} />
          </div>
          <div>
            <label style={lbl}>{lang === "en" ? "Display name (Arabic)" : "الاسم (عربي)"}</label>
            <input value={form.name_ar} onChange={set("name_ar")} style={inp} dir="rtl" />
          </div>
          <div>
            <label style={lbl}>{lang === "en" ? "City (English)" : "المدينة (إنجليزي)"}</label>
            <input value={form.city_en} onChange={set("city_en")} style={inp} />
          </div>
          <div>
            <label style={lbl}>{lang === "en" ? "City (Arabic)" : "المدينة (عربي)"}</label>
            <input value={form.city_ar} onChange={set("city_ar")} style={inp} dir="rtl" />
          </div>
          <div>
            <label style={lbl}>{lang === "en" ? "Trade (English)" : "الحرفة (إنجليزي)"}</label>
            <input value={form.trade_en} onChange={set("trade_en")} style={inp} />
          </div>
          <div>
            <label style={lbl}>{lang === "en" ? "Trade (Arabic)" : "الحرفة (عربي)"}</label>
            <input value={form.trade_ar} onChange={set("trade_ar")} style={inp} dir="rtl" />
          </div>
          <div style={{ gridColumn: "span 2" }}>
            <label style={lbl}>{lang === "en" ? "Your story (English)" : "قصّتك (إنجليزي)"}</label>
            <textarea rows={5} value={form.story_en} onChange={set("story_en")} style={{ ...inp, resize: "vertical" }} />
          </div>
          <div style={{ gridColumn: "span 2" }}>
            <label style={lbl}>{lang === "en" ? "Your story (Arabic)" : "قصّتك (عربي)"}</label>
            <textarea rows={5} value={form.story_ar} onChange={set("story_ar")} dir="rtl" style={{ ...inp, resize: "vertical" }} />
          </div>
          <div style={{ gridColumn: "span 2" }}>
            <label style={lbl}>{lang === "en" ? "Quote — one line (English)" : "اقتباس (إنجليزي)"}</label>
            <input value={form.quote_en} onChange={set("quote_en")} style={inp} />
          </div>
          <div style={{ gridColumn: "span 2" }}>
            <label style={lbl}>{lang === "en" ? "Quote — one line (Arabic)" : "اقتباس (عربي)"}</label>
            <input value={form.quote_ar} onChange={set("quote_ar")} style={inp} dir="rtl" />
          </div>
          {err && <div style={{ gridColumn: "span 2", color: "var(--terracotta)", fontSize: 13 }}>{err}</div>}
          <button type="submit" disabled={status === "submitting"} className="btn" style={{ gridColumn: "span 2", justifySelf: "start", opacity: status === "submitting" ? 0.6 : 1 }}>
            {status === "submitting" ? (lang === "en" ? "Submitting…" : "جاري الإرسال…") : (lang === "en" ? "Submit for approval" : "أرسل للمراجعة")} →
          </button>
        </form>
      )}
    </div>
  );
}

function MakerAdminPage({ t, lang }) {
  const [tab, setTab] = React.useState("overview");
  const vw = useWidth();
  const isMobile = vw <= 640;
  const isRtl = lang === "ar";
  const { user, loading: authLoading } = useAuth();
  const [makerProfile, setMakerProfile] = React.useState(null);
  const [livePieces, setLivePieces] = React.useState([]);
  const [liveOrders, setLiveOrders] = React.useState([]);
  const [livePayouts, setLivePayouts] = React.useState([]);
  const [liveWorkshops, setLiveWorkshops] = React.useState([]);
  const [pendingApprovals, setPendingApprovals] = React.useState([]);
  const [profileNotMaker, setProfileNotMaker] = React.useState(false);
  const [reloadKey, setReloadKey] = React.useState(0);
  const [dataLoading, setDataLoading] = React.useState(true);
  const [loadError, setLoadError] = React.useState("");

  // UI state
  const [mobileOpen, setMobileOpen] = React.useState(false);
  const [newPieceOpen, setNewPieceOpen] = React.useState(false);
  const [archiveTarget, setArchiveTarget] = React.useState(null);
  const [editTarget, setEditTarget] = React.useState(null);
  const [photosTarget, setPhotosTarget] = React.useState(null);
  const [orderDetail, setOrderDetail] = React.useState(null);
  const [newWorkshopOpen, setNewWorkshopOpen] = React.useState(false);

  // Listen for cross-component tab change requests
  React.useEffect(() => {
    const onTab = (e) => setTab(e.detail);
    window.addEventListener("maker-tab", onTab);
    return () => window.removeEventListener("maker-tab", onTab);
  }, []);

  React.useEffect(() => {
    if (!user) return;
    let cancelled = false;
    setDataLoading(true);
    setLoadError("");
    (async () => {
      try {
        const { data: prof, error: profErr } = await window.sb.from("profiles").select("maker_id, role").eq("id", user.id).single();
        if (cancelled) return;
        if (profErr) { setLoadError(makerFail(lang, profErr.message)); setDataLoading(false); return; }
        if (!prof || !prof.maker_id || prof.role !== "maker") {
          setProfileNotMaker(true);
          setDataLoading(false);
          return;
        }
        const mid = prof.maker_id;

        // Parallel fetch
        const [makerR, productsR, itemsR, ordersR, payoutsR, workshopsR, approvalsR, analyticsR] = await Promise.all([
          window.sb.from("makers").select("*").eq("id", mid).single(),
          window.sb.from("products").select("*").eq("maker_id", mid).order("created_at", { ascending: false }),
          window.sb.from("order_items").select("*").eq("maker_id", mid),
          // maker_order_list() returns ONLY this maker's orders, projected to
          // ship-to name/city/phone + the maker's own line aggregates — never the
          // buyer email, street address, billing, or internal notes (RLS-safe RPC).
          window.sb.rpc("maker_order_list"),
          window.sb.from("payouts").select("*").eq("maker_id", mid).order("period_start", { ascending: false }),
          window.sb.from("workshops").select("*").eq("host_maker_id", mid).order("starts_at", { ascending: false }),
          window.sb.from("approval_requests").select("id, kind, status, created_at, target_id, diff_json").eq("maker_id", mid).eq("status", "pending"),
          // Real per-product view counts (product_view events). No products.view_count
          // column exists, so we aggregate analytics_events here and merge into pieces.
          window.sb.from("analytics_events").select("event_type, product_id").eq("maker_id", mid),
        ]);
        if (cancelled) return;

        // analytics_events is non-critical: a failure (e.g. RLS) must not block the
        // dashboard — views simply fall back to 0. So it's excluded from firstErr.
        const firstErr = [makerR, productsR, itemsR, ordersR, payoutsR, workshopsR, approvalsR].map(r => r.error?.message).find(Boolean);
        if (firstErr) { setLoadError(makerFail(lang, firstErr)); setDataLoading(false); return; }

        setPendingApprovals(approvalsR.data || []);
        if (makerR.data) setMakerProfile(makerR.data);

      const items = itemsR.data || [];
      const orders = ordersR.data || [];
      const products = productsR.data || [];

      // Build per-product sold count from order_items
      const soldByProduct = {};
      for (const it of items) soldByProduct[it.product_id] = (soldByProduct[it.product_id] || 0) + (it.quantity || 0);

      // Build per-product real view count from analytics_events (product_view).
      const viewsByProduct = {};
      for (const e of (analyticsR.data || [])) {
        if (e.event_type === "product_view" && e.product_id) {
          viewsByProduct[e.product_id] = (viewsByProduct[e.product_id] || 0) + 1;
        }
      }

      setLivePieces(products.map(p => ({
        id: p.id,
        num: p.sku, name: p.name_en, ar: p.name_ar,
        status: p.is_published ? "Live" : "Draft",
        stock: p.stock || 0,
        edition: p.edition_size ? `1 of ${p.edition_size}` : "Open",
        price: Math.round((p.price_piastres || 0) / 100),
        price_piastres: p.price_piastres || 0,
        sold: soldByProduct[p.id] || 0,
        views: viewsByProduct[p.id] || 0,
        tone: makerR.data?.tone || "sand",
      })));

      // Build orders view from the RPC rows (one row per order, this maker's
      // lines only). The buyer column shows the ship-to recipient name; full
      // street/email/billing are never sent to the maker.
      const orderRows = orders.map(o => {
        const gross = o.my_gross_piastres || 0;
        const commissionPct = o.commission_pct ?? 18;
        const split = Math.round(gross * (1 - commissionPct / 100));
        const statusCap = (o.status || "pending").charAt(0).toUpperCase() + (o.status || "pending").slice(1);
        return {
          id: o.order_number,
          order_id: o.order_id,
          makerRef: (o.maker_refs || []).filter(Boolean).join(" · "),
          makerStatus: o.maker_status || null,
          // store raw ISO; localized at render via fmtDate(created_at, lang)
          created_at: o.created_at,
          buyer: o.ship_recipient || (lang === "ar" ? "ضيف" : "Guest"),
          city: o.ship_city || "—",
          // ship-to fields the detail drawer renders (no street, email, or billing)
          shipRecipient: o.ship_recipient || null,
          shipCity: o.ship_city || null,
          shipGovernorate: o.ship_governorate || null,
          shipPhone: o.ship_phone || null,
          piece: (o.piece_names || []).join(", "),
          qty: o.my_qty || 0,
          gross: Math.round(gross / 100), split: Math.round(split / 100),
          status: statusCap,
          _ts: new Date(o.created_at).getTime(),
        };
      }).sort((a, b) => b._ts - a._ts);
      setLiveOrders(orderRows);

      setLivePayouts((payoutsR.data || []).map(p => ({
        // raw ISO values; localized at render via fmtDate(…, lang)
        period_start: p.period_start,
        paid_at: p.paid_at || null,
        gross: Math.round((p.gross_piastres || 0) / 100),
        split: Math.round((p.payout_piastres || 0) / 100),
        status: (p.status || "pending").charAt(0).toUpperCase() + (p.status || "pending").slice(1),
      })));

      setLiveWorkshops((workshopsR.data || []).map(w => {
        const seatsTotal = w.seats_total || 0;
        const seatsTaken = w.seats_taken || 0;
        const occupancyPct = seatsTotal ? Math.round(100 * seatsTaken / seatsTotal) : 0;
        return {
          id: w.id,
          slug: w.slug,
          t: w.title_en, ar: w.title_ar,
          // raw ISO; localized at render via fmtDateTime(starts_at, lang)
          starts_at: w.starts_at,
          seats: `${seatsTaken} / ${seatsTotal}`,
          seats_total: seatsTotal,
          seats_taken: seatsTaken,
          occupancy_pct: occupancyPct,
          rev: Math.round((seatsTaken * (w.price_piastres || 0)) / 100),
          status_key: w.status || (w.is_published ? "published" : "draft"),
          st: ({
            draft: "Draft",
            published: "Live",
            fully_booked: "Full",
            in_progress: "In progress",
            completed: "Completed",
            cancelled: "Cancelled",
            archived: "Archived",
          })[w.status] || (w.is_published ? "Live" : "Draft"),
        };
      }));
        setDataLoading(false);
      } catch (ex) {
        setLoadError(ex.message || "Failed to load");
        setDataLoading(false);
      }
    })();
    return () => { cancelled = true; };
  }, [user && user.id, reloadKey]);

  const refresh = React.useCallback(() => setReloadKey(k => k + 1), []);

  const pieces = livePieces;
  const orders = liveOrders;
  const payouts = livePayouts;
  const workshops = liveWorkshops;
  const [unread, setUnread] = React.useState(0);

  // Fetch total unread message count from conversations
  React.useEffect(() => {
    if (!makerProfile?.id) return;
    window.sb.from("conversations").select("unread_for_maker").eq("maker_id", makerProfile.id)
      .then(({ data }) => setUnread((data || []).reduce((s, c) => s + (c.unread_for_maker || 0), 0)));
  }, [makerProfile?.id, reloadKey, tab]);

  // Compute stats from real orders
  const stats = React.useMemo(() => {
    const now = new Date();
    const thisMonth = orders.filter(o => {
      const d = new Date(o._ts || 0);
      return d.getFullYear() === now.getFullYear() && d.getMonth() === now.getMonth();
    });
    const grossMonth = thisMonth.reduce((s, o) => s + (o.gross || 0), 0);
    const splitMonth = thisMonth.reduce((s, o) => s + (o.split || 0), 0);
    const piecesSold = orders.reduce((s, o) => s + (o.qty || 0), 0);
    const lifetimeGross = orders.reduce((s, o) => s + (o.gross || 0), 0);
    const lifetimeSplit = orders.reduce((s, o) => s + (o.split || 0), 0);
    // "Pending payout" = amounts genuinely still owed. Only Pending/Approved
    // cycles count; terminal states (Paid, and defensively Cancelled/Failed) are
    // excluded so a closed-out non-paid cycle never inflates what's owed.
    const owedStatuses = new Set(["Pending", "Approved"]);
    return {
      grossMonth, splitMonth, piecesSold, lifetimeGross, lifetimeSplit,
      pendingPayout: payouts.filter(p => owedStatuses.has(p.status)).reduce((s, p) => s + p.split, 0),
    };
  }, [orders, payouts]);

  if (authLoading) return (
    <div style={{ padding: "120px 0", textAlign: "center", color: "var(--muted)", fontFamily: "var(--ff-mono)", fontSize: 12 }}>
      {lang === "en" ? "Loading…" : "جارٍ التحميل…"}
    </div>
  );

  if (!user) return (
    <>
      <Breadcrumbs crumbs={[{ label: lang === "en" ? "Makers" : "الصنّاع", to: "/makers" }, { label: lang === "en" ? "Admin" : "الإدارة" }]} lang={lang} />
      <section style={{ padding: "120px 0", background: "var(--paper)", textAlign: "center" }}>
        <div className="container" style={{ maxWidth: 480 }}>
          <Star8 size={32} color="var(--terracotta)" />
          <h1 style={{ fontFamily: "var(--ff-display)", fontSize: 48, marginTop: 20 }}>
            {lang === "en" ? "Sign in to continue." : "سجّل الدخول للمتابعة."}
          </h1>
          <p style={{ marginTop: 16, color: "var(--olive)", fontSize: 15 }}>
            {lang === "en" ? "The maker portal is only available to registered makers." : "بوّابة الصانع للصنّاع المسجّلين فقط."}
          </p>
          <a href="#/account" className="btn" style={{ display: "inline-flex", marginTop: 24 }}>{lang === "en" ? "Go to account" : "الحساب"} →</a>
        </div>
      </section>
    </>
  );

  if (profileNotMaker) return (
    <>
      <Breadcrumbs crumbs={[{ label: lang === "en" ? "Makers" : "الصنّاع", to: "/makers" }, { label: lang === "en" ? "Admin" : "الإدارة" }]} lang={lang} />
      <section style={{ padding: "120px 0", background: "var(--paper)", textAlign: "center" }}>
        <div className="container" style={{ maxWidth: 480 }}>
          <Star8 size={32} color="var(--terracotta)" />
          <h1 style={{ fontFamily: "var(--ff-display)", fontSize: 48, marginTop: 20 }}>
            {lang === "en" ? "Not a maker account." : "ليس حساب صانع."}
          </h1>
          <p style={{ marginTop: 16, color: "var(--olive)", fontSize: 15 }}>
            {lang === "en" ? "This portal is only available to registered makers. Apply to join the house." : "هذه البوّابة للصنّاع المسجّلين فقط."}
          </p>
          <div style={{ marginTop: 24, display: "flex", gap: 10, justifyContent: "center" }}>
            <a href="#/makers/apply" className="btn">{lang === "en" ? "Apply now" : "قدّم الآن"} →</a>
            <a href="#/" className="btn ghost">{lang === "en" ? "Back home" : "للرئيسية"}</a>
          </div>
        </div>
      </section>
    </>
  );

  // Loading skeleton while fetching maker profile
  if (!makerProfile) return (
    <>
      <Breadcrumbs crumbs={[{ label: lang === "en" ? "Makers" : "الصنّاع", to: "/makers" }, { label: lang === "en" ? "Admin" : "الإدارة" }]} lang={lang} />
      <section style={{ padding: "60px 0", background: "var(--paper)" }}>
        <div className="container-wide">
          <div className="maker-grid">
            <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
              {[...Array(9)].map((_, i) => <Skeleton key={i} h={36} />)}
            </div>
            <div className="stat-grid-4">
              {[...Array(4)].map((_, i) => <StatSkeleton key={i} />)}
            </div>
          </div>
        </div>
      </section>
    </>
  );

  if (loadError) return (
    <section style={{ padding: "120px 0", background: "var(--paper)", textAlign: "center" }}>
      <div className="container" style={{ maxWidth: 480 }}>
        <Star8 size={32} color="var(--terracotta)" />
        <h1 style={{ fontFamily: "var(--ff-display)", fontSize: 36, marginTop: 20 }}>{lang === "en" ? "Could not load your dashboard." : "تعذّر تحميل اللوحة."}</h1>
        <p style={{ marginTop: 12, color: "var(--terracotta)", fontFamily: "var(--ff-mono)", fontSize: 12 }}>{loadError}</p>
        <button className="btn" onClick={refresh} style={{ marginTop: 24 }}>{lang === "en" ? "Retry" : "إعادة"}</button>
      </div>
    </section>
  );

  // makerProfile is guaranteed non-null past this point
  const me = {
    name: makerProfile.name_en || "",
    ar: makerProfile.name_ar || "",
    slug: makerProfile.slug,
    code: makerProfile.maker_code || null,
    // Header chrome localizes city/trade; AR falls back to the EN value when the
    // Arabic column is empty (do not show the EN string when AR exists).
    city: (lang === "ar" ? (makerProfile.city_ar || makerProfile.city_en) : makerProfile.city_en),
    trade: (lang === "ar" ? (makerProfile.trade_ar || makerProfile.trade_en) : makerProfile.trade_en),
    since: makerProfile.since_year,
    avatar_tone: makerProfile.tone || "sand",
    suspended: makerProfile.is_published === false,
    tier: makerProfile.is_published === false ? "Suspended" : (makerProfile.rubric_score >= 90 ? "Senior Master" : makerProfile.rubric_score >= 80 ? "Verified House" : "Emerging"),
    split: 100 - (makerProfile.commission_pct || 18),
    rubric: makerProfile.rubric_score ?? null,
    email: user ? user.email : "",
    phone: "", bank: "", tax_id: "", address: "",
  };

  const NAV = [
    { k: "overview", l: lang === "en" ? "Overview" : "النظرة العامة" },
    { k: "pieces", l: lang === "en" ? "Pieces" : "القطع", c: pieces.length },
    { k: "orders", l: lang === "en" ? "Orders" : "الطلبات", c: orders.length },
    { k: "payouts", l: lang === "en" ? "Earnings" : "الأرباح" },
    { k: "analytics", l: lang === "en" ? "Analytics" : "التحليلات" },
    { k: "messages", l: lang === "en" ? "Inbox" : "صندوق الرسائل", c: unread, badge: true },
    { k: "workshops", l: lang === "en" ? "My workshops" : "ورشي" },
    { k: "profile", l: lang === "en" ? "Public profile" : "الصفحة العامّة" },
    { k: "settings", l: lang === "en" ? "Settings" : "الإعدادات" },
  ];

  return (
    <div dir={isRtl ? "rtl" : "ltr"}>
      <Breadcrumbs crumbs={[
        { label: lang === "en" ? "Makers" : "الصنّاع", to: "/makers" },
        { label: lang === "en" ? `Admin · ${me.name.split(" ")[0]}` : `الإدارة · ${me.ar ? me.ar.split(" ")[0] : ""}` },
      ]} lang={lang} />

      <section style={{ background: "var(--paper-2)", borderBottom: "1px solid var(--line-2)", padding: "28px 0" }}>
        <div className="container-wide" style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
          <div style={{ display: "flex", gap: 18, alignItems: "center" }}>
            <div style={{ width: 64, height: 64, borderRadius: "50%", overflow: "hidden", flexShrink: 0 }}>
              <Placeholder tone={me.avatar_tone} label={me.name.split(" ")[0].toLowerCase()} />
            </div>
            <div>
              <div style={{ fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--terracotta)" }}>
                {lang === "en" ? "Maker admin · Signed in" : "لوحة الصانع · مسجّل"}
              </div>
              <div style={{ display: "flex", alignItems: "baseline", gap: 12, marginTop: 6, flexWrap: "wrap" }}>
                <h1 style={{ fontFamily: "var(--ff-display)", fontSize: 36, lineHeight: 1 }}>{me.name}</h1>
                <span className="ar" style={{ fontSize: 20, color: "var(--terracotta)" }}>{me.ar}</span>
                {me.code && (
                  <span
                    title={lang === "en" ? "Your permanent maker code" : "رمزك التشغيلي الدائم"}
                    style={{ fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.22em", color: "var(--paper)", background: "var(--ink)", padding: "4px 10px", borderRadius: 999 }}
                  >
                    {me.code}
                  </span>
                )}
              </div>
              <div style={{ marginTop: 6, fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.2em", textTransform: "uppercase", color: "var(--muted)" }}>
                {me.trade} · {me.city} · {lang === "en" ? `Maker since ${me.since}` : `منذ ${me.since}`}
              </div>
            </div>
          </div>
          <div className="maker-header-cta" style={{ display: "flex", gap: 10, alignItems: "center" }}>
            <Pill st={me.suspended ? "Suspended" : "Live"}>{statusText(me.tier, lang)}</Pill>
            <a className="btn ghost" href={"#/makers/" + me.slug}>{lang === "en" ? "View public profile" : "الصفحة العامّة"} →</a>
            <button onClick={() => setNewPieceOpen(true)} className="btn">{lang === "en" ? "Upload new piece" : "ارفع قطعة"} +</button>
          </div>
        </div>
        {pendingApprovals.length > 0 && (
          <div className="container-wide" style={{ marginTop: 14 }}>
            <div style={{ padding: "10px 16px", background: "rgba(212,170,97,0.18)", borderRadius: 10, fontSize: 13, color: "#7d6635", fontFamily: "var(--ff-sans)" }}>
              ◆ {lang === "en"
                ? `You have ${pendingApprovals.length} change${pendingApprovals.length === 1 ? "" : "s"} pending review.`
                : `لديك ${fmtNum(pendingApprovals.length, lang)} تغيير في انتظار المراجعة.`}
            </div>
          </div>
        )}
      </section>

      <section style={{ padding: "40px 0 120px", background: "var(--paper)" }}>
        <div className="container-wide maker-grid">
          {/* Mobile burger */}
          <button className="maker-burger" onClick={() => setMobileOpen(true)} style={{ marginBottom: 12 }}>
            ≡ {lang === "en" ? "Menu" : "القائمة"}
          </button>
          {mobileOpen && <div onClick={() => setMobileOpen(false)} style={{ position: "fixed", inset: 0, background: "rgba(28,26,21,0.5)", zIndex: 94 }} />}
          {/* Side nav */}
          <aside className={"maker-aside" + (mobileOpen ? " open" : "")} style={{ position: "sticky", top: 130, alignSelf: "start", display: "flex", flexDirection: "column", gap: 2 }}>
            {NAV.map(n => (
              <button key={n.k} onClick={() => { setTab(n.k); setMobileOpen(false); }} style={{
                textAlign: "start", padding: "12px 16px", borderRadius: 10,
                background: tab === n.k ? "var(--ink)" : "transparent",
                color: tab === n.k ? "var(--paper)" : "var(--ink)",
                border: 0, cursor: "pointer", fontFamily: "var(--ff-sans)", fontSize: 14,
                display: "flex", justifyContent: "space-between", alignItems: "center",
              }}>
                <span>{n.l}</span>
                {n.c != null && (n.badge && n.c > 0 ? (
                  <span style={{ background: "var(--terracotta)", color: "var(--paper)", borderRadius: 999, padding: "2px 8px", fontFamily: "var(--ff-mono)", fontSize: 9 }}>{fmtNum(n.c, lang)}</span>
                ) : (
                  <span style={{ fontFamily: "var(--ff-mono)", fontSize: 10, opacity: 0.5 }}>{fmtNum(n.c, lang)}</span>
                ))}
              </button>
            ))}
            <div style={{ marginTop: 20, padding: "16px 16px", background: "var(--paper-2)", borderRadius: 10, fontSize: 12, color: "var(--olive)", display: "flex", gap: 14, alignItems: "center" }}>
              <RubricGauge score={me.rubric} lang={lang} />
              <div>
                <Star8 size={12} color="var(--gold)" />
                <div style={{ marginTop: 8, fontFamily: "var(--ff-display)", fontSize: 16, color: "var(--ink)" }}>{lang === "en" ? "Quality score" : "معيار الجودة"}</div>
                <div style={{ marginTop: 4, fontSize: 11, color: "var(--muted)", lineHeight: 1.45 }}>
                  {lang === "en" ? "Set by SANAA review" : "يحدّده فريق صَنعة"}
                </div>
              </div>
            </div>
          </aside>

          <div>
            {/* ——— OVERVIEW ——— */}
            {tab === "overview" && (
              <div style={{ display: "flex", flexDirection: "column", gap: 30 }}>
                <div className="stat-grid-4">
                  <StatCard label={lang === "en" ? "Revenue · this month" : "الإيراد · الشهر"} value={fmtNum(stats.grossMonth, lang)} sub="EGP" />
                  <StatCard label={lang === "en" ? `Your split (${me.split}%)` : `حصّتك (${fmtNum(me.split, lang)}٪)`} value={fmtNum(stats.splitMonth, lang)} sub={lang === "en" ? "EGP this month" : "ج.م هذا الشهر"} />
                  <StatCard label={lang === "en" ? "Pieces sold (lifetime)" : "قطع مباعة"} value={fmtNum(stats.piecesSold, lang)} sub={lang === "en" ? `${orders.length} orders` : `${fmtNum(orders.length, lang)} طلب`} />
                  <StatCard label={lang === "en" ? "Live pieces" : "قطع منشورة"} value={fmtNum(pieces.filter(p => p.status === "Live").length, lang)} sub={lang === "en" ? `${pieces.length} total` : `${fmtNum(pieces.length, lang)} إجمالًا`} />
                </div>

                <div className="bigsplit-1614" style={{ gap: 28 }}>
                  {/* 6-month earnings chart from real orders */}
                  <div style={{ padding: 28, border: "1px solid var(--line-2)", borderRadius: 14 }}>
                    <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 22 }}>
                      <h3 style={{ fontFamily: "var(--ff-display)", fontSize: 24 }}>{lang === "en" ? "Earnings · last 6 months" : "الأرباح · آخر ٦ شهور"}</h3>
                      <div style={{ fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.2em", color: "var(--muted)" }}>EGP</div>
                    </div>
                    {(() => {
                      const buckets = [];
                      const now = new Date();
                      for (let i = 5; i >= 0; i--) {
                        const d = new Date(now.getFullYear(), now.getMonth() - i, 1);
                        buckets.push({ d, m: window.fmtDate(d.toISOString(), lang, { month: "short" }), v: 0 });
                      }
                      for (const o of orders) {
                        const od = new Date(o._ts);
                        for (const b of buckets) {
                          if (od.getFullYear() === b.d.getFullYear() && od.getMonth() === b.d.getMonth()) {
                            b.v += o.split || 0;
                            break;
                          }
                        }
                      }
                      const hasData = buckets.some(b => b.v > 0);
                      const max = Math.max(1, ...buckets.map(b => b.v));
                      const PLOT = 150;  // px of plot height the tallest bar fills
                      return (
                        <div style={{ position: "relative" }}>
                          {/* max-value reference gridline + label */}
                          <div style={{ position: "relative", height: PLOT + 4 }}>
                            <div style={{ position: "absolute", insetInlineStart: 0, insetInlineEnd: 0, top: 0, borderTop: "1px dashed var(--line)", pointerEvents: "none" }} />
                            <div style={{ position: "absolute", insetInlineEnd: 0, top: -16, fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.18em", color: "var(--muted)" }}>
                              {lang === "en" ? "max " : "أقصى "}{fmtNum(max, lang)}
                            </div>
                            {/* bars sit on the baseline */}
                            <div style={{ position: "absolute", insetInlineStart: 0, insetInlineEnd: 0, bottom: 0, display: "flex", alignItems: "flex-end", gap: 14, height: PLOT }}>
                              {buckets.map((b, i) => (
                                <div key={i} style={{ flex: 1, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "flex-end", gap: 6, height: "100%" }}>
                                  <div style={{ fontFamily: "var(--ff-mono)", fontSize: 9, color: "var(--muted)", minHeight: 12 }}>{b.v ? fmtNum(b.v, lang) : ""}</div>
                                  {/* a value bar, or a visible zero-height tick for empty months */}
                                  {b.v > 0 ? (
                                    <div style={{ width: "100%", background: i === 5 ? "var(--terracotta)" : "var(--ink)", height: Math.max(4, (b.v / max) * (PLOT - 16)), borderRadius: "6px 6px 0 0", opacity: i === 5 ? 1 : 0.85 }} />
                                  ) : (
                                    <div title={lang === "en" ? "No earnings" : "لا أرباح"} style={{ width: "100%", height: 3, background: "var(--line)", borderRadius: 2 }} />
                                  )}
                                </div>
                              ))}
                            </div>
                          </div>
                          {/* solid baseline */}
                          <div style={{ borderTop: "1px solid var(--line-2)" }} />
                          {/* month labels */}
                          <div style={{ display: "flex", gap: 14, marginTop: 8 }}>
                            {buckets.map((b, i) => (
                              <div key={i} style={{ flex: 1, textAlign: "center", fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.18em", textTransform: "uppercase", color: i === 5 ? "var(--terracotta)" : "var(--muted)" }}>{b.m}</div>
                            ))}
                          </div>
                          {!hasData && (
                            <div style={{ marginTop: 12, textAlign: "center", fontSize: 12, color: "var(--muted)", fontStyle: "italic" }}>
                              {lang === "en" ? "No earnings in the last six months yet." : "لا أرباح في آخر ستة شهور بعد."}
                            </div>
                          )}
                        </div>
                      );
                    })()}
                  </div>

                  {/* To-dos generated from real data */}
                  <div style={{ padding: 28, border: "1px solid var(--line-2)", borderRadius: 14 }}>
                    <h3 style={{ fontFamily: "var(--ff-display)", fontSize: 24, marginBottom: 16 }}>{lang === "en" ? "Needs your attention" : "يحتاج انتباهك"}</h3>
                    {(() => {
                      const todos = [];
                      const lowStock = pieces.filter(p => p.status === "Live" && p.stock > 0 && p.stock <= 2);
                      for (const p of lowStock) todos.push({ t: lang === "en" ? `Restock ${p.num} — ${p.stock} left` : `إعادة تجهيز ${p.num} — ${fmtNum(p.stock, lang)} متبقّي`, meta: lang === "en" ? "Low" : "منخفض", tone: "terracotta" });
                      const drafts = pieces.filter(p => p.status === "Draft");
                      for (const p of drafts.slice(0, 2)) todos.push({ t: lang === "en" ? `Finish draft — ${p.name}` : `أنهِ مسودّة ${p.name}`, meta: lang === "en" ? "Draft" : "مسودّة", tone: "olive" });
                      const pendingOrders = orders.filter(o => o.status === "Pending" || o.status === "Confirmed");
                      for (const o of pendingOrders.slice(0, 2)) todos.push({ t: lang === "en" ? `Pack order ${o.id}` : `جهّز طلب ${o.id}`, meta: window.fmtDate(o.created_at, lang, { day: "numeric", month: "short" }), tone: "gold" });
                      if (todos.length === 0) todos.push({ t: lang === "en" ? "All clear — nothing pending." : "كل شيء على ما يرام.", meta: "—", tone: "olive" });
                      return todos.slice(0, 6).map((i, k) => (
                        <div key={k} style={{ display: "flex", justifyContent: "space-between", alignItems: "center", padding: "12px 0", borderTop: k === 0 ? "none" : "1px solid var(--line-2)" }}>
                          <div style={{ display: "flex", gap: 12, alignItems: "flex-start", minWidth: 0 }}>
                            <div style={{ width: 8, height: 8, borderRadius: "50%", background: `var(--${i.tone})`, flexShrink: 0, marginTop: 5 }} />
                            <div style={{ fontSize: 14, overflow: "hidden", display: "-webkit-box", WebkitLineClamp: 2, WebkitBoxOrient: "vertical", lineHeight: 1.4 }}>{i.t}</div>
                          </div>
                          <div style={{ fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.2em", textTransform: "uppercase", color: "var(--muted)", flexShrink: 0, marginInlineStart: 10 }}>{i.meta}</div>
                        </div>
                      ));
                    })()}
                  </div>
                </div>

                {/* Top pieces */}
                <div>
                  <h3 style={{ fontFamily: "var(--ff-display)", fontSize: 28, marginBottom: 18 }}>{lang === "en" ? "Your top pieces" : "أهم قطعك"}</h3>
                  <div className="stat-grid-4" style={{ gap: 18 }}>
                    {pieces.slice(0, 4).map((p, i) => (
                      <div key={i} style={{ border: "1px solid var(--line-2)", borderRadius: 12, overflow: "hidden" }}>
                        <div style={{ aspectRatio: "1" }}><Placeholder tone={p.tone} label={p.name.toLowerCase()} meta={p.num} /></div>
                        <div style={{ padding: 14 }}>
                          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline" }}>
                            <div style={{ fontFamily: "var(--ff-display)", fontSize: 18 }}>{p.name}</div>
                            <Pill st={p.status} lang={lang} />
                          </div>
                          <div style={{ marginTop: 8, display: "flex", justifyContent: "space-between", fontFamily: "var(--ff-mono)", fontSize: 10, letterSpacing: "0.2em", textTransform: "uppercase", color: "var(--muted)" }}>
                            <span>{fmtNum(p.sold, lang)} {lang === "en" ? "sold" : "مُباع"}</span><span>{fmtNum(p.views, lang)} {lang === "en" ? "views" : "مشاهدة"}</span>
                          </div>
                        </div>
                      </div>
                    ))}
                  </div>
                </div>
              </div>
            )}

            {/* ——— PIECES ——— */}
            {tab === "pieces" && (
              <div>
                <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 20 }}>
                  <h2 style={{ fontFamily: "var(--ff-display)", fontSize: 40 }}>{lang === "en" ? "Your pieces" : "قطعك"} <span style={{ fontFamily: "var(--ff-mono)", fontSize: 12, color: "var(--muted)" }}>({fmtNum(pieces.length, lang)})</span></h2>
                  <button className="btn" onClick={() => setNewPieceOpen(true)}>+ {lang === "en" ? "New piece" : "قطعة"}</button>
                </div>
                {pieces.length === 0 ? (
                  <div style={{ padding: "60px 20px", textAlign: "center", border: "1px dashed var(--line)", borderRadius: 14 }}>
                    <Star8 size={20} color="var(--gold-soft)" />
                    <div style={{ marginTop: 14, fontFamily: "var(--ff-display)", fontSize: 22, color: "var(--ink)" }}>
                      {lang === "en" ? "No pieces yet." : "لا توجد قطع بعد."}
                    </div>
                  </div>
                ) : isMobile ? (
                  /* Stacked card layout — no horizontal scroll on phones */
                  <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
                    {pieces.map((p, i) => {
                      const productId = p.id;
                      const kv = (label, val) => (
                        <div style={{ display: "flex", justifyContent: "space-between", gap: 10, padding: "6px 0", borderTop: "1px solid var(--line-2)" }}>
                          <span style={{ fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--muted)" }}>{label}</span>
                          <span style={{ fontSize: 14 }}>{val}</span>
                        </div>
                      );
                      return (
                        <div key={i} style={{ border: "1px solid var(--line-2)", borderRadius: 14, padding: 16, background: "var(--paper)" }}>
                          <div style={{ display: "flex", gap: 12, alignItems: "center" }}>
                            <div style={{ width: 52, height: 52, borderRadius: 8, overflow: "hidden", flexShrink: 0 }}><Placeholder tone={p.tone} label={p.num.toLowerCase()} /></div>
                            <div style={{ minWidth: 0, flex: 1 }}>
                              <div style={{ fontFamily: "var(--ff-display)", fontSize: 18 }}>{p.name}</div>
                              <div style={{ fontFamily: "var(--ff-mono)", fontSize: 9, color: "var(--muted)", letterSpacing: "0.2em" }}>{p.num} · {p.edition}</div>
                            </div>
                            <Pill st={p.status} lang={lang} />
                          </div>
                          <div style={{ marginTop: 12 }}>
                            {kv(lang === "en" ? "Stock" : "المخزون", fmtNum(p.stock, lang))}
                            {kv(lang === "en" ? "Price" : "السعر", `${fmtNum(p.price, lang)} ${lang === "en" ? "EGP" : "ج.م"}`)}
                            {kv(lang === "en" ? "Sold" : "المُباع", fmtNum(p.sold, lang))}
                            {kv(lang === "en" ? "Views" : "المشاهدات", fmtNum(p.views, lang))}
                          </div>
                          <div style={{ display: "flex", gap: 8, marginTop: 14 }}>
                            <button onClick={() => productId && setPhotosTarget({ ...p, id: productId })} style={{ flex: 1, background: "transparent", border: "1px solid var(--line)", borderRadius: 999, padding: "8px 10px", cursor: "pointer", color: "var(--ink)", display: "inline-flex", alignItems: "center", justifyContent: "center", gap: 6, fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.18em", textTransform: "uppercase" }} aria-label={lang === "en" ? "Manage photos" : "إدارة الصور"}><Icon name="eye" size={14} /> {lang === "en" ? "Photos" : "الصور"}</button>
                            <button onClick={() => productId && setEditTarget({ ...p, id: productId })} style={{ flex: 1, background: "transparent", border: "1px solid var(--line)", borderRadius: 999, padding: "8px 10px", cursor: "pointer", color: "var(--ink)", display: "inline-flex", alignItems: "center", justifyContent: "center", gap: 6, fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.18em", textTransform: "uppercase" }} aria-label={lang === "en" ? "Edit price and stock" : "تعديل السعر والمخزون"}><Icon name="feather" size={14} /> {lang === "en" ? "Edit" : "تعديل"}</button>
                            <button disabled={p.status !== "Live"} onClick={() => productId && setArchiveTarget({ ...p, id: productId })} style={{ background: "transparent", border: "1px solid var(--line)", borderRadius: 999, padding: "8px 12px", cursor: p.status === "Live" ? "pointer" : "not-allowed", color: "var(--terracotta)", opacity: p.status === "Live" ? 1 : 0.4, display: "inline-flex", alignItems: "center", justifyContent: "center" }} aria-label={lang === "en" ? "Archive piece" : "أرشفة القطعة"}><Icon name="box" size={14} /></button>
                          </div>
                        </div>
                      );
                    })}
                  </div>
                ) : (
                <div style={{ border: "1px solid var(--line-2)", borderRadius: 14, overflow: "hidden" }}>
                  <div className="mk-tbl" style={{ display: "grid", gridTemplateColumns: "80px 1.4fr 0.7fr 0.7fr 0.7fr 0.7fr 0.8fr 100px", padding: "14px 20px", background: "var(--paper-2)", fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--muted)" }}>
                    <div></div><div>{lang === "en" ? "Piece" : "القطعة"}</div><div>{lang === "en" ? "Status" : "الحالة"}</div><div>{lang === "en" ? "Stock" : "المخزون"}</div><div>{lang === "en" ? "Price" : "السعر"}</div><div>{lang === "en" ? "Sold" : "المُباع"}</div><div>{lang === "en" ? "Views" : "المشاهدات"}</div><div></div>
                  </div>
                  {pieces.map((p, i) => {
                    const productId = p.id;
                    return (
                    <div key={i} className="mk-tbl" style={{ display: "grid", gridTemplateColumns: "80px 1.4fr 0.7fr 0.7fr 0.7fr 0.7fr 0.8fr 100px", padding: "14px 20px", borderTop: "1px solid var(--line-2)", alignItems: "center", background: "var(--paper)" }}>
                      <div style={{ width: 56, height: 56, borderRadius: 8, overflow: "hidden" }}><Placeholder tone={p.tone} label={p.num.toLowerCase()} /></div>
                      <div>
                        <div style={{ fontFamily: "var(--ff-display)", fontSize: 18 }}>{p.name}</div>
                        <div style={{ fontFamily: "var(--ff-mono)", fontSize: 9, color: "var(--muted)", letterSpacing: "0.2em" }}>{p.num} · {p.edition}</div>
                      </div>
                      <Pill st={p.status} lang={lang} />
                      <div style={{ fontSize: 14 }}>{fmtNum(p.stock, lang)}</div>
                      <div style={{ fontFamily: "var(--ff-display)", fontSize: 18 }}>{fmtNum(p.price, lang)}</div>
                      <div style={{ fontSize: 14 }}>{fmtNum(p.sold, lang)}</div>
                      <div style={{ fontSize: 14 }}>{fmtNum(p.views, lang)}</div>
                      <div style={{ display: "flex", gap: 6, justifyContent: "flex-end" }}>
                        <button title={lang === "en" ? "Photos" : "الصور"} onClick={() => productId && setPhotosTarget({ ...p, id: productId })} style={{ background: "transparent", border: "1px solid var(--line)", borderRadius: 999, padding: "4px 10px", cursor: "pointer", color: "var(--ink)", minWidth: 32, display: "inline-flex", alignItems: "center", justifyContent: "center" }} aria-label={lang === "en" ? "Manage photos" : "إدارة الصور"}><Icon name="eye" size={14} /></button>
                        <button title={lang === "en" ? "Edit price/stock" : "تعديل"} onClick={() => productId && setEditTarget({ ...p, id: productId })} style={{ background: "transparent", border: "1px solid var(--line)", borderRadius: 999, padding: "4px 10px", cursor: "pointer", color: "var(--ink)", display: "inline-flex", alignItems: "center", justifyContent: "center" }} aria-label={lang === "en" ? "Edit price and stock" : "تعديل السعر والمخزون"}><Icon name="feather" size={14} /></button>
                        <button title={lang === "en" ? "Archive (request)" : "أرشفة"} disabled={p.status !== "Live"} onClick={() => productId && setArchiveTarget({ ...p, id: productId })} style={{ background: "transparent", border: "1px solid var(--line)", borderRadius: 999, padding: "4px 10px", cursor: p.status === "Live" ? "pointer" : "not-allowed", color: "var(--terracotta)", opacity: p.status === "Live" ? 1 : 0.4, display: "inline-flex", alignItems: "center", justifyContent: "center" }} aria-label={lang === "en" ? "Archive piece" : "أرشفة القطعة"}><Icon name="box" size={14} /></button>
                      </div>
                    </div>
                    );
                  })}
                </div>
                )}
              </div>
            )}

            {/* ——— ORDERS ——— */}
            {tab === "orders" && (
              <div>
                <h2 style={{ fontFamily: "var(--ff-display)", fontSize: 40, marginBottom: 20 }}>
                  {lang === "en" ? "Orders for you" : "طلباتك"}
                  <span style={{ fontFamily: "var(--ff-mono)", fontSize: 12, color: "var(--muted)", marginInlineStart: 12 }}>({fmtNum(orders.length, lang)})</span>
                </h2>
                {orders.length === 0 ? (
                  <div style={{ padding: "60px 20px", textAlign: "center", border: "1px dashed var(--line)", borderRadius: 14 }}>
                    <Star8 size={20} color="var(--gold-soft)" />
                    <div style={{ marginTop: 14, fontFamily: "var(--ff-display)", fontSize: 22, color: "var(--ink)" }}>
                      {lang === "en" ? "No orders yet." : "لا توجد طلبات بعد."}
                    </div>
                    <div style={{ marginTop: 6, fontSize: 13, color: "var(--muted)" }}>
                      {lang === "en" ? "Orders containing your pieces will appear here." : "ستظهر الطلبات التي تحتوي على قطعك هنا."}
                    </div>
                  </div>
                ) : isMobile ? (
                  /* Stacked card layout — no horizontal scroll on phones */
                  <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
                    {orders.map((o, i) => {
                      const kv = (label, val) => (
                        <div style={{ display: "flex", justifyContent: "space-between", gap: 10, padding: "6px 0", borderTop: "1px solid var(--line-2)" }}>
                          <span style={{ fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--muted)" }}>{label}</span>
                          <span style={{ fontSize: 14, textAlign: "end", minWidth: 0 }}>{val}</span>
                        </div>
                      );
                      return (
                        <button key={i} type="button" onClick={() => setOrderDetail(o)}
                          style={{ display: "block", width: "100%", textAlign: "start", border: "1px solid var(--line-2)", borderRadius: 14, padding: 16, background: "var(--paper)", cursor: "pointer", font: "inherit", color: "inherit" }}>
                          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", gap: 10 }}>
                            <div style={{ minWidth: 0 }}>
                              <div style={{ fontFamily: "var(--ff-mono)", fontSize: 12, letterSpacing: "0.1em" }}>{o.id}</div>
                              {o.makerRef && <div style={{ marginTop: 2, fontSize: 9, color: "var(--terracotta)", letterSpacing: "0.22em", fontFamily: "var(--ff-mono)" }}>{o.makerRef}</div>}
                            </div>
                            <Pill st={o.status} lang={lang} />
                          </div>
                          <div style={{ marginTop: 12 }}>
                            {kv(lang === "en" ? "Date" : "التاريخ", window.fmtDate(o.created_at, lang, { day: "numeric", month: "short" }))}
                            {kv(lang === "en" ? "Buyer" : "المشتري", `${o.buyer} · ${o.city}`)}
                            {kv(lang === "en" ? "Piece" : "القطعة", o.piece)}
                            {kv(lang === "en" ? "Qty" : "الكمية", fmtNum(o.qty, lang))}
                            {kv(lang === "en" ? "Gross" : "الإجمالي", `${fmtNum(o.gross, lang)} ${lang === "en" ? "EGP" : "ج.م"}`)}
                            {kv(lang === "en" ? "Your split" : "حصّتك", `${fmtNum(o.split, lang)} ${lang === "en" ? "EGP" : "ج.م"}`)}
                          </div>
                        </button>
                      );
                    })}
                  </div>
                ) : (
                  <div style={{ border: "1px solid var(--line-2)", borderRadius: 14, overflow: "hidden" }}>
                    <div className="mk-tbl" style={{ display: "grid", gridTemplateColumns: "1.2fr 0.8fr 1.4fr 1.2fr 0.6fr 0.8fr 0.9fr 0.9fr", padding: "14px 20px", 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" ? "Date" : "التاريخ"}</div><div>{lang === "en" ? "Buyer" : "المشتري"}</div><div>{lang === "en" ? "Piece" : "القطعة"}</div><div>{lang === "en" ? "Qty" : "الكمية"}</div><div>{lang === "en" ? "Gross" : "الإجمالي"}</div><div>{lang === "en" ? "Your split" : "حصّتك"}</div><div>{lang === "en" ? "Status" : "الحالة"}</div>
                    </div>
                    {orders.map((o, i) => (
                      <div key={i} className="mk-tbl" onClick={() => setOrderDetail(o)} style={{ display: "grid", gridTemplateColumns: "1.2fr 0.8fr 1.4fr 1.2fr 0.6fr 0.8fr 0.9fr 0.9fr", padding: "14px 20px", borderTop: "1px solid var(--line-2)", alignItems: "center", fontSize: 14, cursor: "pointer" }}
                        onMouseEnter={e => e.currentTarget.style.background = "var(--paper-2)"}
                        onMouseLeave={e => e.currentTarget.style.background = "transparent"}
                      >
                        <div style={{ fontFamily: "var(--ff-mono)", fontSize: 11, letterSpacing: "0.1em" }}>
                          {o.id}
                          {o.makerRef && (
                            <div style={{ marginTop: 2, fontSize: 9, color: "var(--terracotta)", letterSpacing: "0.22em" }}>
                              {o.makerRef}
                            </div>
                          )}
                        </div>
                        <div style={{ fontFamily: "var(--ff-mono)", fontSize: 11, color: "var(--muted)" }}>{window.fmtDate(o.created_at, lang, { day: "numeric", month: "short" })}</div>
                        <div>{o.buyer}<div style={{ fontFamily: "var(--ff-mono)", fontSize: 9, color: "var(--muted)", letterSpacing: "0.2em" }}>{o.city}</div></div>
                        <div style={{ fontSize: 13, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{o.piece}</div>
                        <div>{fmtNum(o.qty, lang)}</div>
                        <div style={{ fontFamily: "var(--ff-display)" }}>{fmtNum(o.gross, lang)}</div>
                        <div style={{ fontFamily: "var(--ff-display)", color: "var(--olive)" }}>{fmtNum(o.split, lang)}</div>
                        <Pill st={o.status} lang={lang} />
                      </div>
                    ))}
                  </div>
                )}
              </div>
            )}

            {/* ——— PAYOUTS ——— */}
            {tab === "payouts" && (
              <div>
                <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 20, gap: 10, flexWrap: "wrap" }}>
                  <h2 style={{ fontFamily: "var(--ff-display)", fontSize: 40 }}>{lang === "en" ? "Earnings & payouts" : "الأرباح"}</h2>
                  <button
                    onClick={() => downloadCsv(`sanaa-earnings-${me.slug}-${new Date().toISOString().slice(0,10)}.csv`,
                      ["Order", "Date", "Buyer", "City", "Piece(s)", "Qty", "Gross EGP", "Your Split EGP", "Status"],
                      orders.map(o => [o.id, window.fmtDate(o.created_at, lang, { day: "numeric", month: "short", year: "numeric" }), o.buyer, o.city, o.piece, o.qty, o.gross, o.split, o.status]))
                    }
                    disabled={orders.length === 0}
                    className="btn ghost"
                    style={{ fontSize: 12, opacity: orders.length === 0 ? 0.5 : 1 }}
                  >↓ {lang === "en" ? "Export CSV" : "تصدير CSV"}</button>
                </div>
                <div className="col-3" style={{ marginBottom: 30 }}>
                  <StatCard label={lang === "en" ? "Lifetime sales (your split)" : "إجمالي حصّتك"} value={fmtNum(stats.lifetimeSplit, lang)} sub="EGP" />
                  <StatCard label={lang === "en" ? "Pending payout" : "قيد الصرف"} value={fmtNum(stats.pendingPayout, lang)} sub={lang === "en" ? "EGP — across cycles" : "ج.م — عبر الدورات"} />
                  <StatCard label={lang === "en" ? "Your split" : "نسبتك"} value={`${fmtNum(me.split, lang)}%`} sub={lang === "en" ? `Platform fee: ${100 - me.split}%` : `رسوم: ${fmtNum(100 - me.split, lang)}٪`} />
                </div>
                {payouts.length === 0 ? (
                  <div style={{ padding: "60px 20px", textAlign: "center", border: "1px dashed var(--line)", borderRadius: 14 }}>
                    <Star8 size={20} color="var(--gold-soft)" />
                    <div style={{ marginTop: 14, fontFamily: "var(--ff-display)", fontSize: 22, color: "var(--ink)" }}>
                      {lang === "en" ? "No payout cycles yet." : "لا توجد دورات صرف بعد."}
                    </div>
                    <div style={{ marginTop: 6, fontSize: 13, color: "var(--muted)" }}>
                      {lang === "en" ? "Payouts are computed on the 5th of each month from delivered orders." : "تُحسب الأرباح في يوم ٥ من كل شهر من الطلبات المُسلَّمة."}
                    </div>
                  </div>
                ) : isMobile ? (
                  /* Stacked card layout — no horizontal scroll on phones */
                  <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
                    {payouts.map((p, i) => {
                      const kv = (label, val) => (
                        <div style={{ display: "flex", justifyContent: "space-between", gap: 10, padding: "6px 0", borderTop: "1px solid var(--line-2)" }}>
                          <span style={{ fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--muted)" }}>{label}</span>
                          <span style={{ fontSize: 14, textAlign: "end" }}>{val}</span>
                        </div>
                      );
                      return (
                        <div key={i} style={{ border: "1px solid var(--line-2)", borderRadius: 14, padding: 16, background: "var(--paper)" }}>
                          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", gap: 10 }}>
                            <div style={{ fontFamily: "var(--ff-display)", fontSize: 20 }}>{window.fmtDate(p.period_start, lang, { month: "short", year: "numeric" })}</div>
                            <Pill st={p.status} lang={lang} />
                          </div>
                          <div style={{ marginTop: 12 }}>
                            {kv(lang === "en" ? "Gross" : "الإجمالي", `${fmtNum(p.gross, lang)} ${lang === "en" ? "EGP" : "ج.م"}`)}
                            {kv(lang === "en" ? "Your split" : "حصّتك", `${fmtNum(p.split, lang)} ${lang === "en" ? "EGP" : "ج.م"}`)}
                            {kv(lang === "en" ? "Paid" : "المدفوع", p.paid_at ? window.fmtDate(p.paid_at, lang, { day: "numeric", month: "short" }) : "—")}
                          </div>
                        </div>
                      );
                    })}
                  </div>
                ) : (
                  <div style={{ border: "1px solid var(--line-2)", borderRadius: 14, overflow: "hidden" }}>
                    <div className="mk-tbl" style={{ display: "grid", gridTemplateColumns: "1.5fr 1fr 1fr 1fr 1fr", padding: "14px 20px", background: "var(--paper-2)", fontFamily: "var(--ff-mono)", fontSize: 9, letterSpacing: "0.22em", textTransform: "uppercase", color: "var(--muted)" }}>
                      <div>{lang === "en" ? "Period" : "الفترة"}</div><div>{lang === "en" ? "Gross" : "الإجمالي"}</div><div>{lang === "en" ? "Your split" : "حصّتك"}</div><div>{lang === "en" ? "Paid" : "المدفوع"}</div><div>{lang === "en" ? "Status" : "الحالة"}</div>
                    </div>
                    {payouts.map((p, i) => (
                      <div key={i} className="mk-tbl" style={{ display: "grid", gridTemplateColumns: "1.5fr 1fr 1fr 1fr 1fr", padding: "16px 20px", borderTop: "1px solid var(--line-2)", alignItems: "center", fontSize: 14 }}>
                        <div style={{ fontFamily: "var(--ff-display)", fontSize: 18 }}>{window.fmtDate(p.period_start, lang, { month: "short", year: "numeric" })}</div>
                        <div>{fmtNum(p.gross, lang)}</div>
                        <div style={{ fontFamily: "var(--ff-display)", fontSize: 18, color: "var(--olive)" }}>{fmtNum(p.split, lang)}</div>
                        <div style={{ fontFamily: "var(--ff-mono)", fontSize: 11, color: "var(--muted)" }}>{p.paid_at ? window.fmtDate(p.paid_at, lang, { day: "numeric", month: "short" }) : "—"}</div>
                        <Pill st={p.status} lang={lang} />
                      </div>
                    ))}
                  </div>
                )}
                <div style={{ marginTop: 24, padding: 20, background: "var(--paper-2)", borderRadius: 12, fontSize: 13, color: "var(--olive)" }}>
                  {lang === "en" ? "Payouts land on the 5th of each month, net of VAT and returns." : "تُحوَّل الأرباح في يوم ٥ من كل شهر، خالصة من الضريبة والإرجاع."}
                </div>
              </div>
            )}

            {/* ——— ANALYTICS ——— */}
            {tab === "analytics" && (
              <AnalyticsPanel lang={lang} makerId={makerProfile?.id} orders={orders} pieces={pieces} />
            )}
            {/* ——— MESSAGES ——— */}
            {tab === "messages" && (
              <MessagesPanel lang={lang} makerId={makerProfile?.id} userId={user?.id} />
            )}

            {/* ——— WORKSHOPS ——— */}
            {tab === "workshops" && (
              <div>
                <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 20, gap: 10, flexWrap: "wrap" }}>
                  <h2 style={{ fontFamily: "var(--ff-display)", fontSize: 40 }}>
                    {lang === "en" ? "Your workshops" : "ورشك"}
                    <span style={{ fontFamily: "var(--ff-mono)", fontSize: 12, color: "var(--muted)", marginInlineStart: 12 }}>({fmtNum(workshops.length, lang)})</span>
                  </h2>
                  <button onClick={() => setNewWorkshopOpen(true)} className="btn">+ {lang === "en" ? "New workshop" : "ورشة جديدة"}</button>
                </div>
                {workshops.length === 0 ? (
                  <div style={{ padding: "60px 20px", textAlign: "center", border: "1px dashed var(--line)", borderRadius: 14 }}>
                    <Star8 size={20} color="var(--gold-soft)" />
                    <div style={{ marginTop: 14, fontFamily: "var(--ff-display)", fontSize: 22, color: "var(--ink)" }}>
                      {lang === "en" ? "No workshops yet." : "لا توجد ورش بعد."}
                    </div>
                    <div style={{ marginTop: 6, fontSize: 13, color: "var(--muted)" }}>
                      {lang === "en" ? "Workshops you host will appear here once approved by the platform." : "ستظهر ورشك هنا بمجرد اعتمادها."}
                    </div>
                  </div>
                ) : (
                  <div style={{ display: "grid", gridTemplateColumns: "repeat(2, 1fr)", gap: 18 }}>
                    {workshops.map((w, i) => (
                      <MakerWorkshopCard key={w.id} w={w} lang={lang} />
                    ))}
                  </div>
                )}
              </div>
            )}

            {/* ——— PUBLIC PROFILE EDITOR ——— */}
            {tab === "profile" && (
              <ProfileEditor lang={lang} maker={makerProfile} userId={user?.id} onSubmitted={() => setReloadKey(k => k + 1)} />
            )}

            {/* ——— SETTINGS ——— */}
            {tab === "settings" && (
              <MakerSettings lang={lang} userId={user?.id} userEmail={user?.email} maker={makerProfile} onChanged={refresh} />
            )}
          </div>
        </div>
      </section>

      {/* Modals */}
      <NewPieceModal
        open={newPieceOpen}
        onClose={() => setNewPieceOpen(false)}
        lang={lang}
        makerId={makerProfile?.id}
        userId={user?.id}
        onSubmitted={refresh}
      />
      <ArchiveConfirmModal
        open={!!archiveTarget}
        onClose={() => setArchiveTarget(null)}
        lang={lang}
        piece={archiveTarget}
        makerId={makerProfile?.id}
        userId={user?.id}
        onSubmitted={refresh}
      />
      <OrderDetailDrawer
        open={!!orderDetail}
        onClose={() => setOrderDetail(null)}
        lang={lang}
        orderRow={orderDetail}
        makerId={makerProfile?.id}
      />
      <EditPieceModal
        open={!!editTarget}
        onClose={() => setEditTarget(null)}
        lang={lang}
        piece={editTarget}
        makerId={makerProfile?.id}
        userId={user?.id}
        onSubmitted={refresh}
      />
      <PiecePhotosModal
        open={!!photosTarget}
        onClose={() => setPhotosTarget(null)}
        lang={lang}
        piece={photosTarget}
        makerId={makerProfile?.id}
        userId={user?.id}
        onSubmitted={refresh}
      />
      <NewWorkshopModal
        open={newWorkshopOpen}
        onClose={() => setNewWorkshopOpen(false)}
        lang={lang}
        makerId={makerProfile?.id}
        makerCity={makerProfile?.city_en}
        makerGovernorate={makerProfile?.governorate}
        onSubmitted={refresh}
      />
    </div>
  );
}

Object.assign(window, { MakerAdminPage });
