﻿/* ============================================================
   SAYRU â€” noc.jsx
   Command-center graphic compositions (hero panel, radar, topology).
   Pure CSS/SVG, in-brand. Exported to window.
   ============================================================ */

/* A smooth monitoring line, reused for stroke + moving glow dot */
const NOC_PATH = "M0 128 C 38 120 66 70 104 80 S 168 138 210 102 S 286 44 332 70 S 416 128 470 84 S 548 36 600 66";

function Sparkline({ points, color = 'var(--cyan)', w = 120, h = 30 }) {
  const max = Math.max(...points), min = Math.min(...points);
  const norm = points.map((p, i) => {
    const x = (i / (points.length - 1)) * w;
    const y = h - ((p - min) / (max - min || 1)) * (h - 4) - 2;
    return `${x.toFixed(1)},${y.toFixed(1)}`;
  }).join(' ');
  return (
    <svg className="spark" width={w} height={h} viewBox={`0 0 ${w} ${h}`} preserveAspectRatio="none" aria-hidden="true">
      <polyline points={norm} fill="none" stroke={color} strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" />
    </svg>
  );
}

function Radar({ size = 92 }) {
  return (
    <div className="radar-eye" style={{ width: size, height: size }} aria-hidden="true">
      <span className="radar-eye__ring r1"></span>
      <span className="radar-eye__ring r2"></span>
      <span className="radar-eye__ring r3"></span>
      <span className="radar-eye__sweep"></span>
      <span className="radar-eye__core"></span>
    </div>
  );
}

/* mini network topology */
function Topology() {
  const nodes = [
    { x: 30, y: 46, s: 'ok' }, { x: 110, y: 22, s: 'ok' }, { x: 110, y: 70, s: 'ok' },
    { x: 200, y: 30, s: 'warn' }, { x: 200, y: 64, s: 'ok' }, { x: 285, y: 46, s: 'ok' },
  ];
  const links = [[0,1],[0,2],[1,3],[2,4],[3,5],[4,5],[1,4]];
  return (
    <svg className="topo" viewBox="0 0 315 92" aria-hidden="true">
      {links.map(([a,b], i) => (
        <line key={i} x1={nodes[a].x} y1={nodes[a].y} x2={nodes[b].x} y2={nodes[b].y}
          stroke="rgba(91,216,248,.32)" strokeWidth="1" />
      ))}
      {nodes.map((n, i) => (
        <g key={i} className={'topo__n topo__n--' + n.s} style={{ animationDelay: (i * 0.4) + 's' }}>
          <circle cx={n.x} cy={n.y} r="8" className="topo__halo" />
          <circle cx={n.x} cy={n.y} r="4" className="topo__dot" />
        </g>
      ))}
    </svg>
  );
}

/* Service-aware hero NOC dashboard composition */
const HERO_PANEL_SERVICE = {
  s1: { tone: 'operations' },
  s2: { tone: 'itsm' },
  s3: { tone: 'monitoring' },
  s4: { tone: 'siem' },
  s5: { tone: 'audit' },
};

function heroPanelValue(t, slide, key, fallback) {
  const fullKey = 'hero.panel.' + slide + '.' + key;
  const value = t(fullKey);
  return value === fullKey ? fallback : value;
}

function heroPanelPoints(slide) {
  const sets = {
    s1: [[5, 7, 9, 7, 10, 12, 10, 13, 15, 13], [8, 7, 7, 6, 7, 5, 5, 4, 5, 4]],
    s2: [[3, 5, 8, 7, 9, 10, 11, 12, 13, 15], [7, 6, 5, 5, 4, 4, 3, 3, 2, 2]],
    s3: [[4, 5, 5, 6, 5, 7, 7, 8, 8, 9], [8, 7, 6, 7, 5, 4, 5, 3, 4, 3]],
    s4: [[2, 4, 7, 6, 9, 12, 11, 14, 13, 16], [4, 4, 5, 5, 6, 5, 6, 7, 8, 9]],
    s5: [[6, 7, 8, 8, 9, 10, 10, 11, 12, 12], [9, 8, 7, 7, 6, 5, 5, 4, 3, 3]],
  };
  return sets[slide] || sets.s1;
}

function NocComposition({ slide = 's1' }) {
  const { t } = useT();
  const svc = HERO_PANEL_SERVICE[slide] || HERO_PANEL_SERVICE.s1;
  const lines = heroPanelPoints(slide);
  const title = heroPanelValue(t, slide, 'title', 'sayru://operations-center');
  const status = heroPanelValue(t, slide, 'status', t('hero.live'));
  const metricLabel = heroPanelValue(t, slide, 'metric.label', 'NETWORK THROUGHPUT');
  const metricValue = heroPanelValue(t, slide, 'metric.value', '2.84');
  const metricUnit = heroPanelValue(t, slide, 'metric.unit', 'Gbps');
  const side1Label = heroPanelValue(t, slide, 'side1.label', 'UPTIME');
  const side1Value = heroPanelValue(t, slide, 'side1.value', '99.98');
  const side1Unit = heroPanelValue(t, slide, 'side1.unit', '%');
  const side2Label = heroPanelValue(t, slide, 'side2.label', 'LATENCY');
  const side2Value = heroPanelValue(t, slide, 'side2.value', '42');
  const side2Unit = heroPanelValue(t, slide, 'side2.unit', 'ms');
  const topology = heroPanelValue(t, slide, 'topology', 'TOPOLOGY - 6 NODES');
  const radarLabel = heroPanelValue(t, slide, 'radar.label', 'SCAN');
  const radarValue = heroPanelValue(t, slide, 'radar.value', 'ACTIVE');
  const alertLabel = heroPanelValue(t, slide, 'alert.label', 'ALERTS');
  const alertValue = heroPanelValue(t, slide, 'alert.value', '0 critical');
  return (
    <div className={'noc noc--' + svc.tone} role="img" aria-label="SAYRU operations dashboard">
      <div className="noc__bar">
        <div className="noc__tabs">
          <span className="noc__dot"></span><span className="noc__dot"></span><span className="noc__dot"></span>
          <span className="noc__title mono">{title}</span>
        </div>
        <span className="pill"><span className="dot"></span>{status}</span>
      </div>

      <div className="noc__body">
        <div className="noc__main">
          <div className="noc__main-head">
            <div>
              <div className="noc__label mono">{metricLabel}</div>
              <div className="noc__big mono">{metricValue}<span>{metricUnit}</span></div>
            </div>
            <div className="noc__legend">
              <span className="mono"><i className="lg lg--cy"></i>inbound</span>
              <span className="mono"><i className="lg lg--bl"></i>outbound</span>
            </div>
          </div>
          <div className="noc__chart">
            <div className="cc-grid noc__chartgrid"></div>
            <svg viewBox="0 0 600 160" preserveAspectRatio="none" className="noc__svg">
              <defs>
                <linearGradient id="fillg" x1="0" y1="0" x2="0" y2="1">
                  <stop offset="0" stopColor="rgba(24,197,244,.34)" />
                  <stop offset="1" stopColor="rgba(24,197,244,0)" />
                </linearGradient>
              </defs>
              <path d={NOC_PATH + ' L600 160 L0 160 Z'} fill="url(#fillg)" />
              <path d={NOC_PATH} fill="none" stroke="var(--cyan)" strokeWidth="2.2" strokeLinecap="round" className="noc__line" />
              <path d="M0 140 C 60 132 120 150 200 130 S 360 96 470 120 S 560 100 600 110"
                fill="none" stroke="rgba(14,77,164,.7)" strokeWidth="1.8" strokeDasharray="4 5" />
            </svg>
            <span className="noc__cursor"></span>
          </div>
          <div className="noc__topo-wrap">
            <div className="noc__label mono">{topology}</div>
            <Topology />
          </div>
        </div>

        <div className="noc__side">
          <div className="noc__stat">
            <div className="noc__stat-top"><span className="mono noc__label">{side1Label}</span><span className="noc__delta up">▲</span></div>
            <div className="noc__stat-v mono">{side1Value}<span>{side1Unit}</span></div>
            <Sparkline points={lines[0]} />
          </div>
          <div className="noc__stat">
            <div className="noc__stat-top"><span className="mono noc__label">{side2Label}</span><span className="noc__delta dn">▼</span></div>
            <div className="noc__stat-v mono">{side2Value}<span>{side2Unit}</span></div>
            <Sparkline points={lines[1]} color="var(--blue)" />
          </div>
          <div className="noc__radar">
            <Radar size={86} />
            <div className="noc__radar-meta">
              <div className="mono noc__label">{radarLabel}</div>
              <div className="noc__radar-v mono">{radarValue}</div>
            </div>
          </div>
          <div className="noc__alerts">
            <span className="mono noc__label">{alertLabel}</span>
            <span className="noc__alerts-v">{alertValue}</span>
          </div>
        </div>
      </div>
    </div>
  );
}

/* ---------------- Hero "service constellation" composition ---------------- */
const CONST_NODES = [
  { id: 'yon', x: 64, y: 11 },
  { id: 'goz', x: 11, y: 40 },
  { id: 'iz',  x: 27, y: 89 },
  { id: 'dem', x: 90, y: 67 },
];
function HeroConstellation() {
  const { t } = useT();
  const shortName = (id) => (t('svc.' + id + '.name') || '').replace(/^Sayru[\-\u2011]?/i, '').toLocaleUpperCase('tr');
  return (
    <div className="hconst" role="img" aria-label="SAYRU hizmet takÄ±myÄ±ldÄ±zÄ±">
      <div className="cc-grid hconst__grid"></div>
      <svg className="hconst__lines" viewBox="0 0 100 100" preserveAspectRatio="none" aria-hidden="true">
        {CONST_NODES.map((n, i) => (
          <line key={n.id} x1="50" y1="50" x2={n.x} y2={n.y} className="hconst__line" style={{ animationDelay: (i * 0.5) + 's' }} />
        ))}
      </svg>
      <div className="hconst__core">
        <span className="hconst__ring r1"></span>
        <span className="hconst__ring r2"></span>
        <span className="hconst__sweep"></span>
        <span className="hconst__emblem"><Icon name="goz" size={34} /></span>
      </div>
      {CONST_NODES.map((n, i) => (
        <div key={n.id} className="hconst__node" style={{ left: n.x + '%', top: n.y + '%', animationDelay: (i * 0.6) + 's' }}>
          <span className="hconst__node-ic"><Icon name={n.id} size={22} /></span>
          <div className="hconst__node-body">
            <span className="hconst__node-name">{shortName(n.id)}</span>
            <span className="hconst__node-desc">{t('svc.' + n.id + '.tag')}</span>
          </div>
        </div>
      ))}
    </div>
  );
}

/* switcher used by the hero â€” reads the live CMS setting, re-renders on live update */
function HeroVisual({ slide = 's1' }) {
  const [, tick] = React.useState(0);
  React.useEffect(() => {
    const h = () => tick(t => t + 1);
    window.addEventListener('sayru-live-update', h);
    return () => window.removeEventListener('sayru-live-update', h);
  }, []);
  const style = (window.__SAYRU_SETTINGS && window.__SAYRU_SETTINGS.heroVisual) || 'none';
  if (style === 'constellation') return <HeroConstellation />;
  if (style === 'noc') return <NocComposition slide={slide} />;
  return null;
}

Object.assign(window, { NocComposition, HeroConstellation, HeroVisual, Radar, Topology, Sparkline, NOC_PATH });
