/* Designs — back-office list of every customer gang-sheet design (draft / in cart /
   ordered), built in the headless storefront builder. Mirrors the reference tool:
   tabs + columns (Name, Order, Customer, Product, Size, Status, Type, Date) + per-row
   actions, and a "Design Assets" modal showing each uploaded image's Raw art vs Current
   design file with edit-provenance badges.
   Data: GET /api/admin/designs (list) + /api/admin/designs/:id/assets (modal). Both are
   staff-session gated (requireAuth). Customer names resolve client-side via DTF.getCustomer. */
const { useState: useStateD, useEffect: useEffectD, useRef: useRefD } = React;

const DZ_TABS = [
  { key: "", label: "All" },
  { key: "draft", label: "Draft" },
  { key: "cart", label: "In Cart" },
  { key: "ordered", label: "Ordered" },
];
const DZ_STATUS = {
  draft:   { label: "Draft",   cls: "badge--grey" },
  cart:    { label: "In Cart", cls: "badge--blue" },
  ordered: { label: "Ordered", cls: "badge--mint" },
};
// Edit-op → provenance badge (label + colour) for the assets modal.
const DZ_EDIT_BADGE = {
  "remove-bg":    { label: "BACKGROUND REMOVED", cls: "badge--mint" },
  "remove-white": { label: "WHITE REMOVED",      cls: "badge--mint" },
  upscale:        { label: "UPSCALED",           cls: "badge--blue" },
  trim:           { label: "TRIMMED",            cls: "badge--amber" },
  harden:         { label: "HARDENED",           cls: "badge--violet" },
  convert:        { label: "CONVERTED",          cls: "badge--grey" },
};
const dzBadge = (op, label) => DZ_EDIT_BADGE[op] || { label: (label || op || "EDITED").toUpperCase(), cls: "badge--grey" };
// PDP base for the builder edit/share link (?gs=<id> restores the exact sheet).
const DZ_BUILDER_BASE = "https://dtf.uk/products/";

function dzFmtDate(s) {
  if (!s) return "—";
  try {
    const d = new Date(s);
    return d.toLocaleDateString(undefined, { day: "2-digit", month: "short", year: "numeric" }) +
      " " + d.toLocaleTimeString(undefined, { hour: "2-digit", minute: "2-digit" });
  } catch { return String(s).slice(0, 16); }
}
function dzCustomerLabel(d) {
  if (!d.customerId) return { name: "Guest", sub: null, id: null };
  let c = null;
  try { c = DTF.getCustomer && DTF.getCustomer(d.customerId); } catch {}
  if (c) return { name: c.name || c.displayName || c.email || "Customer", sub: c.email || null, id: d.customerId };
  // Unresolved GID → show the numeric tail so it's still identifiable.
  const tail = String(d.customerId).split("/").pop();
  return { name: "Customer " + tail, sub: null, id: d.customerId };
}
function dzEditUrl(d) {
  const handle = d.productHandle || "build-a-dtf-gang-sheet-online";
  return DZ_BUILDER_BASE + encodeURIComponent(handle) + "?gs=" + encodeURIComponent(d.id);
}
function dzDownload(url, name) {
  if (!url) return;
  const a = document.createElement("a");
  a.href = url; a.download = name || ""; a.target = "_blank"; a.rel = "noopener";
  document.body.appendChild(a); a.click(); a.remove();
}

function DesignsView({ go }) {
  const [tab, setTab] = useStateD("");
  const [q, setQ] = useStateD("");
  const [qInput, setQInput] = useStateD("");
  const [page, setPage] = useStateD(1);
  const [data, setData] = useStateD(null);   // { designs, total, page, per, pages }
  const [loading, setLoading] = useStateD(true);
  const [err, setErr] = useStateD("");
  const [assetsFor, setAssetsFor] = useStateD(null); // design row whose assets modal is open
  const [copiedId, setCopiedId] = useStateD(null);
  const per = 20;

  useEffectD(() => { setPage(1); }, [tab, q]);
  useEffectD(() => {
    let alive = true;
    setLoading(true); setErr("");
    const params = new URLSearchParams({ per: String(per), page: String(page) });
    if (tab) params.set("status", tab);
    if (q) params.set("q", q);
    fetch("/api/admin/designs?" + params.toString())
      .then((r) => r.ok ? r.json() : r.json().then((j) => Promise.reject(new Error(j.error || ("HTTP " + r.status)))))
      .then((j) => { if (alive) { setData(j); setLoading(false); } })
      .catch((e) => { if (alive) { setErr(e.message || String(e)); setLoading(false); } });
    return () => { alive = false; };
  }, [tab, q, page]);

  function copyShare(d) {
    const url = dzEditUrl(d);
    const done = () => { setCopiedId(d.id); setTimeout(() => setCopiedId((x) => (x === d.id ? null : x)), 1400); };
    try { navigator.clipboard.writeText(url).then(done, () => { window.prompt("Checkout / edit URL:", url); }); }
    catch { window.prompt("Checkout / edit URL:", url); }
  }

  const rows = (data && data.designs) || [];
  const total = (data && data.total) || 0;
  const pages = (data && data.pages) || 1;

  return (
    <div className="board">
      <div className="toolbar">
        <div className="seg">
          {DZ_TABS.map((t) => (
            <button key={t.key || "all"} className={tab === t.key ? "is-active" : ""} onClick={() => setTab(t.key)}>{t.label}</button>
          ))}
        </div>
        <form style={{ marginLeft: "auto", display: "flex", gap: 6 }} onSubmit={(e) => { e.preventDefault(); setQ(qInput.trim()); }}>
          <input className="rm-in" placeholder="Search name, order, customer…" value={qInput}
                 onChange={(e) => setQInput(e.target.value)} style={{ width: 240 }} />
          <button className="btn btn--sm btn--primary" type="submit"><Icon name="search" /> Search</button>
          {(q || qInput) && <button className="btn btn--sm btn--ghost" type="button" onClick={() => { setQInput(""); setQ(""); }}>Clear</button>}
        </form>
      </div>

      {err && <div className="warn-banner" style={{ marginBottom: 12 }}><Icon name="spark" /> Couldn’t load designs — {err}</div>}

      <div className="tbl-wrap">
        <table className="tbl">
          <thead>
            <tr>
              <th>Name</th><th>Order</th><th>Customer</th><th>Product</th>
              <th>Size</th><th>Status</th><th>Type</th><th>Date</th><th style={{ width: 196 }}></th>
            </tr>
          </thead>
          <tbody>
            {loading
              ? Array.from({ length: 8 }).map((_, i) => (
                  <tr key={"sk" + i}><td colSpan={9} style={{ padding: "10px 12px" }}><div className="skel skel-bar" style={{ height: 18, opacity: Math.max(0.35, 1 - i * 0.08) }} /></td></tr>))
              : rows.length === 0
                ? <tr><td colSpan={9}><div className="empty" style={{ padding: "28px 12px" }}><Icon name="image" /><div className="t">No designs</div><div className="m">{q ? "Try another search or tab." : "Customer gang sheets will appear here as they’re built."}</div></div></td></tr>
                : rows.map((d) => {
                    const cust = dzCustomerLabel(d);
                    const st = DZ_STATUS[d.status] || { label: d.status || "—", cls: "badge--grey" };
                    return (
                      <tr key={d.id}>
                        <td>
                          <div style={{ fontWeight: 600 }}>{d.name || "New Gang Sheet"}</div>
                          {d.assetCount > 0 && <div className="dim" style={{ fontSize: 11 }}>{d.assetCount} artwork{d.assetCount === 1 ? "" : "s"}</div>}
                        </td>
                        <td>{d.orderId ? <a className="linklike" href={"#/orders/" + encodeURIComponent(String(d.orderId).replace(/^#/, ""))} onClick={(e) => { if (!(e.metaKey || e.ctrlKey || e.shiftKey)) { e.preventDefault(); go && go({ view: "order", id: "#" + String(d.orderId).replace(/^#/, "") }); } }}>#{String(d.orderId).replace(/^#/, "")}</a> : <span className="dim">—</span>}</td>
                        <td>
                          {cust.id
                            ? <a className="linklike" href="#" onClick={(e) => { e.preventDefault(); go && go({ view: "customer", id: cust.id }); }}>{cust.name}</a>
                            : <span>{cust.name}</span>}
                          {cust.sub && <div className="dim" style={{ fontSize: 11 }}>{cust.sub}</div>}
                        </td>
                        <td>{d.productTitle ? <span title={d.productHandle || ""}>{d.productTitle}</span> : <span className="dim">—</span>}</td>
                        <td>{d.sizeLabel || (d.meters != null ? d.meters + "M" : "—")}</td>
                        <td><span className={"badge " + st.cls}>{st.label}</span></td>
                        <td>{d.type ? <span className="badge badge--violet">{d.type}</span> : <span className="dim">—</span>}</td>
                        <td className="dim" style={{ whiteSpace: "nowrap" }}>{dzFmtDate(d.updatedAt)}</td>
                        <td>
                          <div className="dz-actions" style={{ display: "flex", gap: 4, justifyContent: "flex-end", flexWrap: "nowrap" }}>
                            {d.previewUrl && <button className="icon-btn" title="Preview" onClick={() => window.open(d.previewUrl, "_blank", "noopener")}><Icon name="image" /></button>}
                            <button className="icon-btn" title="Design assets (raw + edited artwork)" onClick={() => setAssetsFor(d)}><Icon name="doc" /></button>
                            <a className="icon-btn" title="Edit in the builder" href={dzEditUrl(d)} target="_blank" rel="noopener"><Icon name="external" /></a>
                            <button className="icon-btn" title={copiedId === d.id ? "Copied!" : "Copy checkout / edit URL"} style={copiedId === d.id ? { borderColor: "var(--mint)", color: "var(--mint-ink)" } : undefined} onClick={() => copyShare(d)}><Icon name={copiedId === d.id ? "check" : "link"} /></button>
                            <button className="icon-btn" disabled title={d.renderUrl ? "Download print file" : "Not generated yet"} onClick={() => d.renderUrl && dzDownload(d.renderUrl, (d.name || "gang-sheet") + ".png")}><Icon name="download" /></button>
                          </div>
                        </td>
                      </tr>
                    );
                  })}
          </tbody>
        </table>
      </div>

      <div className="tbl-foot" style={{ display: "flex", alignItems: "center", gap: 12, marginTop: 12 }}>
        <span className="dim" style={{ fontSize: 12 }}>{total} design{total === 1 ? "" : "s"}{pages > 1 ? ` · page ${page} of ${pages}` : ""}</span>
        <div style={{ marginLeft: "auto", display: "flex", gap: 6 }}>
          <button className="btn btn--sm btn--ghost" disabled={page <= 1 || loading} onClick={() => setPage((p) => Math.max(1, p - 1))}>Prev</button>
          <button className="btn btn--sm btn--ghost" disabled={page >= pages || loading} onClick={() => setPage((p) => Math.min(pages, p + 1))}>Next</button>
        </div>
      </div>

      {assetsFor && <DesignAssetsModal design={assetsFor} onClose={() => setAssetsFor(null)} />}
    </div>
  );
}

// "Design Assets" modal — one card per uploaded image, showing provenance badges from the
// edit log + downloads for the Raw art (original upload) and Current design file (latest).
function DesignAssetsModal({ design, onClose }) {
  const [imgs, setImgs] = useStateD(null);
  const [err, setErr] = useStateD("");
  useEffectD(() => {
    let alive = true;
    fetch("/api/admin/designs/" + encodeURIComponent(design.id) + "/assets")
      .then((r) => r.ok ? r.json() : r.json().then((j) => Promise.reject(new Error(j.error || ("HTTP " + r.status)))))
      .then((j) => { if (alive) setImgs(j.images || []); })
      .catch((e) => { if (alive) setErr(e.message || String(e)); });
    return () => { alive = false; };
  }, [design.id]);

  const rows = imgs || [];
  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal modal--wide" onClick={(e) => e.stopPropagation()} style={{ maxWidth: 1040 }}>
        <div className="modal__head" style={{ alignItems: "flex-start" }}>
          <span style={{ display: "inline-grid", placeItems: "center", width: 42, height: 42, borderRadius: 10, background: "var(--paper-2,#f4f4f6)", border: "1px solid var(--rule)", flex: "0 0 auto" }}><Icon name="image" /></span>
          <div style={{ lineHeight: 1.25 }}>
            <div className="kick">Design assets</div>
            <h3 style={{ margin: 0 }}>Images</h3>
            <div className="dim" style={{ fontSize: 11.5, marginTop: 4 }}>Design <span className="mono" style={{ fontSize: 11 }}>{design.id}</span></div>
          </div>
          <button className="icon-btn" style={{ marginLeft: "auto" }} onClick={onClose} title="Close"><Icon name="x" /></button>
        </div>
        <div className="modal__body">
          {err && <div className="warn-banner"><Icon name="spark" /> {err}</div>}
          {!imgs && !err && <div className="dim" style={{ padding: 20 }}>Loading artwork…</div>}
          {imgs && imgs.length === 0 && <div className="empty" style={{ padding: 28 }}><Icon name="image" /><div className="t">No artwork</div><div className="m">This design has no placed images.</div></div>}
          {rows.length > 0 && (
            <div className="dz-assets-grid" style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(300px, 1fr))", gap: 16 }}>
              {rows.map((im, i) => {
                const seen = new Set();
                const badges = (im.edits || []).map((e) => dzBadge(e.op, e.label)).filter((b) => (seen.has(b.label) ? false : (seen.add(b.label), true)));
                return (
                  <div key={i} className="card" style={{ overflow: "hidden" }}>
                    <div style={{ position: "relative", background: "var(--paper-2,#f4f4f6)", minHeight: 150, display: "flex", alignItems: "center", justifyContent: "center", padding: 10 }}>
                      {badges.length > 0 && (
                        <div style={{ position: "absolute", top: 8, left: 8, display: "flex", gap: 4, flexWrap: "wrap", maxWidth: "78%" }}>
                          {badges.map((b, bi) => <span key={bi} className={"badge " + b.cls} style={{ fontSize: 10 }}>{b.label}</span>)}
                        </div>
                      )}
                      <span className="badge badge--grey" style={{ position: "absolute", bottom: 8, right: 8, fontSize: 10 }}>{im.format || "PNG"}</span>
                      {im.url
                        ? <img src={im.url} alt={im.name || ""} loading="lazy" referrerPolicy="no-referrer" style={{ maxWidth: "100%", maxHeight: 220, objectFit: "contain" }} />
                        : <Icon name="image" />}
                    </div>
                    <div className="card__body" style={{ padding: 14 }}>
                      <div style={{ fontWeight: 700, fontSize: 14, textAlign: "center", wordBreak: "break-word" }}>{im.name || "artwork"}</div>
                      <div className="dim" style={{ fontSize: 10.5, textAlign: "center", letterSpacing: ".06em", textTransform: "uppercase", margin: "3px 0 12px" }}>{im.sourceType || "Upload image"}</div>
                      <div style={{ display: "grid", gap: 8 }}>
                        <DzFileRow dot="#9aa3ad" label="Raw art" name={im.name} url={im.rawUrl} />
                        {im.beforeUrl && <DzFileRow dot="#eab308" label="Before edits" name={im.name} url={im.beforeUrl} />}
                        <DzFileRow dot="#10b981" label="Current design file" name={im.name} url={im.url} />
                      </div>
                    </div>
                  </div>
                );
              })}
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

// One downloadable file tier (raw art / before edits / current design file) in an assets card.
function DzFileRow({ dot, label, name, url }) {
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 10, border: "1px solid var(--rule)", borderRadius: 8, padding: "8px 10px" }}>
      <span style={{ width: 9, height: 9, borderRadius: "50%", background: dot, flex: "0 0 auto" }} />
      <div style={{ minWidth: 0, flex: 1 }}>
        <div style={{ fontWeight: 600, fontSize: 12.5 }}>{label}</div>
        <div className="dim" style={{ fontSize: 11, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{name || "—"}</div>
      </div>
      <button className="btn btn--sm btn--ghost" disabled={!url} onClick={() => url && dzDownload(url, name || "artwork")} style={{ flex: "0 0 auto" }}><Icon name="download" /> Download</button>
    </div>
  );
}

window.DesignsView = DesignsView;
