// Sites map — stylized SVG of the Cabinda Pilot operational area.
// No tile provider, no external library: just SVG driven by the FLEET_DATA
// coords. Click a pin → the parent sets siteFilter and the fleet list scrolls.

const _siteStatusColor = (s) =>
  s === 'alarm'   ? 'var(--alarm)' :
  s === 'warn'    ? 'var(--warn)'  :
  s === 'offline' ? 'var(--off)'   :
                    'var(--ok)';

const _worstSiteStatus = (site) => {
  if (site.gensets.some(g => g.status === 'alarm')) return 'alarm';
  if (site.gensets.some(g => g.status === 'warn'))  return 'warn';
  if (site.gensets.every(g => g.status === 'offline')) return 'offline';
  return 'running';
};

// Geographic bounds chosen to cover all 4 pilot sites + a margin for
// the Atlantic coast on the west. Equirectangular projection is fine at
// this scale (< 1° across).
const SitesMap = ({ sites, activeSiteId, onSiteClick }) => {
  const bounds = { lngMin: 11.90, lngMax: 12.42, latMin: -5.86, latMax: -5.26 };
  const vw = 800, vh = 320;
  const project = (lng, lat) => ({
    x: ((lng - bounds.lngMin) / (bounds.lngMax - bounds.lngMin)) * vw,
    y: ((bounds.latMax - lat) / (bounds.latMax - bounds.latMin)) * vh,
  });

  const placed = sites.map(s => {
    const [lat, lng] = s.coords.split(',').map(v => parseFloat(v.trim()));
    const worst = _worstSiteStatus(s);
    const running  = s.gensets.filter(g => g.status === 'running').length;
    const alarmCt  = s.gensets.filter(g => g.status === 'alarm').length;
    const warnCt   = s.gensets.filter(g => g.status === 'warn').length;
    const capacity = s.gensets.reduce((a, g) => a + g.kw, 0);
    const output   = s.gensets
      .filter(g => g.status === 'running' || g.status === 'warn')
      .reduce((a, g) => a + (g.kw * g.load / 100), 0);
    return { ...s, pos: project(lng, lat), worst, running, alarmCt, warnCt, capacity, output };
  });

  // Which side of the pin to render the label — flip to avoid running off
  // the right edge for sites near lngMax.
  const labelSide = (p) => (p.pos.x > vw * 0.72 ? 'left' : 'right');

  // Coastline is drawn to reflect real Cabinda geography: Atlantic on the
  // west, a pronounced eastward cape at Cabinda City, and a return northwest
  // south of the cape. The curve is calibrated against the pilot sites so
  // pins sit on the correct side of the coast — Malongo and Cabinda Port on
  // the coast itself, Fútila inland east of the city, Yema to the south.
  const cabindaCity = placed.find(p => p.id === 'cabinda')?.pos || { x: 435, y: 154 };
  const coastPath =
    'M 120 0 ' +
    'C 150 25, 170 55, 170 75 ' +
    `Q 205 115, ${cabindaCity.x.toFixed(1)} ${cabindaCity.y.toFixed(1)} ` +
    'Q 340 192, 245 232 ' +
    'Q 225 272, 230 320';

  const oceanMask =
    'M 0 0 L 120 0 ' +
    'C 150 25, 170 55, 170 75 ' +
    `Q 205 115, ${cabindaCity.x.toFixed(1)} ${cabindaCity.y.toFixed(1)} ` +
    'Q 340 192, 245 232 ' +
    'Q 225 272, 230 320 ' +
    'L 0 320 Z';

  return (
    <div className="sitesmap">
      <div className="sm-head">
        <div className="sm-title">
          <Icon.Site size={12}/>
          <span>Sites Map</span>
          <span className="sm-region">Cabinda Province · AO</span>
          <span className="sm-hint">Click a pin to filter the fleet list</span>
        </div>
        <div className="sm-legend">
          <span><span className="sm-dot ok"/>Operational</span>
          <span><span className="sm-dot warn"/>Warning</span>
          <span><span className="sm-dot alarm"/>Alarm</span>
          <span><span className="sm-dot off"/>Offline</span>
        </div>
      </div>
      <div className="sm-wrap">
        <svg className="sm-svg" viewBox={`0 0 ${vw} ${vh}`} preserveAspectRatio="xMidYMid meet">
          <defs>
            <linearGradient id="sm-ocean" x1="0" y1="0" x2="1" y2="0">
              <stop offset="0" stopColor="#0B1420" stopOpacity="0.9"/>
              <stop offset="1" stopColor="#0B1420" stopOpacity="0"/>
            </linearGradient>
            <pattern id="sm-grid" width="60" height="60" patternUnits="userSpaceOnUse">
              <path d="M 60 0 L 0 0 0 60" fill="none" stroke="#1E242E" strokeWidth="0.6" opacity="0.55"/>
            </pattern>
            <pattern id="sm-wave" width="14" height="6" patternUnits="userSpaceOnUse">
              <path d="M 0 3 Q 3.5 0, 7 3 T 14 3" fill="none" stroke="#1A3246" strokeWidth="0.5" opacity="0.5"/>
            </pattern>
          </defs>

          {/* Land base + grid graticule */}
          <rect width={vw} height={vh} fill="var(--bg-1)"/>
          <rect width={vw} height={vh} fill="url(#sm-grid)"/>

          {/* Atlantic Ocean (west) */}
          <path d={oceanMask} fill="#0B1420"/>
          <path d={oceanMask} fill="url(#sm-wave)" opacity="0.8"/>
          <path d={oceanMask} fill="url(#sm-ocean)"/>

          {/* Coastline */}
          <path d={coastPath} fill="none" stroke="#2E5B76" strokeWidth="1.4" opacity="0.9"/>
          <path d={coastPath} fill="none" stroke="var(--accent-cyan)" strokeWidth="0.6" opacity="0.35"/>

          {/* Ocean label */}
          <text x="70" y="162" fill="#2E5B76" fontSize="11" fontFamily="var(--mono)" letterSpacing="0.25em" opacity="0.75">ATLANTIC</text>
          <text x="70" y="178" fill="#2E5B76" fontSize="11" fontFamily="var(--mono)" letterSpacing="0.25em" opacity="0.75">OCEAN</text>

          {/* Province label */}
          <text x={vw - 16} y={vh - 14} textAnchor="end" fill="var(--text-3)" fontSize="10" fontFamily="var(--mono)" letterSpacing="0.18em">CABINDA · ANGOLA</text>

          {/* Coordinate hints at corners */}
          <text x="10" y="14" fill="var(--text-3)" fontSize="9" fontFamily="var(--mono)" opacity="0.6">{bounds.latMax.toFixed(2)}° / {bounds.lngMin.toFixed(2)}°</text>
          <text x={vw - 10} y="14" textAnchor="end" fill="var(--text-3)" fontSize="9" fontFamily="var(--mono)" opacity="0.6">{bounds.latMax.toFixed(2)}° / {bounds.lngMax.toFixed(2)}°</text>

          {/* Compass */}
          <g transform={`translate(${vw - 40}, 40)`}>
            <circle r="15" fill="var(--bg-2)" stroke="var(--line-strong)" strokeWidth="1"/>
            <path d="M 0 -10 L 3.5 0 L 0 2.5 L -3.5 0 Z" fill="var(--accent)"/>
            <path d="M 0 10 L 3.5 0 L 0 -2.5 L -3.5 0 Z" fill="var(--text-3)"/>
            <text y="-20" textAnchor="middle" fill="var(--text-1)" fontSize="10" fontFamily="var(--mono)" fontWeight="600">N</text>
          </g>

          {/* Cabinda City label — anchors the geography so pin positions
              read as meaningful relative locations. */}
          {(() => {
            const c = placed.find(p => p.id === 'cabinda');
            if (!c) return null;
            return (
              <g transform={`translate(${c.pos.x - 18}, ${c.pos.y + 36})`} opacity="0.55">
                <text fontSize="9" fontFamily="var(--mono)" fill="var(--text-3)" letterSpacing="0.22em">CABINDA CITY</text>
              </g>
            );
          })()}

          {/* Site pins — labels stagger vertically when two pins are close
              (e.g. Cabinda Port and Fútila Depot are 50px apart). */}
          {placed.map((s, idx) => {
            const active = activeSiteId === s.id;
            const clr = _siteStatusColor(s.worst);
            const side = labelSide(s);
            const dx = side === 'left' ? -16 : 16;
            const anchor = side === 'left' ? 'end' : 'start';
            let labelDy = 0;
            for (let j = 0; j < idx; j++) {
              const o = placed[j];
              if (Math.abs(o.pos.x - s.pos.x) < 110 && Math.abs(o.pos.y - s.pos.y) < 42) {
                labelDy += 36;
              }
            }
            // Tether line when the label is pushed down — keeps the
            // association between pin and label visually clear.
            return (
              <g key={s.id}
                 transform={`translate(${s.pos.x.toFixed(1)}, ${s.pos.y.toFixed(1)})`}
                 className={`sm-pin ${active ? 'active' : ''}`}
                 data-site={s.id}
                 onClick={() => onSiteClick && onSiteClick(s.id)}>
                {(s.worst === 'warn' || s.worst === 'alarm') && (
                  <circle r="10" fill={clr} opacity="0.35">
                    <animate attributeName="r" values="10;26;10" dur={s.worst === 'alarm' ? '1.4s' : '2.2s'} repeatCount="indefinite"/>
                    <animate attributeName="opacity" values="0.35;0;0.35" dur={s.worst === 'alarm' ? '1.4s' : '2.2s'} repeatCount="indefinite"/>
                  </circle>
                )}
                {active && <circle r="17" fill="none" stroke={clr} strokeWidth="1.5" opacity="0.6"/>}
                <circle r="10" fill="var(--bg-0)" stroke={clr} strokeWidth="2"/>
                <circle r="5" fill={clr}/>
                {labelDy > 0 && (
                  <line x1="0" y1="10" x2={dx * 0.6} y2={labelDy - 4} stroke={clr} strokeWidth="0.8" opacity="0.5" strokeDasharray="1 2"/>
                )}
                <g transform={`translate(${dx}, ${labelDy})`}>
                  <text y="-4" fontSize="12" fontFamily="var(--mono)" fill="var(--text-0)" fontWeight="600" textAnchor={anchor}>{s.name}</text>
                  <text y="10" fontSize="10" fontFamily="var(--mono)" fill="var(--text-2)" textAnchor={anchor}>
                    <tspan>{s.running}/{s.gensets.length} running</tspan>
                    {s.alarmCt > 0 && <tspan dx="6" fill="var(--alarm)"> · {s.alarmCt} alarm</tspan>}
                    {s.warnCt  > 0 && <tspan dx="6" fill="var(--warn)"> · {s.warnCt} warn</tspan>}
                  </text>
                  <text y="22" fontSize="9.5" fontFamily="var(--mono)" fill="var(--text-3)" textAnchor={anchor}>{(s.output/1000).toFixed(2)} / {(s.capacity/1000).toFixed(1)} MW</text>
                </g>
              </g>
            );
          })}

          {/* Scale bar */}
          <g transform={`translate(20, ${vh - 14})`}>
            <line x1="0" y1="0" x2="90" y2="0" stroke="var(--text-2)" strokeWidth="1"/>
            <line x1="0" y1="-3" x2="0" y2="3" stroke="var(--text-2)" strokeWidth="1"/>
            <line x1="45" y1="-2" x2="45" y2="2" stroke="var(--text-2)" strokeWidth="1"/>
            <line x1="90" y1="-3" x2="90" y2="3" stroke="var(--text-2)" strokeWidth="1"/>
            <text x="45" y="-6" fill="var(--text-2)" fontSize="9" textAnchor="middle" fontFamily="var(--mono)">~ 40 km</text>
          </g>
        </svg>
      </div>
    </div>
  );
};

Object.assign(window, { SitesMap });
