/* Austria map — real Bundesländer geometry, gray "In Vorbereitung",
   hover-only labels, live pin links to its city dashboard. */

const { useState: u_useState, useEffect: u_useEffect, useMemo: u_useMemo } = React;

const STATUS_META = {
  live: { label: "Live", short: "Live", description: "Plattform öffentlich verfügbar" },
  active: { label: "In Vorbereitung", short: "Aktiv", description: "Rollout läuft" },
  future: { label: "Vormerkung", short: "Anfrage", description: "Anfrage / Vormerkung" }
};

// Only LIVE cities have a real dashboard URL today. Others are visual
// markers — hover shows the name, click does nothing.
const CITIES = [
{
  id: "linz",
  name: "Linz",
  state: "Oberösterreich",
  pop: "210.000",
  status: "live",
  since: "seit 2026",
  coords: [14.2858, 48.3069],
  url: "https://linz.politikdashboard.at",
  note: "Live seit 2026."
},
{
  id: "sierning",
  name: "Sierning",
  state: "Oberösterreich",
  pop: "9.300",
  status: "active",
  since: "Rollout 2026",
  coords: [14.3167, 48.0500],
  labelBelow: true,
  note: "Marktgemeinde — Pilot für kleinere Gemeinden."
},
{
  id: "ooe",
  name: "Oberösterreich",
  state: "Landtag",
  pop: "1,5 Mio.",
  status: "active",
  since: "in Vorbereitung",
  coords: [14.05, 48.10],
  isRegion: true,
  mapHidden: true,
  note: "Landtags-Variante in Vorbereitung."
},
// soft "Vormerkung" markers — small grey unlabeled-by-default dots
{ id: "wien", name: "Wien", state: "Wien", status: "future", coords: [16.3738, 48.2082], since: "Vormerkung" },
{ id: "graz", name: "Graz", state: "Steiermark", status: "future", coords: [15.4395, 47.0707], since: "Vormerkung" },
{ id: "salzburg", name: "Salzburg", state: "Salzburg", status: "future", coords: [13.0500, 47.8000], since: "Vormerkung" }];


const ACTIVE_REGIONS = new Set(["Oberösterreich", "Upper Austria", "Oberoesterreich"]);

const AT_FALLBACK_PATH =
"M 6,279 L 130,269 L 260,269 L 390,250 L 519,192 L 649,96 L 779,29 L 909,29 L 981,115 L 994,192 L 961,250 L 896,385 L 857,414 L 805,442 L 740,452 L 623,481 L 545,471 L 455,462 L 377,442 L 325,404 L 247,394 L 156,414 L 91,414 L 46,394 L 13,346 Z";

const GEO_URL =
"https://cdn.jsdelivr.net/gh/codeforgermany/click_that_hood@main/public/data/austria-states.geojson";

// Pin color: accent only for LIVE; everything else uses neutral gray.
function pinColor(status, accent) {
  if (status === "live") return accent;
  return "var(--pin-gray, #94a3a6)";
}

function CityPin({ city, accent }) {
  const isLive = city.status === "live";
  const isActive = city.status === "active";
  const color = pinColor(city.status, accent);

  const labelY = isLive ? -18 : city.labelBelow ? 22 : -14;

  const visual =
  <>
      {isLive &&
    <>
          <circle r="22" fill={color} opacity="0.12">
            <animate attributeName="r" from="14" to="34" dur="2.4s" repeatCount="indefinite" />
            <animate attributeName="opacity" from="0.35" to="0" dur="2.4s" repeatCount="indefinite" />
          </circle>
          <circle r="9" fill={color} />
          <circle r="3.5" fill="white" />
        </>
    }
      {isActive &&
    <>
          <circle r="9" fill={color} opacity="0.22" />
          <circle r="6" fill={color} />
        </>
    }
      {city.status === "future" &&
    <circle r="5" fill="white" stroke="var(--at-future-stroke)" strokeWidth="1.5" strokeDasharray="2 2" opacity="0.9" />
    }
      <circle r="18" fill="transparent" />
      <g
      className="pin-label"
      transform={`translate(0, ${labelY})`}
      style={{ pointerEvents: "none" }}>
      
        <text
        textAnchor="middle"
        fontSize="13.5"
        fontWeight={isLive ? 600 : 500}
        fill="var(--ink)"
        style={{ paintOrder: "stroke", stroke: "var(--surface)", strokeWidth: 4 }}>
        
          {city.name}
        </text>
      </g>
    </>;


  // Live cities are wrapped in an <a>; others are inert <g>s.
  if (city.url) {
    return (
      <a
        className="pin pin-link"
        href={city.url}
        target="_blank"
        rel="noopener noreferrer"
        transform={`translate(${city.x}, ${city.y})`}
        aria-label={`${city.name} — ${STATUS_META[city.status].label}, Dashboard öffnen`}
        style={{ cursor: "pointer", outline: "none" }}>
        
        {visual}
      </a>);

  }
  return (
    <g
      className="pin"
      transform={`translate(${city.x}, ${city.y})`}
      aria-label={`${city.name} — ${STATUS_META[city.status].label}`}
      style={{ outline: "none" }}>
      
      {visual}
    </g>);

}

function AustriaMap({ accent }) {
  const [geo, setGeo] = u_useState(null);
  const [failed, setFailed] = u_useState(false);

  u_useEffect(() => {
    let cancelled = false;
    fetch(GEO_URL).
    then((r) => {if (!r.ok) throw new Error("fetch failed");return r.json();}).
    then((d) => {if (!cancelled) setGeo(d);}).
    catch(() => {if (!cancelled) setFailed(true);});
    return () => {cancelled = true;};
  }, []);

  const W = 1000,H = 500;

  const projection = u_useMemo(() => {
    if (geo && window.d3?.geoMercator) {
      return window.d3.geoMercator().fitExtent([[20, 20], [W - 20, H - 20]], geo);
    }
    return (coords) => {
      const [lng, lat] = coords;
      return [(lng - 9.5) / 7.7 * W, (49 - lat) / 2.6 * H];
    };
  }, [geo]);

  const pathGen = u_useMemo(() => {
    if (geo && window.d3?.geoPath) return window.d3.geoPath(projection);
    return null;
  }, [geo, projection]);

  const pinned = u_useMemo(() => {
    return CITIES.filter((c) => !c.mapHidden).map((c) => {
      const [x, y] = projection(c.coords);
      return { ...c, x, y };
    });
  }, [projection]);

  function regionName(f) {
    const p = f.properties || {};
    return p.name || p.NAME_1 || p.NAME || p.NUTS_NAME || "";
  }

  return (
    <svg
      viewBox={`0 0 ${W} ${H}`}
      className="austria-svg"
      role="img"
      aria-label="Karte Österreichs mit Bundesländern und Standorten">
      
      <defs>
        <filter id="at-shadow" x="-10%" y="-10%" width="120%" height="130%">
          <feGaussianBlur stdDeviation="5" />
        </filter>
      </defs>

      {geo && pathGen &&
      <g>
          {/* very soft drop shadow — keeps map feeling like a backdrop */}
          <g transform="translate(0, 8)" opacity="0.22">
            {geo.features.map((f, i) =>
          <path key={`s${i}`} d={pathGen(f)} fill="var(--at-shadow)" filter="url(#at-shadow)" />
          )}
          </g>
          {geo.features.map((f, i) => {
          const name = regionName(f);
          const isActive = ACTIVE_REGIONS.has(name);
          return (
            <path
              key={i}
              d={pathGen(f)}
              fill={isActive ? "var(--at-region-active)" : "var(--at-region)"}
              stroke="var(--at-stroke)"
              strokeWidth="0.8"
              strokeLinejoin="round">
              
                <title>{name}</title>
              </path>);

        })}
        </g>
      }

      {!geo && failed &&
      <g>
          <path d={AT_FALLBACK_PATH} fill="var(--at-shadow)" filter="url(#at-shadow)" transform="translate(0, 14)" opacity="0.4" />
          <path d={AT_FALLBACK_PATH} fill="var(--at-region)" stroke="var(--at-stroke)" strokeWidth="1.5" />
        </g>
      }

      {!geo && !failed &&
      <g>
          <rect x="40" y="120" width={W - 80} height={H - 240} rx="22" fill="var(--at-region)" opacity="0.5" />
          <text x={W / 2} y={H / 2} textAnchor="middle" fontSize="13" fill="var(--muted)" fontFamily="var(--font)">
            Karte wird geladen …
          </text>
        </g>
      }

      {(geo || failed) &&
      pinned.map((c) => <CityPin key={c.id} city={c} accent={accent} />)}
    </svg>);

}

Object.assign(window, { AustriaMap, CITIES, STATUS_META });