// guardCity shared — paleta DirectLuz-aligned (azul royal + noite), módulos, cena cinematográfica.
const GC = {
  ink: '#070809',         // base mais profunda
  midnight: '#0C0D0F',    // hero bg
  navy: '#131517',        // panels
  steel: '#23262B',       // borders
  iron: '#2F3339',        // emphasis-low
  fog: '#7A828B',         // muted
  cloud: '#D8DCE0',       // body
  bone: '#F2F4F6',        // bright UI
  white: '#FFFFFF',
  // Acentos = monocromáticos (white-driven)
  blue: '#FFFFFF',        // (alias) acento principal = branco puro
  blueLight: '#F2F4F6',   // (alias) soft accent
  blueGlow: '#FFFFFF',    // (alias) glow accent
  amber: '#D8DCE0',       // (alias) "luz" = cinza claro neutro, sem cor
};

const GC_MODULES = [
  { key: 'viewguard', name: 'ViewGuard', role: 'VMS · Vídeo', pitch: 'Vídeo gerenciado de ponta a ponta. Multi-stream, multi-câmera, multi-cidade.', icon: 'assets/viewguard-icon.svg', accent: '#10b981' },
  { key: 'faceguard', name: 'FaceGuard', role: 'IA · Reconhecimento', pitch: 'Reconhecimento facial em tempo real, com cadeia de custódia e governança LGPD.', icon: 'assets/faceguard-aperture-icon.png', accent: '#10b981' },
  { key: 'cityguard', name: 'CityGuard', role: 'OMS · Operações', pitch: 'Despacho, patrulhamento e gestão de incidentes integrados ao VMS.', icon: 'assets/cityguard-icon.svg', accent: '#f59e0b' },
  { key: 'directluz', name: 'DirectLuz', role: 'Iluminação Pública', pitch: 'Telegestão de iluminação pública. Postes, luminárias, ordens de serviço e equipes de campo.', icon: 'assets/directluz-icon.png', accent: '#4169e8' },
];

// Cena cinematográfica: skyline → postes → luz/câmeras → feixes → nodes → logo guardCity.
// 6 atos sincronizados ao scroll progress 0→1.
function CityScene({ progress }) {
  const p = Math.max(0, Math.min(1, progress));
  const seg = (a, b) => Math.max(0, Math.min(1, (p - a) / (b - a)));
  const ease = t => t < .5 ? 2*t*t : 1 - Math.pow(-2*t+2, 2)/2;
  const easeOut = t => 1 - Math.pow(1 - t, 3);
  const easeBack = t => {
    const c1 = 1.70158, c3 = c1 + 1;
    return 1 + c3 * Math.pow(t - 1, 3) + c1 * Math.pow(t - 1, 2);
  };

  // Atos
  const skyline = ease(seg(0.00, 0.16));     // 0-16%
  const poles   = ease(seg(0.10, 0.32));     // 10-32%
  const lights  = ease(seg(0.28, 0.50));     // 28-50%
  const cams    = ease(seg(0.42, 0.60));     // 42-60%
  const beams   = ease(seg(0.52, 0.74));     // 52-74%
  // Daylight: cresce conforme luzes acendem; postes acendem BRANCO sobre cinza-noite
  const daylight = ease(seg(0.30, 0.78));    // 30-78%: cinza-noite → cinza-dia
  // Final ato: cena dissolve TOTAL + logo blades montam
  const sceneFade = ease(seg(0.70, 0.88));   // cena fade-out 70-88%
  const logoIn    = ease(seg(0.74, 1.00));   // blades fly-in 74-100% (mais tempo p/ montar)
  const sceneOpacity = 1 - sceneFade;        // some por inteiro
  const sceneScale = 1 - sceneFade * 0.12;
  const logoOpacity = logoIn;
  const logoScale = 0.6 + easeOut(logoIn) * 0.45;
  // Final morph: blades fade out as real PNG logo takes over (handled by parent)
  const bladesFade = ease(seg(0.90, 0.98)); // blades fade out as crisp PNG takes over

  // Lerp helper for color interpolation
  const lerpHex = (a, b, t) => {
    const pa = [parseInt(a.slice(1,3),16), parseInt(a.slice(3,5),16), parseInt(a.slice(5,7),16)];
    const pb = [parseInt(b.slice(1,3),16), parseInt(b.slice(3,5),16), parseInt(b.slice(5,7),16)];
    const r = Math.round(pa[0] + (pb[0]-pa[0])*t);
    const g = Math.round(pa[1] + (pb[1]-pa[1])*t);
    const bl = Math.round(pa[2] + (pb[2]-pa[2])*t);
    return `rgb(${r},${g},${bl})`;
  };
  // Day/night palette — STRICT GREYSCALE: noite cinza-escuro → "dia" cinza claro neutro
  const skyTop    = lerpHex('#0A0B0D', '#C8CCD0', daylight);
  const skyMid    = lerpHex('#101216', '#D8DCE0', daylight);
  const skyBottom = lerpHex('#0E1014', '#E8EBEE', daylight);
  const bldgTop   = lerpHex('#1A1D22', '#8A8E94', daylight);
  const bldgBot   = lerpHex('#0A0C10', '#6E7278', daylight);
  const groundCol = lerpHex('#06080A', '#B8BCC0', daylight);
  const lineCol   = lerpHex('#23262B', '#9DA1A6', daylight);
  // Stars and window lights fade out as day rises
  const nightAlpha = 1 - daylight;

  // Building skyline data (deterministic). [x, width, height]
  const buildings = [
    [40, 60, 220], [105, 45, 180], [155, 80, 280], [240, 55, 160],
    [300, 70, 240], [375, 90, 320], [470, 50, 200], [525, 65, 260],
    [595, 75, 300], [675, 55, 220], [735, 70, 280], [810, 60, 240],
    [875, 95, 360], [975, 50, 200], [1030, 70, 260], [1105, 60, 220],
  ];

  // Light pole positions along ground (x positions)
  const polePositions = [180, 320, 460, 600, 740, 880, 1020];

  return (
    <div style={{ width: '100%', height: '100%', position: 'relative', overflow: 'hidden', background: GC.ink }}>
    <svg viewBox="0 0 1200 700" preserveAspectRatio="xMidYMid slice" style={{ width: '100%', height: '100%', display: 'block', transform: `scale(${sceneScale})`, transformOrigin: '50% 55%', transition: 'none' }}>
      <defs>
        <linearGradient id="gc_sky" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0" stopColor={skyTop} />
          <stop offset="0.6" stopColor={skyMid} />
          <stop offset="1" stopColor={skyBottom} />
        </linearGradient>
        <linearGradient id="gc_bldg" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0" stopColor={bldgTop} />
          <stop offset="1" stopColor={bldgBot} />
        </linearGradient>
        <radialGradient id="gc_lampglow" cx="0.5" cy="0.5" r="0.5">
          <stop offset="0" stopColor="#FFFFFF" stopOpacity="0.7" />
          <stop offset="0.4" stopColor="#FFFFFF" stopOpacity="0.18" />
          <stop offset="1" stopColor="#FFFFFF" stopOpacity="0" />
        </radialGradient>
        <radialGradient id="gc_bluepulse" cx="0.5" cy="0.5" r="0.5">
          <stop offset="0" stopColor="#FFFFFF" stopOpacity="0.9" />
          <stop offset="0.5" stopColor="#FFFFFF" stopOpacity="0.18" />
          <stop offset="1" stopColor="#FFFFFF" stopOpacity="0" />
        </radialGradient>
        <linearGradient id="gc_beam" x1="0" y1="1" x2="0" y2="0">
          <stop offset="0" stopColor="#FFFFFF" stopOpacity="0.85" />
          <stop offset="1" stopColor="#FFFFFF" stopOpacity="0" />
        </linearGradient>
        {/* Blade gradients (matching brand SVG: light grey → darker grey) */}
        <linearGradient id="gc_blade_a" x1="0" y1="0.5" x2="1" y2="0.5">
          <stop offset="0" stopColor="#E8EAEC" />
          <stop offset="1" stopColor="#9DA1A6" />
        </linearGradient>
        <linearGradient id="gc_blade_b" x1="0" y1="0.5" x2="1" y2="0.5">
          <stop offset="0" stopColor="#C7CACE" />
          <stop offset="1" stopColor="#7F8388" />
        </linearGradient>
        <linearGradient id="gc_blade_c" x1="0" y1="0.5" x2="1" y2="0.5">
          <stop offset="0" stopColor="#D8DCE0" />
          <stop offset="1" stopColor="#8E9297" />
        </linearGradient>
        <linearGradient id="gc_blade_d" x1="0" y1="0.5" x2="1" y2="0.5">
          <stop offset="0" stopColor="#F2F4F6" />
          <stop offset="1" stopColor="#A8ACB1" />
        </linearGradient>
        <filter id="gc_blur" x="-50%" y="-50%" width="200%" height="200%">
          <feGaussianBlur stdDeviation="3" />
        </filter>
      </defs>

      <g opacity={sceneOpacity}>
      {/* Sky */}
      <rect x="0" y="0" width="1200" height="700" fill="url(#gc_sky)" />

      {/* Stars (subtle, fade in early; fade out with daylight) */}
      <g opacity={skyline * 0.7 * nightAlpha}>
        {[[80,60],[230,90],[440,40],[610,75],[820,55],[990,85],[1140,50],[180,120],[520,110],[760,100],[1080,130]].map(([x,y], i) => (
          <circle key={i} cx={x} cy={y} r="0.8" fill={GC.cloud} opacity="0.6" />
        ))}
      </g>

      {/* ACT 1 — Skyline. Buildings draw in (reveal mask via height growing). */}
      <g>
        {buildings.map(([x, w, h], i) => {
          const stagger = ease(Math.max(0, Math.min(1, skyline * 1.6 - i * 0.04)));
          const drawH = h * stagger;
          return (
            <g key={i}>
              <rect x={x} y={520 - drawH} width={w} height={drawH} fill="url(#gc_bldg)" opacity={stagger} />
              {/* Outline edge */}
              <line x1={x} y1={520 - drawH} x2={x + w} y2={520 - drawH} stroke={GC.steel} strokeWidth="0.5" opacity={stagger * 0.6} />
              <line x1={x + w} y1={520 - drawH} x2={x + w} y2={520} stroke={GC.steel} strokeWidth="0.5" opacity={stagger * 0.4} />
              {/* Random windows */}
              {stagger > 0.5 && [...Array(Math.floor(h / 22))].map((_, j) => {
                const litRow = ((i * 7 + j * 13) % 100) / 100;
                const litStagger = ease(Math.max(0, Math.min(1, (skyline - 0.4) * 2.5 - j * 0.05)));
                if (litRow > 0.6) return null;
                return (
                  <rect
                    key={j}
                    x={x + 4 + ((j * 9) % (w - 12))}
                    y={520 - drawH + 8 + j * 22}
                    width="3" height="3"
                    fill={GC.amber}
                    opacity={litStagger * 0.7 * nightAlpha}
                  />
                );
              })}
            </g>
          );
        })}
      </g>

      {/* Ground */}
      <rect x="0" y="520" width="1200" height="180" fill={groundCol} opacity={skyline} />
      {/* Ground horizon line */}
      <line x1="0" y1="520" x2="1200" y2="520" stroke={lineCol} strokeWidth="1" opacity={skyline * 0.6} />
      {/* Subtle ground texture */}
      <g opacity={skyline * 0.4}>
        {[540, 570, 600, 630, 660].map((y, i) => (
          <line key={i} x1="0" y1={y} x2="1200" y2={y} stroke={GC.steel} strokeWidth="0.4" strokeDasharray="2 6" />
        ))}
      </g>

      {/* ACT 2 — Light poles grow from ground */}
      {polePositions.map((px, i) => {
        const stagger = ease(Math.max(0, Math.min(1, poles * 1.4 - i * 0.08)));
        const POLE_H = 200;
        const drawH = POLE_H * stagger;
        const lightOn = ease(Math.max(0, Math.min(1, lights * 1.3 - i * 0.07)));
        const camOn = easeBack(Math.max(0, Math.min(1, cams * 1.4 - i * 0.06)));

        return (
          <g key={`pole-${i}`} transform={`translate(${px}, 520)`}>
            {/* Base */}
            {stagger > 0 && <rect x="-6" y="-4" width="12" height="6" fill={GC.iron} opacity={stagger} />}
            {/* Pole */}
            <rect x="-1.5" y={-drawH} width="3" height={drawH} fill={GC.iron} />

            {stagger > 0.95 && (
              <g transform={`translate(0, ${-POLE_H})`}>
                {/* Arm */}
                <path d={`M 0 4 Q 30 -4 50 -4`} stroke={GC.iron} strokeWidth="2.5" fill="none" strokeLinecap="round" />

                {/* Lamp head */}
                <g transform="translate(50, -4)">
                  {/* Glow halo */}
                  {lightOn > 0 && (
                    <circle cx="0" cy="6" r={48 * lightOn} fill="url(#gc_lampglow)" />
                  )}
                  <rect x="-12" y="-3" width="24" height="8" rx="2" fill="#1A1D22" stroke={GC.iron} strokeWidth="0.8" />
                  <rect x="-9" y="-1" width="18" height="3" fill={GC.amber} opacity={lightOn * 0.95} />
                  {/* Light cone projected down */}
                  {lightOn > 0.5 && (
                    <path
                      d={`M -10 5 L ${-30 - 25*lightOn} ${60 + 40*lightOn} L ${30 + 25*lightOn} ${60 + 40*lightOn} L 10 5 Z`}
                      fill={GC.amber}
                      opacity={(lightOn - 0.5) * 0.12}
                    />
                  )}
                </g>

                {/* Camera mounted on pole — appears after lamp */}
                {camOn > 0 && (
                  <g transform={`translate(-2, 18) scale(${0.6 + 0.4 * Math.min(1, camOn)})`}>
                    <rect x="-3" y="-7" width="6" height="14" fill={GC.iron} />
                    <rect x="-14" y="-12" width="22" height="10" rx="1.5" fill="#1A1D22" stroke={GC.fog} strokeWidth="0.5" />
                    <rect x="6" y="-9" width="6" height="4" rx="1" fill={GC.ink} stroke={GC.fog} strokeWidth="0.4" />
                    {/* Cam status LED */}
                    <circle cx="9" cy="-7" r="1" fill={GC.blueGlow} opacity={Math.min(1, camOn * 1.5)}>
                      <animate attributeName="opacity" values="1;0.4;1" dur="2s" repeatCount="indefinite" />
                    </circle>
                  </g>
                )}
              </g>
            )}
          </g>
        );
      })}

      {/* ACT 5 — Data beams rising from poles toward center */}
      {beams > 0 && polePositions.map((px, i) => {
        const stagger = Math.max(0, Math.min(1, beams * 1.3 - i * 0.07));
        if (stagger <= 0) return null;
        const startX = px;
        const startY = 320; // pole top approx
        const endX = 600;
        const endY = 320;

        // Bezier control point for arc
        const midX = (startX + endX) / 2;
        const midY = startY - 80 - Math.abs(startX - endX) * 0.15;

        return (
          <g key={`beam-${i}`} opacity={stagger}>
            <path
              d={`M ${startX} ${startY} Q ${midX} ${midY} ${endX} ${endY}`}
              stroke={GC.blue}
              strokeWidth="1"
              fill="none"
              opacity="0.35"
              strokeDasharray="4 4"
            />
            {/* Animated particle dots flowing along the path */}
            {[0, 0.33, 0.66].map((offset, j) => {
              const t = (p * 4 + offset + i * 0.1) % 1;
              const ix = (1-t)*(1-t)*startX + 2*(1-t)*t*midX + t*t*endX;
              const iy = (1-t)*(1-t)*startY + 2*(1-t)*t*midY + t*t*endY;
              return (
                <circle key={j} cx={ix} cy={iy} r="2" fill={GC.blueGlow} opacity={stagger * (1 - t * 0.4)} />
              );
            })}
          </g>
        );
      })}

      {/* Center pulse (where beams converge) */}
      {beams > 0.4 && (
        <g transform="translate(600, 320)">
          <circle r={40 * Math.min(1, (beams - 0.4) * 2)} fill="url(#gc_bluepulse)" />
        </g>
      )}

      </g>

      {/* ACT 6 — BLADES ASSEMBLE: city dissolves, real logo blades fly in from scene elements */}
      {/*
        Original blade coords from brand SVG (viewBox 0 0 ~382 ~410):
          blade-05 (dot):        cx≈260, cy≈113, r≈45
          blade-06 (top-left):   bbox ~ 0..173,  87..265
          blade-07 (right):      bbox ~ 209..381, 184..402
          blade-08 (bottom-left):bbox ~ 63..236,  201..397
        Center of formation ≈ (190, 230). We want to land at scene center (600, 350).
        Scale 1.05 → translate by (600 - 190*1.05, 350 - 230*1.05) = (400.5, 108.5)
      */}
      {(() => {
        // Final blade size must match logo-h (~104 CSS px max) at the lockup placeholder.
        // At ~1920px viewport, scene scale = 1.6 → 1 CSS px ≈ 0.625 viewBox units.
        // Blade artwork is 410 units tall; we want ~65 viewBox units → scale ≈ 0.16.
        const LOGO_SCALE = 0.16;
        // Blade landing nudged to overlap the icon position of the full guardCity PNG
        // when it fades in centered on the lockup at typical desktop viewports.
        const LOGO_CENTER_X = 470;
        const LOGO_CENTER_Y = 330;
        const LOGO_TX = LOGO_CENTER_X - 190 * LOGO_SCALE;
        const LOGO_TY = LOGO_CENTER_Y - 230 * LOGO_SCALE;
        // Each blade starts at a scattered "city" origin (in scene coords),
        // then morphs to its logo origin. We compute per-blade transforms.
        // The blade paths are authored in the original SVG coordinate system,
        // so to render them we apply translate(LOGO_TX, LOGO_TY) scale(LOGO_SCALE)
        // — combined with a per-blade fly-in from a starting offset+rotation.

        // logoIn drives assembly. Each blade has stagger.
        const blades = [
          {
            id: 'blade-05', // dot — starts huge top-center, shrinks down to icon spot
            startOffset: [120, -180],
            startRot: 0,
            startScale: 8,
            stagger: 0.00,
            d: "M260.49,159.20c60.01-1.02,60-90.29,0-91.31-59.71.27-59.70,91.05,0,91.31Z",
            fill: 'url(#gc_blade_d)',
          },
          {
            id: 'blade-06', // right swirl — comes from camera pole right side
            // Final bbox center ≈ (295, 293) → scene (709, 416)
            // Origin: from a right-side camera ≈ (1020, 380)
            startOffset: [380, 60],
            startRot: -180,
            startScale: 8,
            stagger: 0.08,
            d: "M358.49,184.55c-21.99-12.70-50.11-5.16-62.80,16.82-14.60,25.28,6.99,45.88-14.96,83.89-21.95,38.01-50.57,29.62-65.17,54.90-12.69,21.99-5.16,50.10,16.83,62.80,21.99,12.70,50.10,5.16,62.79-16.83,14.59-25.27-7.16-45.81,14.86-83.95,22.01-38.13,50.68-29.58,65.27-54.84,12.70-21.99,5.16-50.10-16.83-62.80Z",
            fill: 'url(#gc_blade_b)',
          },
          {
            id: 'blade-07', // top-left swirl — comes from skyline upper left
            // Final bbox center ≈ (86, 173) → scene (491, 290)
            // Origin: top-left ≈ (140, 100)
            startOffset: [-420, -160],
            startRot: 180,
            startScale: 8,
            stagger: 0.16,
            d: "M86.11,265.42c14.59-25.27-7.16-45.81,14.86-83.95,22.01-38.13,50.68-29.58,65.27-54.84,29.31-52.80-48.51-97.81-79.63-45.97-14.60,25.28,6.99,45.87-14.96,83.88-21.95,38.02-50.57,29.62-65.17,54.90-29.31,52.80,48.50,97.82,79.62,45.97Z",
            fill: 'url(#gc_blade_c)',
          },
          {
            id: 'blade-08', // bottom swirl — comes from ground / beam trail
            // Final bbox center ≈ (156, 293) → scene (564, 416)
            // Origin: bottom-center ≈ (300, 600)
            startOffset: [-180, 280],
            startRot: 220,
            startScale: 8,
            stagger: 0.24,
            d: "M236.32,247.35c29.32-52.80-48.51-97.82-79.63-45.97-14.60,25.28,6.99,45.87-14.96,83.88-21.94,38.02-50.57,29.62-65.17,54.90-29.31,52.80,48.50,97.82,79.62,45.97,14.59-25.27-7.16-45.81,14.86-83.95,22.01-38.13,50.69-29.58,65.27-54.84Z",
            fill: 'url(#gc_blade_a)',
          },
        ];

        return (
          <g opacity={1 - bladesFade}>
            {/* Soft white aura behind assembled logo */}
            {logoIn > 0.4 && (
              <g transform={`translate(${LOGO_CENTER_X}, ${LOGO_CENTER_Y})`} opacity={(logoIn - 0.4) * 1.6}>
                <circle r={220} fill="url(#gc_bluepulse)" opacity="0.6" />
                <circle r={140} fill="url(#gc_bluepulse)" opacity="0.4" />
              </g>
            )}

            {blades.map((b) => {
              const t = ease(Math.max(0, Math.min(1, (logoIn - b.stagger) / Math.max(0.001, 1 - b.stagger))));
              const opacity = Math.min(1, t * 1.8);
              // Interpolate from start (scattered) to final (assembled)
              const dx = b.startOffset[0] * (1 - t);
              const dy = b.startOffset[1] * (1 - t);
              const rot = b.startRot * (1 - t);
              const sc = b.startScale + (1 - b.startScale) * t;
              return (
                <g
                  key={b.id}
                  transform={`translate(${LOGO_TX + dx}, ${LOGO_TY + dy}) scale(${LOGO_SCALE * sc}) rotate(${rot}, 190, 230)`}
                  opacity={opacity}
                >
                  <path d={b.d} fill={b.fill} fillRule="evenodd" />
                </g>
              );
            })}
          </g>
        );
      })()}
    </svg>
    </div>
  );
}

// Module card — DirectLuz-aligned blue accent.
function ModuleCard({ m, mono }) {
  return (
    <article style={{
      background: GC.navy,
      border: `1px solid ${GC.steel}`,
      padding: '32px 28px',
      display: 'flex',
      flexDirection: 'column',
      gap: 14,
      position: 'relative',
      minHeight: 280,
    }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
        <div style={{
          width: 44, height: 44,
          background: GC.ink,
          border: `1px solid ${GC.iron}`,
          display: 'grid', placeItems: 'center',
        }}>
          <img src={m.icon} alt="" style={{ width: 26, height: 26, objectFit: 'contain' }} />
        </div>
        <span style={{
          fontFamily: mono ? '"JetBrains Mono", ui-monospace, monospace' : 'inherit',
          fontSize: 10, letterSpacing: 2,
          color: GC.fog, textTransform: 'uppercase',
        }}>{m.role}</span>
      </div>
      <h3 style={{
        fontSize: 26, fontWeight: 700,
        margin: 0, color: GC.bone,
        letterSpacing: '-0.02em',
      }}>{m.name}</h3>
      <p style={{ margin: 0, color: GC.fog, fontSize: 14, lineHeight: 1.55 }}>{m.pitch}</p>
      <div style={{ flex: 1 }} />
      <a href="#" style={{
        color: GC.blueLight,
        fontFamily: mono ? '"JetBrains Mono", ui-monospace, monospace' : 'inherit',
        fontSize: 11, letterSpacing: 2,
        textTransform: 'uppercase', textDecoration: 'none',
        display: 'flex', alignItems: 'center', gap: 8,
      }}>
        Conhecer <span>→</span>
      </a>
    </article>
  );
}

Object.assign(window, { GC, GC_MODULES, CityScene, ModuleCard });
