/* =============================================================
   Sentinel — shared components
   ============================================================= */

const { useState: useStateHF, useEffect: useEffectHF, useRef: useRefHF, useMemo: useMemoHF } = React;

// ---------- Lucide icon component (inline SVG, paths cherry-picked) ----------
const ICON_PATHS = {
  layoutDashboard: <><rect x="3" y="3" width="7" height="9" rx="1"/><rect x="14" y="3" width="7" height="5" rx="1"/><rect x="14" y="12" width="7" height="9" rx="1"/><rect x="3" y="16" width="7" height="5" rx="1"/></>,
  bot: <><path d="M12 8V4H8"/><rect width="16" height="12" x="4" y="8" rx="2"/><path d="M2 14h2M20 14h2M15 13v2M9 13v2"/></>,
  activity: <path d="M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.5.5 0 0 1-.96 0L9.24 2.18a.5.5 0 0 0-.96 0l-2.35 8.36A2 2 0 0 1 4 12H2"/>,
  shield: <><path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/></>,
  zap: <path d="M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z"/>,
  fileCheck: <><path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/><path d="m9 15 2 2 4-4"/></>,
  settings: <><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/><circle cx="12" cy="12" r="3"/></>,
  search: <><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></>,
  bell: <><path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/><path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"/></>,
  download: <><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" x2="12" y1="15" y2="3"/></>,
  upload: <><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" x2="12" y1="3" y2="15"/></>,
  filter: <polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"/>,
  plus: <><path d="M5 12h14"/><path d="M12 5v14"/></>,
  check: <polyline points="20 6 9 17 4 12"/>,
  chevronRight: <polyline points="9 18 15 12 9 6"/>,
  chevronDown: <polyline points="6 9 12 15 18 9"/>,
  arrowRight: <><path d="M5 12h14"/><path d="m12 5 7 7-7 7"/></>,
  alertTriangle: <><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/></>,
  power: <><path d="M18.36 6.64a9 9 0 1 1-12.73 0"/><line x1="12" x2="12" y1="2" y2="12"/></>,
  lock: <><rect width="18" height="11" x="3" y="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></>,
  fileText: <><path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"/><path d="M14 2v6h6"/><path d="M16 13H8"/><path d="M16 17H8"/><path d="M10 9H8"/></>,
  package: <><path d="m7.5 4.27 9 5.15"/><path d="M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z"/><path d="m3.3 7 8.7 5 8.7-5"/><path d="M12 22V12"/></>,
  link2: <><path d="M9 17H7A5 5 0 0 1 7 7h2"/><path d="M15 7h2a5 5 0 1 1 0 10h-2"/><line x1="8" x2="16" y1="12" y2="12"/></>,
  trendingUp: <><polyline points="22 7 13.5 15.5 8.5 10.5 2 17"/><polyline points="16 7 22 7 22 13"/></>,
  trendingDown: <><polyline points="22 17 13.5 8.5 8.5 13.5 2 7"/><polyline points="16 17 22 17 22 11"/></>,
  more: <><circle cx="12" cy="12" r="1"/><circle cx="19" cy="12" r="1"/><circle cx="5" cy="12" r="1"/></>,
  user: <><path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></>,
  externalLink: <><path d="M15 3h6v6"/><path d="M10 14 21 3"/><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/></>,
  sparkle: <path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"/>,
  command: <path d="M18 3a3 3 0 0 0-3 3v12a3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3H6a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3V6a3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3h12a3 3 0 0 0 3-3 3 3 0 0 0-3-3z"/>,
  x: <><path d="M18 6 6 18"/><path d="m6 6 12 12"/></>,
  sun: <><circle cx="12" cy="12" r="4"/><path d="M12 2v2"/><path d="M12 20v2"/><path d="m4.93 4.93 1.41 1.41"/><path d="m17.66 17.66 1.41 1.41"/><path d="M2 12h2"/><path d="M20 12h2"/><path d="m6.34 17.66-1.41 1.41"/><path d="m19.07 4.93-1.41 1.41"/></>,
  moon: <path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"/>,
};

const Icon = ({ name, size = 18, stroke = 1.6, className = '' }) => {
  const path = ICON_PATHS[name];
  if (!path) return null;
  return (
    <svg className={`lucide ${className}`} width={size} height={size}
      viewBox="0 0 24 24" fill="none" stroke="currentColor"
      strokeWidth={stroke} strokeLinecap="round" strokeLinejoin="round">
      {path}
    </svg>
  );
};

// ---------- Provider mark (real logos when available, monogram fallback) ----------
// `logo`: filename in /public/assets/providers/ — when present, render the SVG.
// `bg`/`fg` define the tile colour (bg) and the logo tint (fg, applied via CSS filter on monochrome SVGs).
// `style: 'surface'` switches the tile to a white surface — used for marks whose source SVG is colourful
//                   (or where the brand colour reads better against a light tile).
const HF_PROVIDERS = {
  OpenAI:             { logo: 'openai.svg',         bg: '#10A37F', fg: '#ffffff' },
  Anthropic:          { logo: 'anthropic.svg',      bg: '#F4F1ED', fg: '#181818', style: 'surface' },
  Mistral:            { logo: 'mistralai.svg',      bg: '#0F1936', fg: '#FA7F2C' },
  'Mistral AI':       { logo: 'mistralai.svg',      bg: '#0F1936', fg: '#FA7F2C' },
  'Azure OpenAI':     { logo: 'microsoftazure.svg', bg: '#0078D4', fg: '#ffffff' },
  'Google Vertex':    { logo: 'googlecloud.svg',    bg: '#ffffff', fg: '#4285F4', style: 'surface' },
  'Google Gemini':    { logo: 'googlegemini.svg',   bg: '#ffffff', fg: '#1C69FF', style: 'surface' },
  'AWS Bedrock':      { logo: 'amazonaws.svg',      bg: '#232F3E', fg: '#FF9900' },
  Cohere:             { ini: 'Co', bg: '#39594D',   fg: '#D18EE2' },
  'Meta Llama':       { logo: 'meta.svg',           bg: '#ffffff', fg: '#0866FF', style: 'surface' },
  'Hugging Face':     { logo: 'huggingface.svg',    bg: '#FFD21E', fg: '#181818' },
  Ollama:             { logo: 'ollama.svg',         bg: '#ffffff', fg: '#0d0a2c', style: 'surface' },
  LangChain:          { logo: 'langchain.svg',      bg: '#1C3C3C', fg: '#ffffff' },
  LangGraph:          { logo: 'langgraph.svg',      bg: '#1C3C3C', fg: '#4D9DE0' },
  n8n:                { logo: 'n8n.svg',            bg: '#ffffff', fg: '#EA4B71', style: 'surface' },
  Make:               { logo: 'make.svg',           bg: '#ffffff', fg: '#6D00CC', style: 'surface' },
  'Azure AI Foundry': { logo: 'microsoftazure.svg', bg: '#0078D4', fg: '#ffffff' },
  IDUN:               { ini: 'I',  bg: '#6F2DBD', fg: '#ffffff' },
  'Active Directory': { logo: 'microsoftazure.svg', bg: '#0078D4', fg: '#ffffff' },
  GitHub:             { logo: 'github.svg',         bg: '#181717', fg: '#ffffff' },
  GitLab:             { logo: 'gitlab.svg',         bg: '#ffffff', fg: '#FC6D26', style: 'surface' },
  Ascenzia:           { ini: 'A',  bg: '#0d0a2c',   fg: '#ddac63' },
};

// Render a provider logo SVG with the requested foreground colour applied via mask trick.
// Most simple-icons SVGs use fill="currentColor" so we set color via CSS.
const ProviderLogo = ({ src, color, size }) => {
  // Use a CSS mask so we can apply the brand fg colour to any monochrome SVG reliably.
  return (
    <span
      aria-hidden="true"
      style={{
        display: 'block',
        width: size,
        height: size,
        background: color,
        WebkitMask: `url(${src}) center / contain no-repeat`,
        mask: `url(${src}) center / contain no-repeat`,
      }}
    />
  );
};

const ProviderMarkHF = ({ name, size = 32, radius = 8 }) => {
  const p = HF_PROVIDERS[name] || { ini: (name || '?').slice(0, 1).toUpperCase(), bg: '#0d0a2c', fg: '#fff' };
  const isAsc = name === 'Ascenzia';
  const innerSize = Math.round(size * 0.62);
  return (
    <div
      className="provider-mark"
      data-style={p.style || ''}
      title={name}
      style={{
        width: size,
        height: size,
        borderRadius: radius,
        background: p.bg,
        color: p.fg,
        fontSize: Math.floor(size * 0.42),
      }}
    >
      {isAsc ? (
        <svg viewBox="0 0 36 36" width={Math.round(size * 0.7)} height={Math.round(size * 0.7)}>
          <path d="M8 28 L18 6 L28 28" fill="none" stroke="#ddac63" strokeWidth="3.2" strokeLinecap="round" strokeLinejoin="round" />
          <path d="M11 22 L25 22" stroke="#ddac63" strokeWidth="3.2" strokeLinecap="round" />
          <path d="M14 16 Q18 12 22 16" fill="none" stroke="#ddac63" strokeWidth="2.2" strokeLinecap="round" />
        </svg>
      ) : p.logo ? (
        <ProviderLogo src={`assets/providers/${p.logo}`} color={p.fg} size={innerSize} />
      ) : (
        p.ini
      )}
    </div>
  );
};

// ---------- Activity Rings (Apple-style, hi-fi) ----------
// dimensions: [{ label, value 0..100, color }]
const ActivityRingsHF = ({ dimensions = [], size = 220, glow = true, strokeRatio = 0.075, gap = 4, animate = true }) => {
  const center = size / 2;
  const pad = 4;
  const maxR = size / 2 - pad;
  const strokeBase = Math.max(8, Math.floor(size * strokeRatio));
  const totalNeeded = strokeBase * dimensions.length + gap * (dimensions.length - 1);
  const stroke = totalNeeded > maxR
    ? Math.floor((maxR - gap * (dimensions.length - 1)) / dimensions.length)
    : strokeBase;

  return (
    <svg viewBox={`0 0 ${size} ${size}`} width={size} height={size}
      style={{ filter: glow ? 'drop-shadow(0 4px 16px rgba(13,10,44,0.10))' : 'none', display: 'block' }}>
      <defs>
        {dimensions.map((d, i) => (
          <linearGradient key={i} id={`ring-grad-${d.label.replace(/\s/g, '')}-${i}-${size}`} x1="0%" y1="0%" x2="100%" y2="100%">
            <stop offset="0%" stopColor={d.color} stopOpacity="1" />
            <stop offset="100%" stopColor={d.color} stopOpacity="0.7" />
          </linearGradient>
        ))}
      </defs>
      {dimensions.map((d, i) => {
        const r = maxR - i * (stroke + gap) - stroke / 2;
        if (r <= stroke / 2) return null;
        const c = 2 * Math.PI * r;
        const dash = Math.max(0.001, (d.value / 100) * c);
        const gradId = `ring-grad-${d.label.replace(/\s/g, '')}-${i}-${size}`;
        return (
          <g key={i}>
            <circle cx={center} cy={center} r={r} fill="none"
              stroke={d.color} strokeWidth={stroke} opacity="0.16" />
            <circle cx={center} cy={center} r={r} fill="none"
              stroke={`url(#${gradId})`} strokeWidth={stroke} strokeLinecap="round"
              strokeDasharray={`${dash} ${c}`}
              transform={`rotate(-90 ${center} ${center})`}
              style={animate ? { transition: 'stroke-dasharray 1.2s cubic-bezier(0.22, 1, 0.36, 1)' } : {}} />
          </g>
        );
      })}
    </svg>
  );
};

// ---------- Sparkline ----------
const SparkHF = ({ data, h = 80, color = 'currentColor', stroke = 2, area = true }) => {
  const w = 240;
  const max = Math.max(...data), min = Math.min(...data);
  const points = data.map((v, i) => [
    (i / (data.length - 1)) * w,
    h - 4 - ((v - min) / (max - min || 1)) * (h - 12),
  ]);
  const path = points.map(([x, y], i) => `${i === 0 ? 'M' : 'L'}${x.toFixed(1)} ${y.toFixed(1)}`).join(' ');
  return (
    <svg viewBox={`0 0 ${w} ${h}`} preserveAspectRatio="none" style={{ width: '100%', height: h, display: 'block' }}>
      {area && <path d={`${path} L${w} ${h} L0 ${h} Z`} fill={color} opacity="0.08" />}
      <path d={path} stroke={color} strokeWidth={stroke} fill="none" strokeLinecap="round" strokeLinejoin="round" />
    </svg>
  );
};

// ---------- Sovereignty badge ----------
const SovBadge = () => (
  <div className="sov-badge">Hébergé France · SecNumCloud</div>
);

// ---------- Sidebar nav ----------
const HF_NAV = [
  { key: 'cockpit', label: 'Cockpit', icon: 'layoutDashboard', count: '' },
  { key: 'parc', label: 'Parc d\'agents', icon: 'bot', count: '142' },
  { key: 'observe', label: 'Observabilité', icon: 'activity', count: '' },
  { key: 'secure', label: 'Sécurité', icon: 'shield', count: '3' },
  { key: 'pilot', label: 'Pilotage', icon: 'zap', count: '' },
  { key: 'compliance', label: 'Conformité', icon: 'fileCheck', count: '' },
];

const Sidebar = ({ current }) => (
  <aside className="sidebar">
    <div className="sidebar-brand">
      <img src="assets/brand/logo-ascenzia-white.svg" alt="Ascenzia" />
      <span style={{
        fontFamily: 'var(--font-primary)',
        fontSize: 10,
        letterSpacing: 'var(--track-label)',
        textTransform: 'uppercase',
        color: 'var(--gold-400)',
        fontWeight: 600,
        marginLeft: 'auto',
      }}>Sentinel</span>
    </div>

    <div className="sidebar-tenant">
      <span className="label">Tenant</span>
      <strong>Banque Aurore SA</strong>
      <span style={{ color: 'var(--fg-subtle)', fontSize: 11 }}>FR · Paris dc-3</span>
    </div>

    <div className="sidebar-group">Modules</div>
    {HF_NAV.map(it => (
      <a key={it.key} href={`#${it.key}`} className={`nav-item ${current === it.key ? 'active' : ''}`}>
        <Icon name={it.icon} size={16} />
        {it.label}
        {it.count && <span className="count">{it.count}</span>}
      </a>
    ))}

    <div className="sidebar-group" style={{ marginTop: 16 }}>Système</div>
    <a className="nav-item" href="#admin"><Icon name="settings" size={16} />Administration</a>

    <div className="sidebar-footer">
      <div className="avatar">LM</div>
      <div style={{ flex: 1 }}>
        <div className="name">Léa Mercier</div>
        <div className="role">RSSI · Sécurité</div>
      </div>
    </div>
  </aside>
);

// ---------- Top bar ----------
const TopBar = ({ onIndexOpen }) => (
  <div className="topbar">
    <div className="search">
      <Icon name="search" size={14} />
      <input placeholder="Rechercher agents, événements, policies…" />
      <kbd>⌘K</kbd>
    </div>
    <div style={{ flex: 1 }} />
    {onIndexOpen && (
      <button className="screen-index-trigger" onClick={onIndexOpen} title="Index des écrans">
        <Icon name="layoutDashboard" size={12} />
        Écrans
        <kbd>⇧⌘P</kbd>
      </button>
    )}
    <SovBadge />
    <button className="icon-btn" aria-label="Notifications">
      <Icon name="bell" size={18} />
      <span className="badge"></span>
    </button>
    <div className="avatar">LM</div>
  </div>
);

// ---------- Page header ----------
const PageHeader = ({ eyebrow, title, lead, actions }) => (
  <div className="page-header">
    <div>
      {eyebrow && <div className="eyebrow">{eyebrow}</div>}
      <h1>{title}</h1>
      {lead && <p className="lead">{lead}</p>}
    </div>
    {actions && <div className="row" style={{ gap: 8 }}>{actions}</div>}
  </div>
);

// ---------- Metric card ----------
const MetricCard = ({ label, value, unit, sub, trend, variant }) => (
  <div className={`card ${variant === 'dark' ? 'dark' : ''} ${variant === 'gold' ? 'gold-frame' : ''}`}>
    <span className="label">{label}</span>
    <div className="metric">
      <div className="value">
        {value}{unit && <span className="unit">{unit}</span>}
      </div>
      {trend && (
        <div className={`trend ${trend.dir}`}>
          <Icon name={trend.dir === 'up' ? 'trendingUp' : 'trendingDown'} size={11} />
          {trend.label}
        </div>
      )}
      {sub && <div className="sub">{sub}</div>}
    </div>
  </div>
);

// expose
Object.assign(window, {
  Icon, ProviderMarkHF, ActivityRingsHF, SparkHF,
  SovBadge, Sidebar, TopBar, PageHeader, MetricCard,
});
