/* Quick City IFM — Berlin coverage map: real Bezirke geodata (same pattern as the LNS Germany map) */

let _berlinDataCache = null;
async function loadBerlinData() {
  if (_berlinDataCache) return _berlinDataCache;
  try {
    const resp = await fetch('https://cdn.jsdelivr.net/gh/funkeinteraktiv/Berlin-Geodaten@master/berlin_bezirke.geojson');
    const geo = await resp.json();
    _berlinDataCache = geo;
  } catch (e) {
    _berlinDataCache = null;
  }
  return _berlinDataCache;
}

const QC_IFM_BERLIN_VIEWBOX = { w: 100, h: 76 }; // fallback until real data loads

// Real approximate coordinates [lng, lat] per named cluster area.
const QC_IFM_BERLIN_CLUSTERS = [
  { id: 'hsl', name: 'Hohenschönhausen / Lichtenberg / Weißensee', count: 45,   lng: 13.49, lat: 52.545 },
  { id: 'ppb', name: 'Pankow / Prenzlauer Berg / südl. Weißensee', count: 37.5, lng: 13.41, lat: 52.555 },
  { id: 'cwg', name: 'Charlottenburg / Wilmersdorf / Grunewald',   count: 37.5, lng: 13.30, lat: 52.50 },
  { id: 'fkm', name: 'Friedrichshain / Kreuzberg / östl. Mitte',   count: 32.5, lng: 13.42, lat: 52.51 },
  { id: 'wmm', name: 'Wedding / Moabit / nördl. Mitte',            count: 32.5, lng: 13.35, lat: 52.535 },
  { id: 'trw', name: 'Tegel / Reinickendorf / Wittenau',           count: 32.5, lng: 13.30, lat: 52.58 },
  { id: 'mha', name: 'Marzahn / Hellersdorf / Ahrensfelde',        count: 32.5, lng: 13.585,lat: 52.55 },
  { id: 'slz', name: 'Steglitz / Lichterfelde / Zehlendorf',       count: 32.5, lng: 13.30, lat: 52.44 },
  { id: 'ssf', name: 'Spandau / Staaken / Falkenhagener Feld',     count: 27.5, lng: 13.18, lat: 52.545 },
  { id: 'nbt', name: 'Neukölln / Britz / nördl. Treptow',          count: 27.5, lng: 13.45, lat: 52.475 },
  { id: 'tsf', name: 'Tiergarten / Schöneberg / Friedenau',        count: 27.5, lng: 13.34, lat: 52.487 },
  { id: 'bkp', name: 'Buch / Karow / Panketal',                    count: 22.5, lng: 13.50, lat: 52.62 },
  { id: 'fhh', name: 'Frohnau / Hermsdorf / Hohen Neuendorf',      count: 22.5, lng: 13.29, lat: 52.64 },
  { id: 'tmm', name: 'Tempelhof / Mariendorf / Marienfelde',       count: 22.5, lng: 13.38, lat: 52.44 },
  { id: 'kas', name: 'Köpenick / Adlershof / südöstl. Berlin',     count: 20,   lng: 13.57, lat: 52.44 },
  { id: 'lbs', name: 'Lichtenrade / Buckow / Schönefeld',          count: 17.5, lng: 13.45, lat: 52.40 },
  { id: 'wkg', name: 'Wannsee / Kladow / Gatow',                   count: 12.5, lng: 13.15, lat: 52.44 },
  { id: 'fal', name: 'Falkensee (Brandenburg)',                    count: 5,    lng: 13.08, lat: 52.56, outside: true }
];

const QC_IFM_HQ = { name: 'Zentrale — Blankenburger Str. 18, 13089 Berlin', lng: 13.459, lat: 52.586 };

function IfmBerlinMap({ rightShift } = {}) {
  const { t } = window.useT ? window.useT() : { t: (k, f) => f };
  const [data, setData] = React.useState(_berlinDataCache);
  const [hoverId, setHoverId] = React.useState(null);
  const [hoverCellIdx, setHoverCellIdx] = React.useState(null);
  const [hoverHQ, setHoverHQ] = React.useState(false);
  const clusters = QC_IFM_BERLIN_CLUSTERS;
  const hovered = hoverId ? clusters.find(c => c.id === hoverId) : null;
  const totalSites = Math.round(clusters.reduce((s, c) => s + c.count, 0));

  React.useEffect(() => {
    if (!data) { let cancelled = false; loadBerlinData().then(d => { if (!cancelled) setData(d); }); return () => { cancelled = true; }; }
  }, []);

  const projected = React.useMemo(() => {
    if (typeof window === 'undefined' || !window.d3 || !data) return null;
    const padTop = 4, padRight = rightShift ? 12 : 18, padBottom = 6, padLeft = rightShift ? 24 : 18, w = 100;
    // Aspect ratio comes ONLY from Berlin's own bounds (stable, known-good data) — the live
    // Falkensee fetch is drawn on top afterward and never allowed to affect the box shape/scale.
    const [[minLng, minLat], [maxLng, maxLat]] = window.d3.geoBounds(data);
    const midLat = (minLat + maxLat) / 2;
    const dx = (maxLng - minLng) * Math.cos(midLat * Math.PI / 180);
    const dy = (maxLat - minLat);
    const innerW = w - padLeft - padRight;
    const innerH = innerW * (dy / dx);
    const h = Math.round(innerH + padTop + padBottom);
    const proj = window.d3.geoMercator().fitExtent([[padLeft, padTop], [w - padRight, innerH + padTop]], data);
    const path = window.d3.geoPath(proj);
    const districtPaths = data.features.map(f => ({ name: f.properties && f.properties.name, d: path(f) }));
    const points = clusters.map(c => {
      const r = proj([c.lng, c.lat]) || [0, 0];
      return { ...c, x: r[0], y: r[1] };
    });
    const hq = proj([QC_IFM_HQ.lng, QC_IFM_HQ.lat]) || [0, 0];
    // Falkensee has no reliable live geodata source (fetch has twice produced degenerate/huge
    // geometry and broken the layout) — draw a small fixed decorative blob at its marker instead.
    const falMarker = clusters.find(c => c.id === 'fal');
    const markerProj = proj([falMarker.lng, falMarker.lat]);
    const falX = Math.max(padLeft * 0.5, 6);
    const falY = markerProj[1];
    const falkenseeBlob = { x: falX, y: falY, r: 5 };
    return { districtPaths, points, hq: { x: hq[0], y: hq[1] }, falkenseeBlob, w, h, padLeft };
  }, [data]);

  const hoveredBezirk = (!hovered && hoverCellIdx !== null && projected) ? projected.districtPaths[hoverCellIdx] : null;
  const falMarkerFixed = projected && projected.falkenseeBlob ? { x: projected.falkenseeBlob.x, y: projected.falkenseeBlob.y } : null;

  return (
    <div className="qc-cmap">
      <div className="qc-cmap__stage qc-cmap__stage--berlin" style={projected ? {aspectRatio: `${projected.w} / ${projected.h}`} : undefined}>
        <svg className="qc-cmap__svg" viewBox={`0 0 ${projected ? projected.w : QC_IFM_BERLIN_VIEWBOX.w} ${projected ? projected.h : QC_IFM_BERLIN_VIEWBOX.h}`} xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet">
          {projected ? (
            <>
              {projected.falkenseeBlob && (
                <circle cx={projected.falkenseeBlob.x} cy={projected.falkenseeBlob.y} r={projected.falkenseeBlob.r} fill="rgba(255,255,255,0.03)" stroke="rgba(255,255,255,0.28)" strokeWidth="0.3" />
              )}
              {projected.districtPaths.map((c, i) => (
                <path key={'cell-'+i} d={c.d}
                  fill={hoverCellIdx === i ? 'rgba(255,255,255,0.06)' : 'rgba(255,255,255,0.012)'}
                  stroke="rgba(255,255,255,0.18)" strokeWidth="0.3" strokeLinejoin="round"
                  style={{cursor:'pointer', transition:'fill 0.15s'}}
                  onMouseEnter={() => setHoverCellIdx(i)} onMouseLeave={() => setHoverCellIdx(null)} />
              ))}
              {projected.points.map(c => {
                const isActive = hoverId === c.id;
                const dimmed = hoverId && !isActive;
                const cx = (c.id === 'fal' && falMarkerFixed) ? falMarkerFixed.x : c.x;
                const cy = (c.id === 'fal' && falMarkerFixed) ? falMarkerFixed.y : c.y;
                const n = Math.max(1, Math.round(c.count / 8));
                const pins = Array.from({length: n}, (_, i) => {
                  const seed = (cx * 7 + cy * 13 + i * 31) % 1;
                  const seed2 = (cx * 17 + cy * 3 + i * 53) % 1;
                  const ang = seed * Math.PI * 2;
                  const dist = 2.4 + seed2 * 6.5;
                  return { x: cx + Math.cos(ang) * dist, y: cy + Math.sin(ang) * dist * 0.7 };
                });
                const s = 0.2 * (isActive ? 1.2 : 1);
                return (
                  <g key={c.id} style={{cursor:'pointer'}} onMouseEnter={() => setHoverId(c.id)} onMouseLeave={() => setHoverId(null)}>
                    <circle cx={cx} cy={cy} r={5.5} fill="transparent" />
                    {pins.map((p, i) => (
                      <g key={i} transform={`translate(${p.x},${p.y}) scale(${s}) translate(-12,-22)`} style={{transition:'transform 0.2s, opacity 0.2s', opacity: dimmed ? 0.4 : 1}}>
                        <path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7z" fill={c.outside ? '#777' : 'var(--accent)'} stroke={isActive ? '#fff' : 'rgba(255,255,255,0.6)'} strokeWidth={isActive ? 1.1 : 0.7} />
                      </g>
                    ))}
                  </g>
                );
              })}
              {projected.hq && (
                <g style={{cursor:'pointer'}} onMouseEnter={() => setHoverHQ(true)} onMouseLeave={() => setHoverHQ(false)}>
                  <circle cx={projected.hq.x} cy={projected.hq.y} r="5" fill="transparent" />
                  <circle cx={projected.hq.x} cy={projected.hq.y} r="0.8" fill="var(--accent)" opacity="0.4">
                    <animate attributeName="r" from="0.8" to="3" dur="2s" repeatCount="indefinite" />
                    <animate attributeName="opacity" from="0.4" to="0" dur="2s" repeatCount="indefinite" />
                  </circle>
                  <circle cx={projected.hq.x} cy={projected.hq.y} r={(hoverHQ ? 1.2 : 1.0) + 0.5} fill="#1a1a1a" style={{transition:'r 0.2s'}} />
                  <circle cx={projected.hq.x} cy={projected.hq.y} r={hoverHQ ? 1.2 : 1.0} fill="var(--accent)" stroke="#fff" strokeWidth={0.35} style={{transition:'r 0.2s'}} />
                </g>
              )}
            </>
          ) : (
            <text x="50" y="50" fill="rgba(255,255,255,0.4)" textAnchor="middle" fontSize="3">Karte lädt …</text>
          )}
        </svg>
        <div className={'qc-cmap__panel' + ((hovered || hoveredBezirk || hoverHQ) ? ' is-active' : '')}>
          {hoverHQ ? (
            <>
              <div className="qc-cmap__panel-meta">
                <span className="qc-cmap__panel-dot" style={{width:16, height:16}} />
                <span className="qc-cmap__panel-region">{t('ifmmap.hq', 'Zentrale')}</span>
              </div>
              <div className="qc-cmap__panel-name">{QC_IFM_HQ.name}</div>
            </>
          ) : hovered ? (
            <>
              <div className="qc-cmap__panel-meta">
                <span className="qc-cmap__panel-dot" style={{width:16, height:16}}><span>{Math.round(hovered.count)}</span></span>
                <span className="qc-cmap__panel-region">{t('ifmmap.objects', 'Objekte / Standorte')}</span>
              </div>
              <div className="qc-cmap__panel-name">{hovered.name}</div>
            </>
          ) : hoveredBezirk ? (
            <>
              <div className="qc-cmap__panel-meta">
                <span className="qc-cmap__panel-region">{t('ifmmap.bezirk', 'Bezirk')}</span>
              </div>
              <div className="qc-cmap__panel-name">{hoveredBezirk.name}</div>
            </>
          ) : (
            <div className="qc-cmap__panel-default">
              <div className="qc-cmap__panel-stat"><strong>{totalSites}<span className="qc-cmap__panel-plus">+</span></strong><span>{t('ifmmap.sites', 'Objekte')}</span></div>
              <div className="qc-cmap__panel-stat"><strong>{clusters.length}</strong><span>{t('ifmmap.regions', 'Gebiete')}</span></div>
              <div className="qc-cmap__panel-hint">{t('ifmmap.hint', 'Bewegen Sie den Mauszeiger über einen Punkt')}</div>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { IfmBerlinMap, QC_IFM_BERLIN_CLUSTERS });
