/* Sentosa Marketplace - shared demo feedback primitives
   Toast bus, modal shell, document preview and generated-report view.
   Every interactive control in the kits resolves to one of these, so no click is a dead end. */

/* ---- Toast bus (no prop drilling: fire from anywhere with window.toast) ---- */
window.toast = (msg, tone = "success", detail) =>
  window.dispatchEvent(new CustomEvent("sm-toast", { detail: { msg, tone, detail } }));

function ToastHost() {
  const [items, setItems] = React.useState([]);
  React.useEffect(() => {
    let seq = 0;
    const handler = (e) => {
      const id = ++seq + "-" + performance.now();
      setItems(t => [...t, { id, ...e.detail }]);
      setTimeout(() => setItems(t => t.filter(x => x.id !== id)), 4200);
    };
    window.addEventListener("sm-toast", handler);
    return () => window.removeEventListener("sm-toast", handler);
  }, []);

  const tones = {
    success: ["var(--success-bg)", "#0f5e35", "#b7e0c8", "check-circle"],
    info: ["var(--info-bg)", "#1a44a8", "#c4d4f7", "info"],
    warning: ["var(--warning-bg)", "#7a5a00", "#F0DCA0", "alert-triangle"],
  };

  return (
    <div aria-live="polite" style={{ position: "fixed", right: 24, bottom: 24, zIndex: 200,
      display: "flex", flexDirection: "column", gap: 10, maxWidth: 380, pointerEvents: "none" }}>
      {items.map(t => {
        const [bg, fg, br, ic] = tones[t.tone] || tones.success;
        return (
          <div key={t.id} style={{ background: bg, border: `1px solid ${br}`, color: fg,
            borderRadius: "var(--radius-md)", padding: "13px 15px", display: "flex", gap: 11,
            alignItems: "flex-start", boxShadow: "var(--elev-2, 0 8px 24px rgba(0,0,0,.12))",
            fontFamily: "var(--font-sans)", pointerEvents: "auto", animation: "smToastIn .18s ease-out" }}>
            <Icon name={ic} size={18} style={{ marginTop: 1, flex: "none" }} />
            <div style={{ minWidth: 0 }}>
              <div style={{ fontSize: 14, fontWeight: 600, lineHeight: 1.4 }}>{t.msg}</div>
              {t.detail && <div style={{ fontSize: 12.5, marginTop: 2, opacity: .85, lineHeight: 1.45 }}>{t.detail}</div>}
            </div>
          </div>
        );
      })}
      <style>{`@keyframes smToastIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }`}</style>
    </div>
  );
}

/* ---- Modal shell ---- */
function Modal({ open, title, subtitle, onClose, children, footer, width = 620 }) {
  React.useEffect(() => {
    if (!open) return;
    const onKey = (e) => e.key === "Escape" && onClose();
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [open, onClose]);
  if (!open) return null;
  return (
    <div role="dialog" aria-modal="true" aria-label={title}
      onClick={onClose}
      style={{ position: "fixed", inset: 0, zIndex: 150, background: "rgba(20,20,20,.45)",
        display: "flex", alignItems: "flex-start", justifyContent: "center", padding: "6vh 24px", overflowY: "auto" }}>
      <div onClick={e => e.stopPropagation()}
        style={{ background: "var(--surface)", borderRadius: "var(--radius-lg)", width: "100%", maxWidth: width,
          boxShadow: "0 24px 64px rgba(0,0,0,.3)", overflow: "hidden", fontFamily: "var(--font-sans)" }}>
        <div style={{ padding: "18px 22px", borderBottom: "1px solid var(--border)", display: "flex", alignItems: "flex-start", gap: 16 }}>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 17, fontWeight: 700 }}>{title}</div>
            {subtitle && <div style={{ fontSize: 13, color: "var(--fg2)", marginTop: 3, lineHeight: 1.45 }}>{subtitle}</div>}
          </div>
          <button onClick={onClose} aria-label="Close"
            style={{ background: "none", border: 0, cursor: "pointer", display: "flex", color: "var(--fg2)", padding: 4 }}>
            <Icon name="x" size={20} />
          </button>
        </div>
        <div style={{ padding: 22, maxHeight: "62vh", overflowY: "auto" }}>{children}</div>
        {footer && <div style={{ padding: "15px 22px", borderTop: "1px solid var(--border)",
          display: "flex", gap: 10, justifyContent: "flex-end", background: "var(--neutral-50)" }}>{footer}</div>}
      </div>
    </div>
  );
}

/* ---- Export menu: turns a bare "Export" button into a real choice ---- */
function ExportButtons({ label = "Export", rows, name, size = "sm", variant = "secondary" }) {
  const fire = (fmt) => window.toast(`${name} exported to ${fmt}`,
    "success", rows ? `${rows} rows · download started` : "Download started");
  return (
    <div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
      <Btn size={size} variant={variant} icon="file-spreadsheet" onClick={() => fire("Excel")}>Excel</Btn>
      <Btn size={size} variant={variant} icon="file-text" onClick={() => fire("PDF")}>PDF</Btn>
      <Btn size={size} variant={variant} icon="download" onClick={() => fire("CSV")}>CSV</Btn>
    </div>
  );
}

/* ---- Document preview (KYC docs, invoices, tickets) ---- */
function DocPreview({ open, onClose, title, kind = "document", meta = [], body }) {
  return (
    <Modal open={open} onClose={onClose} title={title} subtitle={`Preview · ${kind}`} width={640}
      footer={<>
        <Btn variant="ghost" onClick={onClose}>Close</Btn>
        <Btn variant="primary" icon="download" onClick={() => { window.toast(`${title} downloaded`); onClose(); }}>Download</Btn>
      </>}>
      <div style={{ border: "1px solid var(--border)", borderRadius: "var(--radius-md)", overflow: "hidden" }}>
        <div style={{ background: "var(--neutral-50)", padding: "14px 18px", borderBottom: "1px solid var(--border)",
          display: "flex", alignItems: "center", gap: 10 }}>
          <Icon name="file-text" size={18} color="var(--fg2)" />
          <span style={{ fontWeight: 600, fontSize: 14 }}>{title}</span>
          <span style={{ marginLeft: "auto" }}><Badge tone="success">Verified</Badge></span>
        </div>
        {meta.length > 0 && (
          <div style={{ padding: "4px 0" }}>
            {meta.map(([k, v]) => (
              <div key={k} style={{ display: "flex", justifyContent: "space-between", gap: 20,
                padding: "10px 18px", fontSize: 13.5, borderBottom: "1px solid var(--border)" }}>
                <span style={{ color: "var(--fg2)" }}>{k}</span>
                <span style={{ fontWeight: 600, textAlign: "right" }}>{v}</span>
              </div>
            ))}
          </div>
        )}
        <div style={{ padding: 18, background: "#fff" }}>
          {body || (
            <div style={{ display: "flex", flexDirection: "column", gap: 9 }}>
              {[100, 92, 96, 74, 88, 60].map((w, i) => (
                <span key={i} style={{ height: 9, width: `${w}%`, background: "var(--neutral-100)", borderRadius: 3 }}></span>
              ))}
              <div style={{ marginTop: 10, fontSize: 12.5, color: "var(--fg2)", display: "flex", alignItems: "center", gap: 7 }}>
                <Icon name="lock" size={13} />Stored in Singapore · access logged to the audit trail
              </div>
            </div>
          )}
        </div>
      </div>
    </Modal>
  );
}

/* ---- Generated report view ---- */
function ReportPreview({ open, onClose, report, columns, rows, summary }) {
  if (!open || !report) return null;
  return (
    <Modal open={open} onClose={onClose} title={report.name}
      subtitle={report.sno && report.sno !== "-" ? `S/No. ${report.sno} · generated just now` : "Generated just now"}
      width={860}
      footer={<>
        <Btn variant="ghost" onClick={onClose}>Close</Btn>
        <Btn variant="secondary" icon="calendar" onClick={() => window.toast("Report scheduled", "info", "Weekly, Mondays 08:00 · sent to configured mailboxes")}>Schedule</Btn>
        <Btn variant="secondary" icon="file-spreadsheet" onClick={() => window.toast(`${report.name} exported to Excel`, "success", `${rows.length} rows · download started`)}>Excel</Btn>
        <Btn variant="primary" icon="download" onClick={() => window.toast(`${report.name} exported to CSV`, "success", `${rows.length} rows · download started`)}>CSV</Btn>
      </>}>
      {summary && (
        <div style={{ display: "grid", gridTemplateColumns: `repeat(${summary.length},1fr)`, gap: 12, marginBottom: 18 }}>
          {summary.map(([label, value]) => (
            <div key={label} style={{ padding: 13, border: "1px solid var(--border)", borderRadius: "var(--radius-md)" }}>
              <div style={{ fontSize: 12.5, color: "var(--fg2)" }}>{label}</div>
              <div style={{ fontSize: 19, fontWeight: 700, marginTop: 3 }}>{value}</div>
            </div>
          ))}
        </div>
      )}
      <div style={{ border: "1px solid var(--border)", borderRadius: "var(--radius-md)", overflow: "hidden" }}>
        <div style={{ overflowX: "auto" }}>
          <table style={{ width: "100%", borderCollapse: "collapse", minWidth: 620 }}>
            <thead>
              <tr>{columns.map((c, i) => (
                <th key={c} style={{ textAlign: i === 0 ? "left" : "right", padding: "10px 14px", fontSize: 11.5,
                  fontWeight: 600, letterSpacing: ".04em", textTransform: "uppercase", color: "var(--fg2)",
                  borderBottom: "1px solid var(--border)", background: "var(--neutral-50)", whiteSpace: "nowrap" }}>{c}</th>
              ))}</tr>
            </thead>
            <tbody>
              {rows.map((r, ri) => (
                <tr key={ri}>
                  {r.map((cell, ci) => (
                    <td key={ci} style={{ textAlign: ci === 0 ? "left" : "right", padding: "11px 14px", fontSize: 13.5,
                      borderBottom: ri < rows.length - 1 ? "1px solid var(--border)" : 0,
                      fontWeight: ci === 0 ? 600 : 400,
                      fontFamily: ci === 0 ? "var(--font-sans)" : "var(--font-mono)" }}>{cell}</td>
                  ))}
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>
      <div style={{ fontSize: 12.5, color: "var(--fg2)", marginTop: 12, display: "flex", alignItems: "center", gap: 7 }}>
        <Icon name="info" size={14} />Sample extract. Full report supports custom date ranges and role-configurable views.
      </div>
    </Modal>
  );
}

/* ---- Notifications panel ---- */
function NotificationsButton({ items }) {
  const [open, setOpen] = React.useState(false);
  return (
    <React.Fragment>
      <button aria-label="Notifications" onClick={() => setOpen(true)}
        style={{ width: 42, height: 42, borderRadius: "var(--radius-md)", border: "1px solid var(--border)",
          background: "#fff", cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center", position: "relative" }}>
        <Icon name="bell" size={19} color="var(--fg2)" />
        {items.length > 0 && <span style={{ position: "absolute", top: 9, right: 10, width: 8, height: 8,
          borderRadius: 999, background: "var(--action)", border: "2px solid #fff" }}></span>}
      </button>
      <Modal open={open} onClose={() => setOpen(false)} title="Notifications"
        subtitle="Workflow updates and system alerts" width={520}
        footer={<Btn variant="ghost" onClick={() => { window.toast("All notifications marked as read", "info"); setOpen(false); }}>Mark all as read</Btn>}>
        <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
          {items.map((n, i) => (
            <div key={i} style={{ display: "flex", gap: 12, padding: 14, border: "1px solid var(--border)", borderRadius: "var(--radius-md)" }}>
              <Icon name={n.icon} size={18} color="var(--orange-900)" style={{ marginTop: 1, flex: "none" }} />
              <div style={{ minWidth: 0 }}>
                <div style={{ fontSize: 14, fontWeight: 600, lineHeight: 1.4 }}>{n.title}</div>
                <div style={{ fontSize: 13, color: "var(--fg2)", marginTop: 2, lineHeight: 1.5 }}>{n.body}</div>
                <div style={{ fontSize: 12, color: "var(--fg3)", marginTop: 5 }}>{n.when}</div>
              </div>
            </div>
          ))}
        </div>
      </Modal>
    </React.Fragment>
  );
}

/* ---- Photo: real image with the brand tint as the loading/fallback state ---- */
function Photo({ src, tint, alt = "", style, radius, zoom, children }) {
  const [failed, setFailed] = React.useState(false);
  const [hover, setHover] = React.useState(false);
  return (
    <div
      onMouseEnter={zoom ? () => setHover(true) : undefined}
      onMouseLeave={zoom ? () => setHover(false) : undefined}
      style={{ position: "relative", overflow: "hidden", background: tint || "var(--neutral-100)",
        borderRadius: radius, ...style }}>
      {src && !failed && (
        <img src={src} alt={alt} loading="lazy" onError={() => setFailed(true)}
          style={{ position: "absolute", inset: 0, width: "100%", height: "100%",
            objectFit: "cover", display: "block",
            transform: hover ? "scale(1.06)" : "scale(1)",
            transition: "transform .45s cubic-bezier(.2,.6,.2,1)" }} />
      )}
      {/* keeps white text and badges legible over any photograph */}
      <div aria-hidden="true" style={{ position: "absolute", inset: 0,
        background: "linear-gradient(180deg, rgba(0,0,0,.34) 0%, rgba(0,0,0,0) 40%, rgba(0,0,0,0) 60%, rgba(0,0,0,.38) 100%)" }}></div>
      {children}
    </div>
  );
}

Object.assign(window, { Photo, ToastHost, Modal, ExportButtons, DocPreview, ReportPreview, NotificationsButton });
