/* global React, Icon */
const { useState, useEffect, useRef } = React;

// ---- shared color maps ----
const STATUS = {
  completed: { c: "var(--ef-success)", bg: "#E7F2EA", label: "Completed" },
  completed_with_warnings: { c: "var(--ef-warning)", bg: "#FBF1E1", label: "Completed with warnings" },
  partially_completed: { c: "var(--ef-warning)", bg: "#FBF1E1", label: "Partially completed" },
  running: { c: "var(--ef-info)", bg: "#E5ECFB", label: "Running" },
  queued: { c: "var(--ef-ink-400)", bg: "var(--ef-bone-3)", label: "Queued" },
  retrying: { c: "var(--ef-info)", bg: "#E5ECFB", label: "Retrying" },
  failed: { c: "var(--ef-danger)", bg: "#F8E6E6", label: "Failed" },
  cancelled: { c: "var(--ef-ink-400)", bg: "var(--ef-bone-3)", label: "Cancelled" },
  waiting_for_human_review: { c: "var(--ef-violet)", bg: "#EEEAFE", label: "Waiting for review" },
  waiting_for_input: { c: "var(--ef-cyan)", bg: "#E0F5F9", label: "Waiting for input" },
  draft: { c: "var(--ef-ink-500)", bg: "var(--ef-bone-3)", label: "Draft" },
  active: { c: "var(--ef-success)", bg: "#E7F2EA", label: "Active" },
  paused: { c: "var(--ef-warning)", bg: "#FBF1E1", label: "Paused" },
  archived: { c: "var(--ef-ink-400)", bg: "var(--ef-bone-3)", label: "Archived" },
  error: { c: "var(--ef-danger)", bg: "#F8E6E6", label: "Error" },
  connected: { c: "var(--ef-success)", bg: "#E7F2EA", label: "Connected" },
  disconnected: { c: "var(--ef-ink-400)", bg: "var(--ef-bone-3)", label: "Not connected" },
  expired: { c: "var(--ef-danger)", bg: "#F8E6E6", label: "Reauthorize" },
};
const CATEGORY = {
  Finance: "var(--ef-cobalt)", Accounting: "var(--ef-cobalt)", Banking: "var(--ef-cobalt)",
  Insurance: "var(--ef-violet)", Legal: "var(--ef-coral)", Healthcare: "var(--ef-cyan)",
  Manufacturing: "var(--ef-lime)", Logistics: "var(--ef-lime)", HR: "var(--ef-magenta)",
  Procurement: "var(--ef-cobalt)", Education: "var(--ef-cyan)", Operations: "var(--ef-ink-500)",
  Compliance: "var(--ef-coral)",
};
function statusMeta(s) { return STATUS[s] || { c: "var(--ef-ink-400)", bg: "var(--ef-bone-3)", label: s }; }
function catColor(c) { return CATEGORY[c] || "var(--ef-ink-500)"; }

// ---- Button ----
function Button({ variant = "secondary", size, icon, iconRight, children, className = "", ...rest }) {
  const cls = `btn btn-${variant} ${size ? "btn-" + size : ""} ${!children ? "btn-icon" : ""} ${className}`.trim();
  return (
    <button className={cls} {...rest}>
      {icon && <Icon name={icon} size={size === "sm" ? 15 : 16} />}
      {children}
      {iconRight && <Icon name={iconRight} size={size === "sm" ? 15 : 16} />}
    </button>
  );
}

// ---- Badge ----
function StatusBadge({ status, dot = true, size }) {
  const m = statusMeta(status);
  return (
    <span className="badge badge-solid" style={{ background: m.bg, color: m.c, fontSize: size === "sm" ? 11 : 11.5 }}>
      {dot && <span className="dot" style={{ background: m.c, width: 6, height: 6 }} />}
      {m.label}
    </span>
  );
}
function Badge({ children, color, bg, style }) {
  return <span className="badge" style={{ ...(color ? { color, borderColor: "transparent" } : {}), ...(bg ? { background: bg } : {}), ...style }}>{children}</span>;
}
function CategoryChip({ category }) {
  const c = catColor(category);
  return <span className="badge badge-solid" style={{ background: "transparent", color: c, border: `1px solid ${c}`, opacity: 0.95 }}>
    <span className="dot" style={{ background: c, width: 6, height: 6 }} />{category}</span>;
}

// ---- Avatar ----
function Avatar({ name, size = 28, color }) {
  const initials = (name || "?").split(" ").map((w) => w[0]).slice(0, 2).join("").toUpperCase();
  const palette = ["var(--ef-cobalt)", "var(--ef-violet)", "var(--ef-coral)", "var(--ef-cyan)", "var(--ef-lime)", "var(--ef-magenta)"];
  const bg = color || palette[(name || "").charCodeAt(0) % palette.length];
  return (
    <div style={{ width: size, height: size, borderRadius: 999, background: bg, color: "#fff", display: "flex", alignItems: "center", justifyContent: "center", fontSize: size * 0.4, fontWeight: 700, flexShrink: 0, letterSpacing: "-0.01em" }}>
      {initials}
    </div>
  );
}

// ---- Field ----
function Field({ label, help, children, required }) {
  return (
    <div style={{ marginBottom: 18 }}>
      {label && <label className="field-label">{label}{required && <span style={{ color: "var(--ef-danger)" }}> *</span>}</label>}
      {children}
      {help && <div className="field-help">{help}</div>}
    </div>
  );
}

// ---- Toggle ----
function Toggle({ checked, onChange }) {
  return (
    <button onClick={() => onChange?.(!checked)} style={{
      width: 40, height: 24, borderRadius: 999, border: 0, padding: 2,
      background: checked ? "var(--ef-ink-950)" : "var(--ef-ink-200)",
      display: "flex", justifyContent: checked ? "flex-end" : "flex-start",
      transition: "background 150ms",
    }}>
      <span style={{ width: 20, height: 20, borderRadius: 999, background: "#fff", boxShadow: "var(--ef-shadow-sm)", transition: "all 150ms" }} />
    </button>
  );
}

// ---- Modal ----
function Modal({ title, subtitle, children, onClose, footer, width = 560 }) {
  useEffect(() => {
    const h = (e) => e.key === "Escape" && onClose?.();
    window.addEventListener("keydown", h);
    return () => window.removeEventListener("keydown", h);
  }, []);
  return (
    <div className="modal-scrim" onMouseDown={(e) => e.target === e.currentTarget && onClose?.()}>
      <div className="modal" style={{ maxWidth: width }}>
        <div style={{ display: "flex", alignItems: "flex-start", justifyContent: "space-between", padding: "22px 24px 0" }}>
          <div>
            {title && <h4 style={{ fontSize: 20 }}>{title}</h4>}
            {subtitle && <p className="muted" style={{ fontSize: 13.5, marginTop: 5 }}>{subtitle}</p>}
          </div>
          <Button variant="ghost" size="sm" icon="x" onClick={onClose} />
        </div>
        <div style={{ padding: "20px 24px" }}>{children}</div>
        {footer && <div style={{ display: "flex", justifyContent: "flex-end", gap: 10, padding: "16px 24px", borderTop: "1px solid var(--ef-border)" }}>{footer}</div>}
      </div>
    </div>
  );
}

// ---- Tabs ----
function Tabs({ tabs, active, onChange }) {
  return (
    <div className="tabs">
      {tabs.map((t) => {
        const id = typeof t === "string" ? t : t.id;
        const label = typeof t === "string" ? t : t.label;
        const count = typeof t === "object" ? t.count : undefined;
        return (
          <div key={id} className={`tab ${active === id ? "active" : ""}`} onClick={() => onChange(id)}>
            {label}{count != null && <span className="mono" style={{ marginLeft: 7, fontSize: 11, color: "var(--ef-fg-4)" }}>{count}</span>}
          </div>
        );
      })}
    </div>
  );
}

// ---- Empty state ----
function EmptyState({ icon, title, body, actions, compact }) {
  return (
    <div style={{ display: "flex", flexDirection: "column", alignItems: "center", textAlign: "center", padding: compact ? "36px 24px" : "64px 24px", gap: 8 }}>
      {icon && <div style={{ width: 56, height: 56, borderRadius: 14, background: "var(--ef-bone-2)", border: "1px solid var(--ef-border)", display: "flex", alignItems: "center", justifyContent: "center", marginBottom: 8 }}>
        <Icon name={icon} size={26} color="var(--ef-ink-400)" /></div>}
      <h5 style={{ fontSize: 18 }}>{title}</h5>
      {body && <p className="muted" style={{ fontSize: 14, maxWidth: 420, lineHeight: 1.5 }}>{body}</p>}
      {actions && <div style={{ display: "flex", gap: 10, marginTop: 12 }}>{actions}</div>}
    </div>
  );
}

// ---- Section header ----
function PageHeader({ eyebrow, title, subtitle, actions, icon }) {
  return (
    <div style={{ display: "flex", alignItems: "flex-end", justifyContent: "space-between", gap: 24, marginBottom: 24, flexWrap: "wrap" }}>
      <div style={{ minWidth: 0 }}>
        {eyebrow && <div className="eyebrow" style={{ marginBottom: 8 }}>{eyebrow}</div>}
        <h2 style={{ fontSize: 32, display: "flex", alignItems: "center", gap: 12 }}>{title}</h2>
        {subtitle && <p className="muted" style={{ fontSize: 15, marginTop: 8, maxWidth: 640 }}>{subtitle}</p>}
      </div>
      {actions && <div style={{ display: "flex", gap: 10, flexShrink: 0 }}>{actions}</div>}
    </div>
  );
}

// ---- Stepper ----
function Stepper({ steps, current }) {
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 0 }}>
      {steps.map((s, i) => {
        const done = i < current, active = i === current;
        return (
          <React.Fragment key={i}>
            <div style={{ display: "flex", alignItems: "center", gap: 9, flexShrink: 0 }}>
              <div style={{
                width: 26, height: 26, borderRadius: 999, flexShrink: 0,
                background: done ? "var(--ef-ink-950)" : active ? "var(--ef-beam-500)" : "var(--ef-bone-3)",
                color: done ? "var(--ef-bone)" : active ? "var(--ef-ink-950)" : "var(--ef-fg-4)",
                display: "flex", alignItems: "center", justifyContent: "center", fontSize: 12, fontWeight: 700,
                border: active ? "0" : done ? "0" : "1px solid var(--ef-border-strong)",
              }}>
                {done ? <Icon name="check" size={14} color="var(--ef-bone)" /> : i + 1}
              </div>
              <span style={{ fontSize: 12.5, fontWeight: active || done ? 700 : 600, color: active || done ? "var(--ef-fg-1)" : "var(--ef-fg-4)", whiteSpace: "nowrap" }}>{s}</span>
            </div>
            {i < steps.length - 1 && <div style={{ flex: 1, height: 1, background: done ? "var(--ef-ink-300)" : "var(--ef-border)", margin: "0 12px", minWidth: 16 }} />}
          </React.Fragment>
        );
      })}
    </div>
  );
}

// ---- Toast ----
function useToast() {
  const [toasts, setToasts] = useState([]);
  const push = (msg, kind = "default") => {
    const id = Math.random().toString(36).slice(2);
    setToasts((t) => [...t, { id, msg, kind }]);
    setTimeout(() => setToasts((t) => t.filter((x) => x.id !== id)), 3200);
  };
  const node = (
    <div style={{ position: "fixed", bottom: 24, right: 24, display: "flex", flexDirection: "column", gap: 10, zIndex: 80 }}>
      {toasts.map((t) => (
        <div key={t.id} className="fade-in" style={{
          background: "var(--ef-ink-950)", color: "var(--ef-bone)", borderRadius: 10, padding: "12px 16px",
          fontSize: 13.5, fontWeight: 600, boxShadow: "var(--ef-shadow-lg)", display: "flex", alignItems: "center", gap: 10, maxWidth: 380,
        }}>
          <Icon name={t.kind === "success" ? "check-circle" : t.kind === "error" ? "alert-circle" : "info"} size={17}
            color={t.kind === "success" ? "var(--ef-beam-500)" : t.kind === "error" ? "#F08A8A" : "var(--ef-beam-500)"} />
          {t.msg}
        </div>
      ))}
    </div>
  );
  return [push, node];
}

// ---- KPI / stat ----
function Stat({ label, value, sub, icon, trend }) {
  return (
    <div className="card card-pad" style={{ flex: 1, minWidth: 0 }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start" }}>
        <div className="eyebrow">{label}</div>
        {icon && <Icon name={icon} size={17} color="var(--ef-fg-4)" />}
      </div>
      <div style={{ fontSize: 30, fontWeight: 800, letterSpacing: "-0.03em", color: "var(--ef-fg-1)", marginTop: 10, fontVariantNumeric: "tabular-nums" }}>{value}</div>
      {sub && <div style={{ fontSize: 12.5, color: trend === "up" ? "var(--ef-success)" : trend === "down" ? "var(--ef-danger)" : "var(--ef-fg-3)", marginTop: 4, fontWeight: 600 }}>{sub}</div>}
    </div>
  );
}

// ---- node type meta (used by builder + execution graph) ----
const NODE_TYPES = {
  trigger: { color: "var(--ef-beam-600)", icon: "zap", label: "Trigger" },
  input: { color: "var(--ef-cobalt)", icon: "inbox", label: "Input" },
  processing: { color: "var(--ef-violet)", icon: "sparkles", label: "Processing" },
  decision: { color: "var(--ef-warning)", icon: "git-branch", label: "Decision" },
  human: { color: "var(--ef-cyan)", icon: "user-plus", label: "Human review" },
  output: { color: "var(--ef-success)", icon: "send", label: "Output" },
  wait: { color: "var(--ef-ink-400)", icon: "clock", label: "Wait" },
  merge: { color: "var(--ef-magenta)", icon: "git-merge", label: "Merge" },
  error: { color: "var(--ef-danger)", icon: "alert-triangle", label: "Error handler" },
};

window.UI = { Button, StatusBadge, Badge, CategoryChip, Avatar, Field, Toggle, Modal, Tabs, EmptyState, PageHeader, Stepper, useToast, Stat, statusMeta, catColor, STATUS, CATEGORY, NODE_TYPES };
