// Reusable bits + service icons
const sfT = (lang, en, zh) => lang === 'en' ? en : zh;

// Service icon set (Lucide-style, 1.5 stroke, currentColor)
const SF_ICONS = {
  cabling: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M2 7h20M2 12h20M2 17h20"/><circle cx="6" cy="7" r="1.2" fill="currentColor"/><circle cx="12" cy="12" r="1.2" fill="currentColor"/><circle cx="18" cy="17" r="1.2" fill="currentColor"/></svg>,
  fiber: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M3 3l18 18M3 12c4-3 8-3 12 0s8 3 12 0" transform="translate(-3,0)"/><path d="M3 18c3-2 6-2 9 0"/></svg>,
  wifi: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M5 12.55a11 11 0 0 1 14.08 0"/><path d="M1.42 9a16 16 0 0 1 21.16 0"/><path d="M8.53 16.11a6 6 0 0 1 6.95 0"/><circle cx="12" cy="20" r="1" fill="currentColor"/></svg>,
  iptel: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><rect x="5" y="2" width="14" height="20" rx="2"/><line x1="12" y1="18" x2="12.01" y2="18"/><path d="M9 6h6"/></svg>,
  cctv: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M2 4h13l3 6H5l-3-6z"/><line x1="11" y1="10" x2="11" y2="14"/><path d="M5 14h12"/><path d="M5 14v3a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2v-3"/></svg>,
  access: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/><circle cx="12" cy="16" r="1.4" fill="currentColor"/></svg>,
  iot: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="3"/><path d="M19 5l-2 2M7 17l-2 2M19 19l-2-2M7 7L5 5M22 12h-3M5 12H2M12 5V2M12 22v-3"/></svg>,
  serverroom: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="3" width="18" height="6" rx="1"/><rect x="3" y="11" width="18" height="6" rx="1"/><rect x="3" y="19" width="18" height="2" rx="1"/><line x1="6" y1="6" x2="6.01" y2="6"/><line x1="6" y1="14" x2="6.01" y2="14"/></svg>,
  fault: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M12 2v6l4-2M12 22v-6l-4 2"/><path d="M3 12h6l-2-4M21 12h-6l2 4"/><circle cx="12" cy="12" r="3"/></svg>,
  hypervisor: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/></svg>,
  hci: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M12 2L4 6v6c0 5 3.5 8.5 8 10 4.5-1.5 8-5 8-10V6l-8-4z"/><path d="M8 10l3 3 5-5"/></svg>,
  cyber: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/><path d="M9 12l2 2 4-4"/></svg>,
  soc: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><circle cx="11" cy="11" r="7"/><line x1="16" y1="16" x2="22" y2="22"/><circle cx="11" cy="11" r="3"/></svg>,
  sraa: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M9 11l3 3 8-8"/><path d="M21 12v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h11"/></svg>,
  managed: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M9 9h6v6H9z"/><path d="M9 1v3M15 1v3M9 20v3M15 20v3M1 9h3M1 15h3M20 9h3M20 15h3"/></svg>,
  erp: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M3 3h18v4H3zM3 10h18v4H3zM3 17h18v4H3z"/><circle cx="6" cy="5" r=".8" fill="currentColor"/><circle cx="6" cy="12" r=".8" fill="currentColor"/><circle cx="6" cy="19" r=".8" fill="currentColor"/></svg>,
  web: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><rect x="2" y="3" width="20" height="14" rx="2"/><line x1="2" y1="8" x2="22" y2="8"/><circle cx="5" cy="5.5" r=".4" fill="currentColor"/><circle cx="7" cy="5.5" r=".4" fill="currentColor"/></svg>,
  app: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><rect x="6" y="2" width="12" height="20" rx="2"/><line x1="12" y1="18" x2="12.01" y2="18"/></svg>,
  chatbot: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="5" width="18" height="13" rx="2"/><path d="M7 18l-2 3v-3M9 11h.01M15 11h.01M9 14c1 1 4 1 6 0"/></svg>,
  localllm: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="3"/><circle cx="12" cy="3" r="1.5"/><circle cx="12" cy="21" r="1.5"/><circle cx="3" cy="12" r="1.5"/><circle cx="21" cy="12" r="1.5"/><path d="M12 6v3M12 15v3M6 12h3M15 12h3"/></svg>,
  workflow: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="3" width="6" height="6"/><rect x="15" y="3" width="6" height="6"/><rect x="9" y="15" width="6" height="6"/><path d="M6 9v3a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V9"/></svg>,
};

// ── Shared animated particle-network canvas ──────────────────────────────────
// Drop <SFNetworkCanvas> as the first child of any position:relative section.
// The canvas is position:absolute, inset:0, pointer-events:none so it never
// blocks clicks. Give sibling content position:relative; zIndex:1 to float above it.
//
// Props:
//   accent  — hub-node / edge-highlight color   (default: '#E36918')
//   opacity — canvas element opacity            (default: 0.15)
//   inverse — true on dark/navy sections → uses light node colour
const SFNetworkCanvas = ({ accent = '#E36918', opacity = 0.5, inverse = false }) => {
  const canvasRef = React.useRef(null);
  const frameRef  = React.useRef(null);
  const nodesRef  = React.useRef(null);

  React.useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext('2d');
    let W = 0, H = 0;

    const LABELS = [
      'CORE-SW','EDGE-01','EDGE-02','NGFW','AP-1F','AP-2F','AP-3F',
      'NVR','SRV-01','SRV-02','UPS','PDU','VPN','SIEM','EDR',
      'CAM-01','CAM-02','PBX','VLAN10','VLAN20','BGP','OSPF',
      'RADIUS','LDAP','DNS','NTP','SNMP','LLDP','QoS','PoE',
    ];

    const CONNECT_DIST = 170;
    const SPEED = 0.26;
    const NODE_COUNT = 38;

    const makeNode = (i) => ({
      x: Math.random() * W,
      y: Math.random() * H,
      vx: (Math.random() - 0.5) * SPEED,
      vy: (Math.random() - 0.5) * SPEED,
      r:  Math.random() < 0.16 ? 3.8 : 2,
      label: Math.random() < 0.3 ? LABELS[i % LABELS.length] : null,
    });

    const resize = () => {
      W = canvas.offsetWidth;
      H = canvas.offsetHeight;
      if (!W || !H) return;
      canvas.width  = W * devicePixelRatio;
      canvas.height = H * devicePixelRatio;
      ctx.scale(devicePixelRatio, devicePixelRatio);
      if (!nodesRef.current) {
        nodesRef.current = Array.from({ length: NODE_COUNT }, (_, i) => makeNode(i));
      } else {
        // Keep existing nodes; clamp positions
        for (const n of nodesRef.current) {
          n.x = Math.min(n.x, W);
          n.y = Math.min(n.y, H);
        }
      }
    };

    const nodeColor  = inverse ? 'rgba(255,255,255,0.55)' : (() => {
      const s = getComputedStyle(document.documentElement);
      return s.getPropertyValue('--fg-muted').trim() || '#56627A';
    })();

    const draw = () => {
      ctx.clearRect(0, 0, W, H);
      const nodes = nodesRef.current;
      if (!nodes) { frameRef.current = requestAnimationFrame(draw); return; }

      for (const n of nodes) {
        n.x += n.vx; n.y += n.vy;
        if (n.x < 0 || n.x > W) { n.vx *= -1; n.x = Math.max(0, Math.min(W, n.x)); }
        if (n.y < 0 || n.y > H) { n.vy *= -1; n.y = Math.max(0, Math.min(H, n.y)); }
      }

      // Edges
      for (let i = 0; i < nodes.length; i++) {
        for (let j = i + 1; j < nodes.length; j++) {
          const dx = nodes[i].x - nodes[j].x;
          const dy = nodes[i].y - nodes[j].y;
          const d  = Math.sqrt(dx*dx + dy*dy);
          if (d < CONNECT_DIST) {
            ctx.beginPath();
            ctx.moveTo(nodes[i].x, nodes[i].y);
            ctx.lineTo(nodes[j].x, nodes[j].y);
            ctx.strokeStyle = nodeColor;
            ctx.globalAlpha = (1 - d / CONNECT_DIST) * 0.55;
            ctx.lineWidth = 0.65;
            ctx.stroke();
          }
        }
      }

      // Nodes + labels
      for (const n of nodes) {
        const isHub = n.r > 2.5;
        ctx.beginPath();
        ctx.arc(n.x, n.y, n.r, 0, Math.PI * 2);
        ctx.fillStyle = isHub ? accent : nodeColor;
        ctx.globalAlpha = isHub ? 0.75 : 0.45;
        ctx.fill();

        if (isHub) {
          ctx.beginPath();
          ctx.arc(n.x, n.y, n.r + 4, 0, Math.PI * 2);
          ctx.strokeStyle = accent;
          ctx.globalAlpha = 0.22;
          ctx.lineWidth = 0.9;
          ctx.stroke();
        }

        if (n.label) {
          ctx.font = '500 8.5px "JetBrains Mono", monospace';
          ctx.fillStyle = nodeColor;
          ctx.globalAlpha = 0.5;
          ctx.fillText(n.label, n.x + n.r + 4, n.y + 3);
        }
      }

      ctx.globalAlpha = 1;
      frameRef.current = requestAnimationFrame(draw);
    };

    const ro = new ResizeObserver(resize);
    ro.observe(canvas);
    resize();

    const io = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) { frameRef.current = requestAnimationFrame(draw); }
      else { cancelAnimationFrame(frameRef.current); }
    });
    io.observe(canvas);

    return () => {
      cancelAnimationFrame(frameRef.current);
      ro.disconnect();
      io.disconnect();
    };
  }, [accent, inverse]);

  return (
    <canvas ref={canvasRef} style={{
      position:'absolute', inset:0,
      width:'100%', height:'100%',
      opacity, pointerEvents:'none', display:'block',
    }}/>
  );
};

// Inline SVG logo — auto-adapts to dark/light mode via data-theme attribute
const SFLogo = ({ height = 40 }) => {
  const uid = React.useId().replace(/[^a-z0-9]/gi, '');
  const gid = 'sfg' + uid;

  const [dark, setDark] = React.useState(
    () => document.documentElement.dataset.theme === 'dark'
  );
  React.useEffect(() => {
    const mo = new MutationObserver(() =>
      setDark(document.documentElement.dataset.theme === 'dark')
    );
    mo.observe(document.documentElement, { attributes: true, attributeFilter: ['data-theme'] });
    return () => mo.disconnect();
  }, []);

  const navy  = dark ? '#FFFFFF'              : '#0F2F54';
  const slate = dark ? 'rgba(255,255,255,0.7)' : '#1B3A65';

  return (
    <svg viewBox="0 0 320 130" height={height}
      style={{ display:'block', overflow:'visible' }}
      role="img" aria-label="Sun Forest Limited">
      <defs>
        <linearGradient id={gid} gradientUnits="userSpaceOnUse"
          x1="108" y1="65" x2="260" y2="58">
          <stop offset="0%"   stopColor="#FAB332"/>
          <stop offset="100%" stopColor="#D04E08"/>
        </linearGradient>
      </defs>
      {/* Swoosh — tapered arc, points at both ends */}
      <path d="M 108 65 C 138 28 206 14 260 58 C 208 34 148 44 108 65 Z"
        fill={`url(#${gid})`}/>
      {/* SUN FOREST */}
      <text x="160" y="100" textAnchor="middle"
        fontFamily="'Montserrat','Inter',sans-serif"
        fontWeight="900" fontSize="52" letterSpacing="2" fill={navy}>
        SUN FOREST
      </text>
      {/* LIMITED */}
      <text x="160" y="122" textAnchor="middle"
        fontFamily="'Montserrat','Inter',sans-serif"
        fontWeight="500" fontSize="16" letterSpacing="9" fill={slate}>
        LIMITED
      </text>
    </svg>
  );
};

window.sfT = sfT;
window.SF_ICONS = SF_ICONS;
window.SFNetworkCanvas = SFNetworkCanvas;
window.SFLogo = SFLogo;
