/* MANARA — Main App shell (full-bleed map + 3 floating columns: DETECT • RESPOND • DELIVER) */

const { useState: useStateApp, useEffect: useEffectApp, useMemo: useMemoApp, useRef: useRefApp } = React;
const D = window.MANARA_DATA;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "briefingMode": "minister",
  "scenarioOverride": "auto",
  "mapStyle": "dark",
  "motionLevel": "normal"
}/*EDITMODE-END*/;

function App() {
  const [locale, setLocale] = useStateApp('ar');
  const [tweaks, setTweak] = window.useTweaks ? window.useTweaks(TWEAK_DEFAULTS) : [TWEAK_DEFAULTS, () => {}];
  const [scenarioIndex, setScenarioIndex] = useStateApp(0);
  const [showTweaks, setShowTweaks] = useStateApp(false);
  const [showHelp, setShowHelp] = useStateApp(false);

  const isAr = locale === 'ar';
  const t = D.ui[locale];

  // Apply RTL on body
  useEffectApp(() => {
    document.body.dir = isAr ? 'rtl' : 'ltr';
    document.body.lang = isAr ? 'ar' : 'en';
  }, [isAr]);

  // Tweaks panel protocol
  useEffectApp(() => {
    const handler = (ev) => {
      const d = ev.data || {};
      if (d.type === '__activate_edit_mode') setShowTweaks(true);
      if (d.type === '__deactivate_edit_mode') setShowTweaks(false);
    };
    window.addEventListener('message', handler);
    window.parent.postMessage({ type: '__edit_mode_available' }, '*');
    return () => window.removeEventListener('message', handler);
  }, []);

  // Scenario auto-advance loop
  useEffectApp(() => {
    if (tweaks.scenarioOverride && tweaks.scenarioOverride !== 'auto') {
      const idx = D.scenarios.findIndex(s => s.id === tweaks.scenarioOverride);
      if (idx >= 0) setScenarioIndex(idx);
      return;
    }
    const current = D.scenarios[scenarioIndex];
    const id = setTimeout(() => {
      setScenarioIndex((i) => (i + 1) % D.scenarios.length);
    }, current.duration);
    return () => clearTimeout(id);
  }, [scenarioIndex, tweaks.scenarioOverride]);

  const scenario = D.scenarios[scenarioIndex];

  // ============================================================
  // SCENARIO-DRIVEN LIVE DATA — single source of truth.
  // Detect/respond signals shift per scenario, then pipeline +
  // hero totals are *derived* from them so every number agrees.
  // ============================================================
  const liveDetectSignals = useMemoApp(() => {
    const s = JSON.parse(JSON.stringify(D.detectSignals)); // deep clone
    if (scenario.id === 'e11') {
      s.traffic.count += 3;        s.traffic.severity = 'critical';
      s.civilDefense.count += 1;   s.civilDefense.severity = 'warning';
      s.ops.count += 2;            s.ops.severity = 'warning';
    } else if (scenario.id === 'hassantuk') {
      s.civilDefense.count += 1;   s.civilDefense.severity = 'positive';
      s.community.count += 1;
    } else if (scenario.id === 'query') {
      s.traffic.count += 6;        s.traffic.severity = 'warning';
      s.smart.count += 2;
    }
    return s;
  }, [scenario]);

  const liveRespondSignals = useMemoApp(() => {
    const s = JSON.parse(JSON.stringify(D.respondSignals));
    if (scenario.id === 'e11') {
      s.traffic.count += 4;        s.traffic.severity = 'critical'; s.traffic.eta = '0:00';
      s.civilDefense.count += 2;   s.civilDefense.severity = 'critical'; s.civilDefense.eta = '2:14';
      s.ops.count += 3;            s.ops.severity = 'critical';
    } else if (scenario.id === 'hassantuk') {
      s.civilDefense.count += 1;   s.civilDefense.severity = 'positive'; s.civilDefense.eta = '0:18';
      s.community.count += 1;
    } else if (scenario.id === 'query') {
      s.traffic.count += 2;        s.traffic.severity = 'warning';
      s.smart.count += 1;
    }
    return s;
  }, [scenario]);

  // Briefing-mode-driven expansions (which 3 of the 10 depts to "expand" in each column)
  const expandedDetect = useMemoApp(() => {
    if (tweaks.briefingMode === 'civildef') return ['civilDefense', 'ops', 'community'];
    if (tweaks.briefingMode === 'traffic') return ['traffic', 'smart', 'community'];
    if (tweaks.briefingMode === 'crisis') return ['traffic', 'civilDefense', 'criminal'];
    return scenario.expandedDetect;
  }, [scenario, tweaks.briefingMode]);

  const expandedRespond = useMemoApp(() => {
    if (tweaks.briefingMode === 'civildef') return ['civilDefense', 'ops', 'community'];
    if (tweaks.briefingMode === 'traffic') return ['traffic', 'ops', 'community'];
    if (tweaks.briefingMode === 'crisis') return ['traffic', 'civilDefense', 'ops'];
    return scenario.expandedDetect;
  }, [scenario, tweaks.briefingMode]);

  const expandedDeliver = useMemoApp(() => {
    if (tweaks.briefingMode === 'civildef') return ['civilDefense', 'community', 'strategy'];
    if (tweaks.briefingMode === 'traffic') return ['traffic', 'smart', 'strategy'];
    if (tweaks.briefingMode === 'crisis') return ['traffic', 'civilDefense', 'criminal'];
    return scenario.expandedDeliver;
  }, [scenario, tweaks.briefingMode]);

  const threatLevel = scenario.id === 'e11' ? 'GUARDED'
    : tweaks.briefingMode === 'crisis' ? 'ELEVATED'
    : 'NORMAL';

  /* Map choreography: crisis briefing locks camera; scenarios still drive fly-to targets */
  const mapWallMode = tweaks.briefingMode === 'crisis' ? 'crisis' : scenario.mode;

  // Live data simulation
  // Pipeline + totalActive are DERIVED from live signals so everything agrees.
  const derivedActive = useMemoApp(() =>
    Object.values(liveRespondSignals).reduce((a, s) => a + s.count, 0)
  , [liveRespondSignals]);

  const derivedDetections = useMemoApp(() =>
    Object.values(liveDetectSignals).reduce((a, s) => {
      // "detection" = signals that crossed the noise floor (warning+critical+positive)
      return a + (s.severity !== 'info' ? s.count : Math.round(s.count * 0.05));
    }, 0)
  , [liveDetectSignals]);

  const [pipeline, setPipeline] = useStateApp(D.pipelineStages.map(s => ({ ...s })));
  const [insightIdx, setInsightIdx] = useStateApp(0);
  const [incidents, setIncidents] = useStateApp(() => generateIncidents(scenario));
  const [patrols, setPatrols] = useStateApp(() => generatePatrols(derivedActive, scenario));
  const totalActive = derivedActive;

  // Sync pipeline derived counts whenever scenario shifts
  useEffectApp(() => {
    setPipeline(prev => prev.map(s => {
      if (s.id === 'active')      return { ...s, count: derivedActive };
      if (s.id === 'triage')      return { ...s, count: Math.round(derivedActive * 0.78) };
      if (s.id === 'assignment')  return { ...s, count: Math.round(derivedActive * 0.62) };
      if (s.id === 'detection')   return { ...s, count: derivedDetections };
      if (s.id === 'signal')      return { ...s, count: Math.max(s.count, derivedDetections * 32) };
      return s;
    }));
  }, [derivedActive, derivedDetections]);

  // Pipeline ticker — small drifts on top of derived baseline (signals + outcomes drift, response stays aligned)
  useEffectApp(() => {
    const id = setInterval(() => {
      setPipeline(prev => prev.map(s => {
        if (s.id === 'active' || s.id === 'triage' || s.id === 'assignment' || s.id === 'detection') return s;
        const drift = Math.round((Math.random() - 0.45) * (s.count > 1000 ? 12 : 2));
        return { ...s, count: Math.max(0, s.count + drift) };
      }));
    }, 4000);
    return () => clearInterval(id);
  }, []);

  // Insight rotation
  useEffectApp(() => {
    const id = setInterval(() => {
      setInsightIdx(i => (i + 1) % D.insights.length);
    }, 16000);
    return () => clearInterval(id);
  }, []);

  // Regenerate incidents per scenario
  useEffectApp(() => {
    setIncidents(generateIncidents(scenario));
    setPatrols(generatePatrols(derivedActive, scenario));
  }, [scenarioIndex, derivedActive]);

  // Patrol drift
  useEffectApp(() => {
    const id = setInterval(() => {
      setPatrols(prev => prev.map(p => ({
        ...p,
        lng: p.lng + (Math.random() - 0.5) * 0.02,
        lat: p.lat + (Math.random() - 0.5) * 0.015,
        heading: (p.heading + (Math.random() - 0.5) * 30 + 360) % 360
      })));
    }, 2200);
    return () => clearInterval(id);
  }, []);

  // Build current insight
  const currentInsight = useMemoApp(() => {
    if (scenario.id !== 'steady') {
      return {
        agent: scenario.agent,
        dept: scenario.department,
        severity: scenario.severity,
        en: scenario.insightEn,
        ar: scenario.insightAr
      };
    }
    return D.insights[insightIdx];
  }, [scenario, insightIdx]);

  return (
    <div className="wall-stage">
      {/* ===== Layer 0 — Full-bleed map ===== */}
      <div className="wall-stage__map">
        <window.MapboxMap
          locale={locale}
          scenario={scenario}
          incidents={incidents}
          patrols={patrols}
          opCenters={D.opCenters}
          isSatellite={tweaks.mapStyle === 'satellite'}
          mode={mapWallMode}
        />
      </div>

      {/* ===== Layer 1 — Vignette + grid ===== */}
      <div className="wall-stage__vignette" />
      <div className="wall-stage__grid" />

      {/* ===== Layer 10 — All UI floats ===== */}
      <div style={{
        position: 'absolute',
        inset: 0,
        zIndex: 10,
        display: 'flex',
        flexDirection: 'column',
        pointerEvents: 'none'
      }}>
        {/* Top header strip — Ask MANARA embedded inside */}
        <div style={{ pointerEvents: 'auto', flexShrink: 0 }}>
          <window.TopStrip
            locale={locale}
            setLocale={setLocale}
            briefingMode={tweaks.briefingMode}
            threatLevel={threatLevel}
            t={t}
            scenarioIndex={scenarioIndex}
            scenarioCount={D.scenarios.length}
            scenarioTitle={isAr ? scenario.titleAr : scenario.titleEn}
            voiceCommands={D.voiceCommands}
          />
        </div>

        {/* MAIN AREA — DETECT (left) · MAP (center) · DELIVER (right) */}
        <div style={{
          flex: 1,
          minHeight: 0,
          display: 'grid',
          gridTemplateColumns: 'clamp(300px, 22vw, 420px) 1fr clamp(300px, 22vw, 420px)',
          gap: 'clamp(12px, 1.2vw, 24px)',
          padding: 'clamp(12px, 1vw, 22px) clamp(16px, 1.4vw, 36px) 0',
          alignItems: 'stretch',
          pointerEvents: 'none'
        }}>
          {/* DETECT — left side column */}
          <div style={{ minHeight: 0, overflow: 'hidden', pointerEvents: 'auto' }}>
            <window.DetectColumn
              locale={locale} t={t}
              departments={D.departments}
              detectSignals={liveDetectSignals}
              expanded={expandedDetect}
            />
          </div>

          {/* CENTER — map breathing room with floating AI narrative + priority legend */}
          <div style={{
            display: 'flex',
            flexDirection: 'column',
            justifyContent: 'space-between',
            gap: 12,
            minHeight: 0,
            pointerEvents: 'none'
          }}>
            <div style={{ pointerEvents: 'auto', alignSelf: 'center', maxWidth: '100%' }}>
              <window.AiNarrativeCard locale={locale} t={t} scenario={scenario} />
            </div>
            <div style={{ pointerEvents: 'auto', alignSelf: 'center', width: '100%', maxWidth: 560 }}>
              <MapPriorityLegend locale={locale} t={t} incidents={incidents} />
            </div>
          </div>

          {/* DELIVER — right side column */}
          <div style={{ minHeight: 0, overflow: 'hidden', pointerEvents: 'auto' }}>
            <window.DeliverColumn
              locale={locale} t={t}
              departments={D.departments}
              deliverOutcomes={D.deliverOutcomes}
              expanded={expandedDeliver}
              strategicKpis={D.strategicKpis}
            />
          </div>
        </div>

        {/* RESPOND — full-width bottom band */}
        <div style={{ padding: 'clamp(10px, 0.9vw, 18px) clamp(16px, 1.4vw, 36px) 0', flexShrink: 0, pointerEvents: 'auto' }}>
          <window.RespondBand
            locale={locale} t={t}
            departments={D.departments}
            respondSignals={liveRespondSignals}
            expanded={expandedRespond}
            pipeline={pipeline}
            totalActive={totalActive}
            scenario={scenario}
          />
        </div>

        {/* Pipeline strip */}
        <div style={{ padding: 'clamp(8px, 0.7vw, 14px) clamp(16px, 1.4vw, 36px) 0', flexShrink: 0, pointerEvents: 'auto' }}>
          <window.PipelineStrip locale={locale} t={t} stages={pipeline} scenario={scenario} />
        </div>

        {/* AI commentary — bottom bar */}
        <div style={{ padding: 'clamp(8px, 0.7vw, 14px) clamp(16px, 1.4vw, 36px) clamp(12px, 1vw, 22px)', flexShrink: 0, pointerEvents: 'auto' }}>
          <window.AiInsightBar locale={locale} t={t} insights={D.insights} currentInsight={currentInsight} />
        </div>
      </div>

      {/* Zoom advisory banner — appears if browser is at >70% zoom */}
      <ZoomAdvisory locale={locale} />

      {/* Map style toggle (top-left under header) */}
      <div style={{ position: 'absolute', top: 'clamp(74px, 5.5vh, 110px)', insetInlineStart: 'clamp(16px, 1.4vw, 36px)', zIndex: 12 }}>
        <button
          onClick={() => setTweak('mapStyle', tweaks.mapStyle === 'satellite' ? 'dark' : 'satellite')}
          className="float-card"
          style={{
            padding: '6px 12px',
            color: 'var(--text-secondary)',
            fontFamily: isAr ? 'Tajawal, sans-serif' : 'JetBrains Mono, monospace',
            fontSize: 12,
            letterSpacing: isAr ? '0' : '0.15em',
            cursor: 'pointer',
            textTransform: isAr ? 'none' : 'uppercase',
            border: '1px solid var(--border-medium)'
          }}>
          {tweaks.mapStyle === 'satellite' ? t.mapToggleDark : t.mapToggleSat}
        </button>
      </div>

      {/* ? Help button — top-right, floating above the wall */}
      <button
        className="help-btn"
        onClick={() => setShowHelp(true)}
        title={isAr ? 'كيف تعمل منارة' : 'How MANARA works'}
        aria-label={isAr ? 'كيف تعمل منارة' : 'How MANARA works'}
      >?</button>

      {/* How MANARA Works overlay */}
      {showHelp && window.HelpOverlay && (
        <window.HelpOverlay onClose={() => setShowHelp(false)} locale={locale} />
      )}

      {/* Tweaks panel */}
      {showTweaks && window.TweaksPanel && (
        <window.TweaksPanel onClose={() => setShowTweaks(false)} title="Tweaks">
          <window.TweakSection title="Demo">
            <window.TweakSelect
              label="Scenario"
              value={tweaks.scenarioOverride}
              onChange={(v) => setTweak('scenarioOverride', v)}
              options={[
                { value: 'auto', label: 'Auto-loop' },
                { value: 'steady', label: '1 — Steady State' },
                { value: 'e11', label: '2 — E11 Incident' },
                { value: 'hassantuk', label: '3 — Hassantuk Prevention' },
                { value: 'query', label: '4 — Ask MANARA' }
              ]}
            />
            <window.TweakSelect
              label="Briefing Mode"
              value={tweaks.briefingMode}
              onChange={(v) => setTweak('briefingMode', v)}
              options={[
                { value: 'minister', label: 'Minister (default)' },
                { value: 'civildef', label: 'Civil Defense' },
                { value: 'traffic', label: 'Traffic' },
                { value: 'crisis', label: 'Crisis' }
              ]}
            />
            <window.TweakSelect
              label="Map Style"
              value={tweaks.mapStyle}
              onChange={(v) => setTweak('mapStyle', v)}
              options={[
                { value: 'dark', label: 'Dark' },
                { value: 'satellite', label: 'Satellite' }
              ]}
            />
          </window.TweakSection>
        </window.TweaksPanel>
      )}
    </div>
  );
}

/* ---------- Zoom advisory banner ---------- */
function ZoomAdvisory({ locale }) {
  const isAr = locale === 'ar';
  const [show, setShow] = useStateApp(false);
  const [dismissed, setDismissed] = useStateApp(() => {
    try { return localStorage.getItem('manara-zoom-dismissed') === '1'; } catch (e) { return false; }
  });

  useEffectApp(() => {
    if (dismissed) return;
    const check = () => {
      // devicePixelRatio approximates browser zoom on most desktop browsers.
      // Real wall scenario expects the page set to ~50–60% to fit ultra-wide.
      // If we're seeing >0.85 effective zoom (i.e. user hasn't zoomed out), nudge them.
      const ratio = window.devicePixelRatio || 1;
      const w = window.innerWidth;
      // Only nudge on smaller-than-ideal viewports OR high-DPR (un-zoomed) views
      const tooNarrow = w < 1900;
      setShow(tooNarrow);
    };
    check();
    window.addEventListener('resize', check);
    return () => window.removeEventListener('resize', check);
  }, [dismissed]);

  if (dismissed || !show) return null;

  const dismiss = () => {
    setDismissed(true);
    try { localStorage.setItem('manara-zoom-dismissed', '1'); } catch (e) {}
  };

  return (
    <div style={{
      position: 'fixed',
      bottom: 'clamp(14px, 1.2vw, 24px)',
      insetInlineStart: '50%',
      transform: 'translateX(-50%)',
      zIndex: 30,
      display: 'flex',
      alignItems: 'center',
      gap: 14,
      padding: '10px 18px',
      background: 'rgba(212, 175, 55, 0.12)',
      border: '1px solid rgba(212, 175, 55, 0.45)',
      borderRadius: 4,
      backdropFilter: 'blur(20px)',
      boxShadow: '0 8px 28px rgba(0,0,0,0.5), 0 0 24px rgba(212,175,55,0.15)',
      maxWidth: 'min(680px, 90vw)'
    }}>
      <span style={{
        width: 8, height: 8, borderRadius: '50%',
        background: 'var(--accent-gold)',
        boxShadow: '0 0 10px var(--accent-gold)',
        flexShrink: 0
      }} />
      <div style={{
        fontFamily: isAr ? 'Tajawal, sans-serif' : 'DM Sans, sans-serif',
        fontSize: 'clamp(12px, 0.78vw, 14px)',
        color: 'var(--text-primary)',
        lineHeight: 1.4,
        flex: 1
      }}>
        <strong style={{ color: 'var(--accent-gold)' }}>
          {isAr ? 'للحصول على أفضل عرض' : 'For the best view'}
        </strong>{' '}
        {isAr
          ? '— اضبط تكبير المتصفح إلى ٥٠–٦٠٪ (Cmd/Ctrl −). صُمّم منارة لشاشة جدارية فائقة الاتساع.'
          : '— set browser zoom to 50–60% (Cmd/Ctrl −). MANARA is designed for an ultra-wide command-center wall.'}
      </div>
      <button onClick={dismiss} style={{
        padding: '4px 10px',
        background: 'transparent',
        border: '1px solid rgba(212, 175, 55, 0.4)',
        color: 'var(--accent-gold)',
        fontFamily: isAr ? 'Tajawal, sans-serif' : 'JetBrains Mono, monospace',
        fontSize: 11,
        letterSpacing: isAr ? '0' : '0.15em',
        textTransform: isAr ? 'none' : 'uppercase',
        cursor: 'pointer',
        borderRadius: 2,
        flexShrink: 0
      }}>{isAr ? 'فهمت' : 'Got it'}</button>
    </div>
  );
}

/* ---------- Map priority legend ---------- */
function MapPriorityLegend({ locale, t, incidents }) {
  const isAr = locale === 'ar';
  const p1 = incidents.filter(i => i.severity === 'critical').length;
  const p2 = incidents.filter(i => i.severity === 'warning').length;
  const p3 = incidents.filter(i => i.severity === 'info').length;
  return (
    <div className="float-card" style={{
      padding: 'clamp(10px, 0.85vw, 16px) clamp(14px, 1.1vw, 22px)'
    }}>
      <div className="row between" style={{ marginBottom: 8 }}>
        <span className="label-caps" style={{ fontSize: 'clamp(10px, 0.66vw, 12px)' }}>
          {t.mapPriority}
        </span>
        <span style={{
          fontFamily: 'JetBrains Mono, monospace',
          fontSize: 'clamp(10px, 0.66vw, 12px)',
          color: 'var(--text-faint)',
          letterSpacing: '0.15em'
        }}>↳ {incidents.length} {isAr ? 'نقاط' : 'points'}</span>
      </div>
      <div className="row between" style={{ gap: 'clamp(8px, 1vw, 18px)', flexWrap: 'wrap' }}>
        {[
          { label: 'P1', sev: 'critical', count: p1, color: 'var(--status-critical)', name: { en: 'Critical', ar: 'حرج' } },
          { label: 'P2', sev: 'warning',  count: p2, color: 'var(--status-caution)',  name: { en: 'Warning', ar: 'تنبيه' } },
          { label: 'P3', sev: 'info',     count: p3, color: 'var(--status-info)',     name: { en: 'Monitor', ar: 'مراقبة' } }
        ].map(p => (
          <div key={p.label} className="row" style={{ gap: 8, flex: 1, minWidth: 0 }}>
            <span style={{
              width: 12, height: 12, borderRadius: '50%',
              background: p.color,
              boxShadow: `0 0 0 3px ${p.color}33, 0 0 12px ${p.color}99`,
              animation: p.sev === 'critical' ? 'dotPulse 1.4s ease-in-out infinite' : 'none',
              flexShrink: 0
            }} />
            <span style={{
              fontFamily: 'JetBrains Mono, monospace',
              fontSize: 'clamp(11px, 0.78vw, 14px)',
              color: p.color,
              fontWeight: 800,
              letterSpacing: '0.1em'
            }}>{p.label}</span>
            <span style={{
              fontFamily: isAr ? 'Tajawal, sans-serif' : 'DM Sans, sans-serif',
              fontSize: 'clamp(11px, 0.75vw, 13px)',
              color: 'var(--text-secondary)',
              flex: 1,
              minWidth: 0,
              whiteSpace: 'nowrap',
              overflow: 'hidden',
              textOverflow: 'ellipsis'
            }}>{isAr ? p.name.ar : p.name.en}</span>
            <span style={{
              fontFamily: 'JetBrains Mono, monospace',
              fontSize: 'clamp(14px, 0.95vw, 18px)',
              color: 'var(--text-primary)',
              fontWeight: 800,
              fontVariantNumeric: 'tabular-nums'
            }}>{p.count}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

/* ---------- Mock data generators ---------- */
function generateIncidents(scenario) {
  // Steady-state ambient (~9 info+warn points)
  const base = [
    { lng: 55.27, lat: 25.20, severity: 'info', label: 'DXB' },
    { lng: 55.30, lat: 25.05, severity: 'info', label: 'BUR' },
    { lng: 54.40, lat: 24.45, severity: 'info', label: 'AUH' },
    { lng: 54.36, lat: 24.51, severity: 'warning', label: 'KHA' },
    { lng: 55.40, lat: 25.34, severity: 'warning', label: 'SHJ' },
    { lng: 55.94, lat: 25.78, severity: 'info', label: 'RAK' },
    { lng: 55.76, lat: 24.21, severity: 'info', label: 'ALN' },
    { lng: 56.34, lat: 25.13, severity: 'info', label: 'FUJ' },
    { lng: 55.50, lat: 25.40, severity: 'warning', label: 'AJM' }
  ];
  if (scenario?.id === 'e11') {
    base.push({ lng: 54.92, lat: 24.85, severity: 'critical', label: 'E11 km47' });
    base.push({ lng: 54.95, lat: 24.87, severity: 'warning', label: 'E11 km48' });
    base.push({ lng: 54.89, lat: 24.83, severity: 'warning', label: 'E11 km46' });
  }
  if (scenario?.id === 'hassantuk') {
    base.push({ lng: 55.764, lat: 24.207, severity: 'critical', label: 'HSN-401' });
  }
  if (scenario?.id === 'query') {
    base.push({ lng: 55.50, lat: 25.40, severity: 'critical', label: 'E311 S' });
    base.push({ lng: 55.55, lat: 25.42, severity: 'warning', label: 'E311 M' });
    base.push({ lng: 55.45, lat: 25.38, severity: 'warning', label: 'E311 N' });
  }
  return base;
}

function generatePatrols(activeCount, scenario) {
  const out = [];
  // Base distribution centers across the country
  const centers = [
    [55.27, 25.20], [54.40, 24.45], [55.40, 25.34],
    [55.94, 25.78], [55.76, 24.21], [56.34, 25.13]
  ];
  // Scenario-specific hotspots — concentrate patrols near the active scene
  const hotspots = [];
  if (scenario?.id === 'e11')      hotspots.push([54.92, 24.85], [54.95, 24.87], [54.89, 24.83]);
  if (scenario?.id === 'hassantuk') hotspots.push([55.764, 24.207]);
  if (scenario?.id === 'query')    hotspots.push([55.50, 25.40], [55.55, 25.42], [55.45, 25.38]);

  // Total patrols ≈ active count, capped to prevent map clutter
  const n = Math.min(Math.max(activeCount || 14, 12), 28);
  // 60% scenario hotspots when available, 40% baseline distribution
  const hotShare = hotspots.length ? Math.round(n * 0.6) : 0;
  for (let i = 0; i < n; i++) {
    const c = (i < hotShare && hotspots.length)
      ? hotspots[i % hotspots.length]
      : centers[i % centers.length];
    const jitter = (i < hotShare) ? 0.08 : 0.4;
    out.push({
      lng: c[0] + (Math.random() - 0.5) * jitter,
      lat: c[1] + (Math.random() - 0.5) * (jitter * 0.75),
      heading: Math.random() * 360
    });
  }
  return out;
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
