// OrchestAI — shared UI primitives, icons, helpers
const { useState, useEffect, useRef, useMemo, useCallback } = React;

// ---------- Helpers ----------
function classNames(...xs) { return xs.filter(Boolean).join(" "); }
function fmt(n, opts = {}) {
  if (n === null || n === undefined || isNaN(n)) return "—";
  const { decimals = 1, prefix = "", suffix = "", abbr = false } = opts;
  if (abbr) {
    const abs = Math.abs(n);
    if (abs >= 1e9) return prefix + (n / 1e9).toFixed(decimals) + "B" + suffix;
    if (abs >= 1e6) return prefix + (n / 1e6).toFixed(decimals) + "M" + suffix;
    if (abs >= 1e3) return prefix + (n / 1e3).toFixed(decimals) + "k" + suffix;
  }
  return prefix + Number(n).toLocaleString("es-AR", { minimumFractionDigits: decimals, maximumFractionDigits: decimals }) + suffix;
}
function pct(n, decimals = 1) { return (n * 100).toFixed(decimals) + "%"; }

function greeting() {
  const h = new Date().getHours();
  if (h < 12) return "greeting_morning";
  if (h < 19) return "greeting_afternoon";
  return "greeting_evening";
}

function initials(name) {
  if (!name) return "?";
  const parts = name.trim().split(/\s+/);
  if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase();
  return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
}

// i18n factory
function makeT(lang) {
  const dict = window.I18N[lang] || window.I18N.es;
  return (key) => {
    const parts = key.split(".");
    let cur = dict;
    for (const p of parts) { cur = cur?.[p]; if (cur === undefined) return key; }
    return cur;
  };
}

function useI18n(lang) {
  return useMemo(() => {
    const dict = window.I18N[lang] || window.I18N.es;
    const t = (key) => {
      const parts = key.split(".");
      let cur = dict;
      for (const p of parts) { cur = cur?.[p]; if (cur === undefined) return key; }
      return cur;
    };
    return { t, dict, lang };
  }, [lang]);
}

// DB hook — syncs with oai:db event
function useDB() {
  const [data, setData] = useState(() => window.DB.get());
  useEffect(() => {
    const handler = (e) => setData({ ...e.detail });
    window.addEventListener("oai:db", handler);
    return () => window.removeEventListener("oai:db", handler);
  }, []);
  return data;
}

// ---------- Icons ----------
const Icon = {
  plus:     (p) => <svg {...p} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"><path d="M12 5v14M5 12h14"/></svg>,
  search:   (p) => <svg {...p} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"><circle cx="11" cy="11" r="7"/><path d="M21 21l-4.3-4.3"/></svg>,
  upload:   (p) => <svg {...p} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><path d="M12 15V4M6 10l6-6 6 6"/><path d="M4 18v2h16v-2"/></svg>,
  folder:   (p) => <svg {...p} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinejoin="round"><path d="M3 6.5A1.5 1.5 0 0 1 4.5 5H9l2.5 2.5h8A1.5 1.5 0 0 1 21 9v9.5A1.5 1.5 0 0 1 19.5 20h-15A1.5 1.5 0 0 1 3 18.5v-12Z"/></svg>,
  doc:      (p) => <svg {...p} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinejoin="round"><path d="M7 3h7l5 5v13H7z"/><path d="M14 3v5h5"/></svg>,
  book:     (p) => <svg {...p} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinejoin="round"><path d="M4 5a2 2 0 0 1 2-2h14v16H6a2 2 0 0 0-2 2z"/><path d="M6 21h14"/></svg>,
  graph:    (p) => <svg {...p} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6"><circle cx="5" cy="6" r="2"/><circle cx="19" cy="6" r="2"/><circle cx="12" cy="18" r="2"/><path d="M7 7l4 9M17 7l-4 9"/></svg>,
  chart:    (p) => <svg {...p} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"><path d="M4 19V5M4 19h16"/><path d="M8 15l4-6 4 4 4-6"/></svg>,
  bolt:     (p) => <svg {...p} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinejoin="round"><path d="M13 2L4 14h7l-1 8 9-12h-7z"/></svg>,
  settings: (p) => <svg {...p} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6"><circle cx="12" cy="12" r="3"/><path d="M12 2v3M12 19v3M4.2 4.2l2.1 2.1M17.7 17.7l2.1 2.1M2 12h3M19 12h3M4.2 19.8l2.1-2.1M17.7 6.3l2.1-2.1"/></svg>,
  check:    (p) => <svg {...p} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M5 12l4.5 4.5L19 7"/></svg>,
  x:        (p) => <svg {...p} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"><path d="M6 6l12 12M18 6L6 18"/></svg>,
  chevdown: (p) => <svg {...p} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"><path d="M6 9l6 6 6-6"/></svg>,
  chevright:(p) => <svg {...p} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"><path d="M9 6l6 6-6 6"/></svg>,
  ai:       (p) => <svg {...p} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinejoin="round"><path d="M12 3v3M12 18v3M3 12h3M18 12h3M5.6 5.6l2.1 2.1M16.3 16.3l2.1 2.1M5.6 18.4l2.1-2.1M16.3 7.7l2.1-2.1"/><circle cx="12" cy="12" r="4"/></svg>,
  send:     (p) => <svg {...p} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinejoin="round"><path d="M4 12l16-8-5 16-3-7-8-1z"/></svg>,
  sparkle:  (p) => <svg {...p} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinejoin="round"><path d="M12 3l2 5 5 2-5 2-2 5-2-5-5-2 5-2z"/></svg>,
  export:   (p) => <svg {...p} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><path d="M12 4v12M7 9l5-5 5 5"/><path d="M4 20h16"/></svg>,
  globe:    (p) => <svg {...p} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6"><circle cx="12" cy="12" r="9"/><path d="M3 12h18M12 3c3 3 3 15 0 18M12 3c-3 3-3 15 0 18"/></svg>,
  dot:      (p) => <svg {...p} viewBox="0 0 24 24" fill="currentColor"><circle cx="12" cy="12" r="3"/></svg>,
  pin:      (p) => <svg {...p} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinejoin="round"><path d="M12 3l5 5-2 2 1 5-4-4-6 6 1-6-4-4 5-2z"/></svg>,
  filter:   (p) => <svg {...p} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"><path d="M4 5h16l-6 8v6l-4-2v-4z"/></svg>,
  link:     (p) => <svg {...p} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"><path d="M10 14a4 4 0 0 1 0-6l3-3a4 4 0 0 1 6 6l-1.5 1.5"/><path d="M14 10a4 4 0 0 1 0 6l-3 3a4 4 0 0 1-6-6l1.5-1.5"/></svg>,
  more:     (p) => <svg {...p} viewBox="0 0 24 24" fill="currentColor"><circle cx="6" cy="12" r="1.5"/><circle cx="12" cy="12" r="1.5"/><circle cx="18" cy="12" r="1.5"/></svg>,
  home:     (p) => <svg {...p} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinejoin="round"><path d="M4 11l8-7 8 7v9a1 1 0 0 1-1 1h-4v-6h-6v6H5a1 1 0 0 1-1-1z"/></svg>,
  bell:     (p) => <svg {...p} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><path d="M6 15V10a6 6 0 0 1 12 0v5l2 2H4z"/><path d="M10 20a2 2 0 0 0 4 0"/></svg>,
  trash:    (p) => <svg {...p} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><path d="M3 6h18M8 6V4h8v2M19 6l-1 14H6L5 6"/></svg>,
  user:     (p) => <svg {...p} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"><circle cx="12" cy="8" r="4"/><path d="M4 20c0-4 3.6-7 8-7s8 3 8 7"/></svg>
};

// ---------- Primitives ----------
function Button({ kind = "ghost", size = "md", icon, children, className, ...rest }) {
  const base = "oai-btn oai-btn--" + kind + " oai-btn--" + size;
  return (
    <button className={classNames(base, className)} {...rest}>
      {icon ? React.createElement(icon, { className: "oai-btn__icon" }) : null}
      {children && <span>{children}</span>}
    </button>
  );
}

function Pill({ tone = "neutral", children, icon }) {
  return <span className={"oai-pill oai-pill--" + tone}>
    {icon ? React.createElement(icon, { className: "oai-pill__icon" }) : null}
    {children}
  </span>;
}

function Card({ children, className, padded = true, ...rest }) {
  return <div className={classNames("oai-card", padded && "oai-card--padded", className)} {...rest}>{children}</div>;
}

function Field({ label, hint, children }) {
  return (
    <label className="oai-field">
      {label && <span className="oai-field__label">{label}</span>}
      {children}
      {hint && <span className="oai-field__hint">{hint}</span>}
    </label>
  );
}

function Input(props) { return <input className="oai-input" {...props} />; }
function Select({ children, ...props }) { return <select className="oai-select" {...props}>{children}</select>; }
function Textarea(props) { return <textarea className="oai-textarea" {...props} />; }

function Toggle({ checked, onChange, label }) {
  return (
    <label className="oai-toggle">
      <input type="checkbox" checked={!!checked} onChange={e => onChange?.(e.target.checked)} />
      <span className="oai-toggle__track"><span className="oai-toggle__thumb"/></span>
      {label && <span className="oai-toggle__label">{label}</span>}
    </label>
  );
}

function Segmented({ options, value, onChange }) {
  return (
    <div className="oai-seg">
      {options.map(o => (
        <button key={o.value} className={classNames("oai-seg__item", value === o.value && "is-active")} onClick={() => onChange(o.value)}>
          {o.icon ? React.createElement(o.icon, { className: "oai-seg__icon" }) : null}
          {o.label}
        </button>
      ))}
    </div>
  );
}

function Avatar({ initials: ini, size = 28 }) {
  return <div className="oai-avatar" style={{ width: size, height: size, fontSize: size * 0.38 }}>{ini}</div>;
}

function EmptyState({ icon, title, sub, action }) {
  return (
    <div className="empty-state">
      {icon && React.createElement(icon, { style: { width: 40, height: 40, margin: "0 auto 12px", opacity: 0.35 } })}
      <div style={{ fontWeight: 600, fontSize: 15, marginBottom: 6 }}>{title}</div>
      {sub && <div style={{ fontSize: 13, color: "var(--oai-ink-3)", maxWidth: 360, margin: "0 auto" }}>{sub}</div>}
      {action && <div style={{ marginTop: 16 }}>{action}</div>}
    </div>
  );
}

// Sparkline
function Sparkline({ values, width = 80, height = 24, color = "currentColor" }) {
  if (!values || values.length < 2) return null;
  const max = Math.max(...values), min = Math.min(...values);
  const range = max - min || 1;
  const step = width / (values.length - 1);
  const pts = values.map((v, i) => `${i * step},${height - ((v - min) / range) * height}`).join(" ");
  return (
    <svg width={width} height={height} className="oai-spark">
      <polyline points={pts} fill="none" stroke={color} strokeWidth="1.4" strokeLinejoin="round" strokeLinecap="round" />
    </svg>
  );
}

// AI helper — proxies to /api/analyze (Vercel serverless)
async function callAI(system, messages, maxTokens = 1024, model = "claude-haiku-4-5-20251001") {
  const res = await fetch("/api/analyze", {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify({ system, messages, max_tokens: maxTokens, model }),
  });
  if (!res.ok) {
    const err = await res.json().catch(() => ({}));
    throw new Error(err.error || "Error " + res.status);
  }
  const data = await res.json();
  return data.text || "";
}

// Expose
Object.assign(window, {
  classNames, fmt, pct, greeting, initials, makeT, useI18n, useDB, callAI,
  Icon, Button, Pill, Card, Field, Input, Select, Textarea, Toggle, Segmented, Avatar, EmptyState, Sparkline
});
