/* ui.jsx — composants partagés (sidebar, topbar, badges, KPI, charts, helpers) */
const { useState, useEffect, useRef, useMemo } = React;
const I = window.Icons;

/* ---------- helpers ---------- */
const fmt = (n) => new Intl.NumberFormat("fr-FR").format(Math.round(n));
const eur = (n) => new Intl.NumberFormat("fr-FR", { style:"currency", currency:"EUR" }).format(n);
const toneClass = (t) => ({ blue:"badge--blue", green:"badge--green", amber:"badge--amber", red:"badge--red", violet:"badge--violet", gray:"badge--gray" }[t] || "badge--gray");
const toneVar = (t) => ({ blue:"var(--primary)", green:"var(--green)", amber:"var(--amber)", red:"var(--red)", violet:"var(--violet)", gray:"var(--text-3)" }[t] || "var(--text-3)");
const toneSoft = (t) => ({ blue:"var(--primary-soft)", green:"var(--green-soft)", amber:"var(--amber-soft)", red:"var(--red-soft)", violet:"var(--violet-soft)", gray:"var(--surface-3)" }[t] || "var(--surface-3)");

function Ic({ name, ...p }) { const C = I[name]; return C ? React.createElement(C, p) : null; }

/* ---------- Badge ---------- */
function Badge({ tone="gray", dot, children }) {
  return <span className={"badge " + toneClass(tone)}>{dot && <span className="dot" />}{children}</span>;
}
const STATUS = {
  published:{ tone:"green", label:"Publié", dot:true },
  draft:{ tone:"amber", label:"Brouillon", dot:true },
  paid:{ tone:"green", label:"Payée" },
  pending:{ tone:"amber", label:"À régler" },
  active:{ tone:"green", label:"Actif", dot:true },
  invited:{ tone:"gray", label:"Invité", dot:true },
};
function StatusBadge({ s }) { const m = STATUS[s] || {tone:"gray",label:s}; return <Badge tone={m.tone} dot={m.dot}>{m.label}</Badge>; }

/* ---------- Service icon tile ---------- */
function SvcIcon({ service, size }) {
  const st = { background: toneSoft(service.tone), color: toneVar(service.tone) };
  if (size) st.width = st.height = size;
  return <div className="svc-ic" style={st}><Ic name={service.icon} /></div>;
}

/* ---------- KPI card ---------- */
function Kpi({ icon, label, value, unit, delta, deltaDir="up", sub }) {
  return (
    <div className="card kpi">
      <div className="kpi__top">
        <span className="kpi__label">{label}</span>
        <span className="kpi__ic"><Ic name={icon} /></span>
      </div>
      <div className="kpi__val">{value}{unit && <small> {unit}</small>}</div>
      <div style={{ display:"flex", alignItems:"center", gap:8 }}>
        {delta != null && (
          <span className={"kpi__delta " + deltaDir}>
            <Ic name={deltaDir==="down"?"ArrowDown":deltaDir==="flat"?"ChevRight":"ArrowUp"} width={13} height={13} />
            {delta}
          </span>
        )}
        {sub && <span className="muted" style={{ fontSize:12 }}>{sub}</span>}
      </div>
    </div>
  );
}

/* ---------- Provider / connector ---------- */
function provInitials(name) {
  const parts = name.replace(/[^A-Za-zÀ-ÿ0-9 ]/g,"").split(/\s+/).filter(Boolean);
  if (parts.length > 1) return (parts[0][0] + parts[1][0]).toUpperCase();
  return (name || "?").slice(0, 2).toUpperCase();
}
function ProviderTile({ p, size = 32 }) {
  const native = p.kind === "native";
  return (
    <div style={{ width:size, height:size, borderRadius:8, flex:"none", display:"grid", placeItems:"center",
      fontFamily:"var(--mono)", fontWeight:600, fontSize: size*0.36, letterSpacing:"-0.02em",
      background: native ? "var(--primary)" : "var(--surface)", color: native ? "#fff" : "var(--text-2)",
      border: native ? "none" : "1px solid var(--border-strong)" }}>
      {provInitials(p.name)}
    </div>
  );
}

/* ---------- Sidebar ---------- */
const NAV = [
  { group:"Pilotage", items:[
    { id:"dashboard", label:"Tableau de bord", icon:"Dashboard" },
    { id:"billing", label:"Consommation & facturation", icon:"Billing" },
  ]},
  { group:"Orchestration", items:[
    { id:"journeys", label:"Parcours métier", icon:"Flow", badge:"4" },
    { id:"catalog", label:"Catalogue de services", icon:"Catalog" },
    { id:"forms", label:"Formulaires", icon:"Form" },
  ]},
  { group:"Administration", items:[
    { id:"users", label:"Utilisateurs & rôles", icon:"Users" },
    { id:"settings", label:"Paramètres du tenant", icon:"Settings" },
  ]},
];

function Sidebar({ route, go, tenant }) {
  return (
    <aside className="sidebar">
      <div className="sidebar__brand">
        <div className="brandmark" style={{ background: tenant.color }}>{tenant.initials}</div>
        <div style={{ minWidth:0 }}>
          <div className="brand__name">{tenant.name}</div>
          <div className="brand__sub">Espace tenant · Confiance</div>
        </div>
      </div>
      <div className="sidebar__scroll">
        {NAV.map(g => (
          <div className="nav-group" key={g.group}>
            <div className="nav-group__label">{g.group}</div>
            {g.items.map(it => (
              <button key={it.id} className={"nav-item" + (route===it.id ? " is-active":"")} onClick={() => go(it.id)}>
                <Ic name={it.icon} />
                <span>{it.label}</span>
                {it.badge && <span className="nav-item__badge">{it.badge}</span>}
              </button>
            ))}
          </div>
        ))}
      </div>
      <div className="sidebar__foot">
        <div className="avatar" style={{ background:"var(--primary-soft)", color:"var(--primary)" }}>CR</div>
        <div style={{ minWidth:0, flex:1 }}>
          <div style={{ fontSize:12.5, fontWeight:600 }}>Camille Roux</div>
          <div style={{ fontSize:11, color:"var(--text-3)" }}>Administrateur</div>
        </div>
        <button className="btn btn--ghost btn--sm btn--icon" title="Paramètres"><Ic name="Settings" width={16} height={16}/></button>
      </div>
    </aside>
  );
}

/* ---------- Topbar ---------- */
function Topbar({ title, crumb, actions, onMenu }) {
  return (
    <header className="topbar">
      <button className="btn btn--ghost btn--icon hamburger" onClick={onMenu}><Ic name="Menu" /></button>
      <div>
        {crumb && <div className="topbar__crumb">{crumb}</div>}
        <div className="topbar__title">{title}</div>
      </div>
      <div className="topbar__spacer" />
      <div className="search"><Ic name="Search" width={16} height={16} /><input placeholder="Rechercher un parcours, un service…" /></div>
      <button className="btn btn--ghost btn--icon" title="Notifications"><Ic name="Bell" /></button>
      {actions}
    </header>
  );
}

/* ---------- Charts (SVG, simple shapes) ---------- */
function BarChart({ data, labels, height=180, color="var(--primary)", unit }) {
  const max = Math.max(...data, 1);
  const n = data.length;
  const [hover, setHover] = useState(null);
  return (
    <div style={{ position:"relative" }}>
      <div style={{ display:"flex", alignItems:"flex-end", gap:`${Math.max(3, 40/n)}px`, height }}>
        {data.map((v, i) => (
          <div key={i} style={{ flex:1, display:"flex", flexDirection:"column", justifyContent:"flex-end", alignItems:"center", gap:6, height:"100%" }}
               onMouseEnter={() => setHover(i)} onMouseLeave={() => setHover(null)}>
            {hover===i && (
              <div className="mono" style={{ position:"absolute", top:-4, transform:"translateY(-100%)", background:"var(--text)", color:"#fff", fontSize:11, padding:"3px 7px", borderRadius:6, whiteSpace:"nowrap", zIndex:3 }}>
                {fmt(v)} {unit}
              </div>
            )}
            <div style={{ width:"100%", maxWidth:34, height:`${(v/max)*100}%`, minHeight:3, background: hover===i? color : `color-mix(in oklch, ${color} 78%, white)`, borderRadius:"5px 5px 2px 2px", transition:"height .4s cubic-bezier(.2,.8,.2,1), background .12s" }} />
          </div>
        ))}
      </div>
      {labels && <div style={{ display:"flex", gap:`${Math.max(3,40/n)}px`, marginTop:8 }}>
        {labels.map((l,i) => <div key={i} style={{ flex:1, textAlign:"center", fontSize:10.5, color:"var(--text-3)" }}>{l}</div>)}
      </div>}
    </div>
  );
}

function LineChart({ series, labels, height=180 }) {
  const W = 640, H = height, pad = 6;
  const all = series.flatMap(s => s.data);
  const max = Math.max(...all, 1);
  const x = (i, n) => pad + (i/(n-1)) * (W - pad*2);
  const y = (v) => H - pad - (v/max) * (H - pad*2);
  return (
    <div>
      <svg viewBox={`0 0 ${W} ${H}`} style={{ width:"100%", height, overflow:"visible" }} preserveAspectRatio="none">
        {[0.25,0.5,0.75,1].map((g,i) => <line key={i} x1={0} x2={W} y1={H-pad-g*(H-pad*2)} y2={H-pad-g*(H-pad*2)} stroke="var(--border)" strokeWidth="1" />)}
        {series.map((s, si) => {
          const pts = s.data.map((v,i) => `${x(i,s.data.length)},${y(v)}`).join(" ");
          return <g key={si}>
            <polyline points={pts} fill="none" stroke={s.color} strokeWidth="2.5" strokeLinejoin="round" strokeLinecap="round" vectorEffect="non-scaling-stroke" />
            {s.data.map((v,i) => <circle key={i} cx={x(i,s.data.length)} cy={y(v)} r="2.6" fill={s.color} />)}
          </g>;
        })}
      </svg>
      {labels && <div style={{ display:"flex", justifyContent:"space-between", marginTop:6 }}>
        {labels.map((l,i) => <span key={i} style={{ fontSize:10.5, color:"var(--text-3)" }}>{l}</span>)}
      </div>}
    </div>
  );
}

function Donut({ segments, size=132, thickness=18 }) {
  const total = segments.reduce((a,s) => a+s.value, 0) || 1;
  const r = (size - thickness) / 2;
  const C = 2 * Math.PI * r;
  let off = 0;
  return (
    <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
      <g transform={`rotate(-90 ${size/2} ${size/2})`}>
        {segments.map((s,i) => {
          const len = (s.value/total) * C;
          const el = <circle key={i} cx={size/2} cy={size/2} r={r} fill="none" stroke={s.color} strokeWidth={thickness}
            strokeDasharray={`${len} ${C-len}`} strokeDashoffset={-off} strokeLinecap="butt" />;
          off += len; return el;
        })}
      </g>
    </svg>
  );
}

/* ---------- Modal ---------- */
function Modal({ title, icon, onClose, children, foot, lg }) {
  useEffect(() => {
    const h = (e) => e.key === "Escape" && onClose();
    window.addEventListener("keydown", h); return () => window.removeEventListener("keydown", h);
  }, []);
  return (
    <div className="overlay" onMouseDown={(e) => e.target === e.currentTarget && onClose()}>
      <div className={"modal" + (lg ? " modal--lg":"")}>
        <div className="modal__head">
          {icon && <span className="kpi__ic" style={{ width:32, height:32 }}><Ic name={icon} width={17} height={17} /></span>}
          <h3>{title}</h3>
          <div style={{ flex:1 }} />
          <button className="btn btn--ghost btn--icon btn--sm" onClick={onClose}><Ic name="X" /></button>
        </div>
        <div className="modal__body">{children}</div>
        {foot && <div className="modal__foot">{foot}</div>}
      </div>
    </div>
  );
}

Object.assign(window, { fmt, eur, toneClass, toneVar, toneSoft, Ic, Badge, StatusBadge, SvcIcon, ProviderTile, provInitials, Kpi, Sidebar, Topbar, BarChart, LineChart, Donut, Modal, NAV });
