/* eslint-disable no-undef */
// Shared interactive UI: global toast + modal/form bus, dropdown menu, downloads.
// Any component can call AGB_UI.toast(...) / AGB_UI.form(...) / AGB_UI.modal(...).
// A single <UIHost/> (mounted in App) renders the portals.

const { useState: uiUseState, useEffect: uiUseEffect, useRef: uiUseRef } = React;

const UI_EVT = "agb-ui";
const AGB_UI = {
  toast(message, opts = {}) { window.dispatchEvent(new CustomEvent(UI_EVT, { detail: { kind: "toast", message, type: opts.type || "info", duration: opts.duration } })); },
  modal(config) { window.dispatchEvent(new CustomEvent(UI_EVT, { detail: { kind: "modal", config } })); },
  form(config) { window.dispatchEvent(new CustomEvent(UI_EVT, { detail: { kind: "modal", config: { ...config, isForm: true } } })); },
  close() { window.dispatchEvent(new CustomEvent(UI_EVT, { detail: { kind: "close" } })); },
};

// ---------- downloads ----------
function downloadBlob(filename, blob) {
  const a = document.createElement("a");
  a.href = URL.createObjectURL(blob);
  a.download = filename;
  document.body.appendChild(a); a.click();
  setTimeout(() => { URL.revokeObjectURL(a.href); a.remove(); }, 1000);
}
function downloadCSV(filename, headers, rows) {
  const esc = (v) => `"${String(v ?? "").replace(/"/g, '""')}"`;
  const csv = [headers.map(esc).join(","), ...rows.map((r) => r.map(esc).join(","))].join("\n");
  downloadBlob(filename, new Blob([csv], { type: "text/csv;charset=utf-8" }));
  AGB_UI.toast(`Exported ${rows.length} rows → ${filename}`, { type: "ok" });
}
function downloadText(filename, text, mime = "text/plain") {
  downloadBlob(filename, new Blob([text], { type: mime }));
  AGB_UI.toast(`Downloaded ${filename}`, { type: "ok" });
}

// ---------- Toast stack ----------
function ToastStack({ toasts }) {
  return (
    <div style={{ position: "fixed", bottom: 20, left: "50%", transform: "translateX(-50%)", zIndex: 4000, display: "flex", flexDirection: "column", gap: 8, alignItems: "center", pointerEvents: "none" }}>
      {toasts.map((t) => {
        const color = t.type === "ok" ? "var(--green)" : t.type === "warn" ? "var(--amber)" : t.type === "bad" ? "var(--rose)" : "var(--cyan)";
        return (
          <div key={t.id} style={{
            display: "flex", alignItems: "center", gap: 10, padding: "10px 16px",
            background: "var(--bg-elev)", border: "1px solid var(--border-strong)",
            borderLeft: `3px solid ${color}`, borderRadius: 10, boxShadow: "0 8px 30px -8px rgba(0,0,0,0.6)",
            fontSize: 13, color: "var(--text)", minWidth: 220, maxWidth: 440,
            animation: "toast-in .25s ease", pointerEvents: "auto",
          }}>
            <span style={{ width: 7, height: 7, borderRadius: 999, background: color, flexShrink: 0 }} />
            <span style={{ flex: 1 }}>{t.message}</span>
          </div>
        );
      })}
    </div>
  );
}

// ---------- Modal ----------
function Modal({ config, onClose }) {
  const [values, setValues] = uiUseState(() => {
    const v = {};
    (config.fields || []).forEach((f) => { v[f.key] = f.value != null ? f.value : (f.type === "number" || f.type === "range") ? (f.min ?? 0) : (f.options ? f.options[0]?.value ?? f.options[0] : ""); });
    return v;
  });
  uiUseEffect(() => {
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, []);

  const set = (k, v) => setValues((prev) => ({ ...prev, [k]: v }));
  const submit = () => {
    if (config.onSubmit) config.onSubmit(values);
    onClose();
    if (config.successToast !== false) AGB_UI.toast(config.successMessage || `${config.submitLabel || "Saved"} ✓`, { type: "ok" });
  };

  return (
    <div onMouseDown={(e) => { if (e.target === e.currentTarget) onClose(); }}
      style={{ position: "fixed", inset: 0, zIndex: 3500, background: "rgba(6,9,12,0.6)", backdropFilter: "blur(3px)", display: "grid", placeItems: "center", padding: 20, animation: "fade-in .15s ease" }}>
      <div style={{ width: config.wide ? 720 : 480, maxWidth: "100%", maxHeight: "88vh", overflowY: "auto", background: "var(--surface)", border: "1px solid var(--border-strong)", borderRadius: 14, boxShadow: "0 24px 80px -16px rgba(0,0,0,0.7)", animation: "modal-in .2s ease" }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", padding: "18px 20px", borderBottom: "1px solid var(--border)" }}>
          <div>
            {config.eyebrow && <div className="section-title" style={{ margin: "0 0 6px" }}><span style={{ color: "var(--primary)" }}>{config.eyebrow}</span></div>}
            <div style={{ fontSize: 17, fontWeight: 600 }}>{config.title}</div>
            {config.subtitle && <div className="dim" style={{ fontSize: 12, marginTop: 3 }}>{config.subtitle}</div>}
          </div>
          <button className="btn ghost" onClick={onClose} style={{ padding: 6 }}><Icon name="close" size={16} /></button>
        </div>

        <div style={{ padding: 20 }}>
          {config.isForm ? (
            <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
              {(config.fields || []).map((f) => <Field key={f.key} f={f} value={values[f.key]} onChange={(v) => set(f.key, v)} />)}
            </div>
          ) : (typeof config.body === "function" ? config.body(values, set) : config.body)}
        </div>

        <div style={{ display: "flex", justifyContent: "flex-end", gap: 8, padding: "14px 20px", borderTop: "1px solid var(--border)" }}>
          {config.extraActions}
          <button className="btn" onClick={onClose}>{config.cancelLabel || "Cancel"}</button>
          {(config.isForm || config.onSubmit) && (
            <button className="btn solid" onClick={submit}>{config.submitLabel || "Confirm"}</button>
          )}
        </div>
      </div>
    </div>
  );
}

function Field({ f, value, onChange }) {
  const label = (
    <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 6 }}>
      <span className="dim" style={{ fontSize: 11, textTransform: "uppercase", letterSpacing: "0.05em", fontWeight: 500 }}>{f.label}</span>
      {f.type === "range" && <span className="mono" style={{ fontSize: 12, color: "var(--primary)" }}>{value}{f.suffix || ""}</span>}
    </div>
  );
  if (f.type === "select") {
    return <div>{label}<select className="input" value={value} onChange={(e) => onChange(e.target.value)}>
      {f.options.map((o) => { const val = o.value ?? o; const lab = o.label ?? o; return <option key={val} value={val}>{lab}</option>; })}
    </select></div>;
  }
  if (f.type === "textarea") {
    return <div>{label}<textarea className="input" rows={f.rows || 3} value={value} placeholder={f.placeholder} onChange={(e) => onChange(e.target.value)} style={{ resize: "vertical", fontFamily: "inherit" }} /></div>;
  }
  if (f.type === "range") {
    return <div>{label}<input type="range" min={f.min} max={f.max} step={f.step || 1} value={value} onChange={(e) => onChange(+e.target.value)} style={{ width: "100%" }} /></div>;
  }
  if (f.type === "checkbox") {
    return <label style={{ display: "flex", alignItems: "center", gap: 10, cursor: "pointer", fontSize: 13 }}>
      <input type="checkbox" checked={!!value} onChange={(e) => onChange(e.target.checked)} style={{ width: 16, height: 16 }} /> {f.label}
    </label>;
  }
  return <div>{label}<div style={{ display: "flex", alignItems: "center", gap: 8 }}>
    <input className="input" type={f.type || "text"} value={value} placeholder={f.placeholder} onChange={(e) => onChange(f.type === "number" ? (e.target.value === "" ? "" : +e.target.value) : e.target.value)} />
    {f.suffix && <span className="dim mono" style={{ fontSize: 12, whiteSpace: "nowrap" }}>{f.suffix}</span>}
  </div></div>;
}

// ---------- Dropdown menu (for topbar) ----------
function Dropdown({ trigger, children, align = "right", width = 280 }) {
  const [open, setOpen] = uiUseState(false);
  const ref = uiUseRef(null);
  uiUseEffect(() => {
    const onDoc = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener("mousedown", onDoc);
    return () => document.removeEventListener("mousedown", onDoc);
  }, []);
  return (
    <div ref={ref} style={{ position: "relative" }}>
      <div onClick={() => setOpen((v) => !v)}>{trigger}</div>
      {open && (
        <div style={{ position: "absolute", top: "calc(100% + 8px)", [align]: 0, width, zIndex: 2000,
          background: "var(--bg-elev)", border: "1px solid var(--border-strong)", borderRadius: 12,
          boxShadow: "0 16px 50px -12px rgba(0,0,0,0.6)", overflow: "hidden", animation: "modal-in .15s ease" }}>
          {typeof children === "function" ? children(() => setOpen(false)) : children}
        </div>
      )}
    </div>
  );
}

// ---------- Host ----------
function UIHost() {
  const [toasts, setToasts] = uiUseState([]);
  const [modal, setModal] = uiUseState(null);
  uiUseEffect(() => {
    const handler = (e) => {
      const d = e.detail;
      if (d.kind === "toast") {
        const id = Math.random().toString(36).slice(2);
        setToasts((prev) => [...prev, { id, message: d.message, type: d.type }]);
        setTimeout(() => setToasts((prev) => prev.filter((t) => t.id !== id)), d.duration || 3200);
      } else if (d.kind === "modal") {
        setModal(d.config);
      } else if (d.kind === "close") {
        setModal(null);
      }
    };
    window.addEventListener(UI_EVT, handler);
    return () => window.removeEventListener(UI_EVT, handler);
  }, []);
  return (
    <>
      <ToastStack toasts={toasts} />
      {modal && <Modal config={modal} onClose={() => setModal(null)} />}
    </>
  );
}

// ---------- KV row for read-only modals ----------
function KV({ k, v, mono }) {
  return (
    <div style={{ display: "flex", justifyContent: "space-between", padding: "7px 0", borderBottom: "1px solid var(--border-faint)", fontSize: 13 }}>
      <span className="dim">{k}</span>
      <span className={mono ? "mono" : ""} style={{ textAlign: "right" }}>{v}</span>
    </div>
  );
}

Object.assign(window, { AGB_UI, Dropdown, UIHost, KV, downloadCSV, downloadText, downloadBlob });
