// Solkart — data layer
// Fylke shapes (simplified) and kommune positions (auto-computed from fylke paths).
// Map projection: hand-tuned 1000x1200 viewBox, stylized (not GeoJSON-accurate).

// 15 fylker (post-2024 reform). Capacity loaded from NVE data (window.NVE_CAPACITY).
const NVE = window.NVE_CAPACITY;

function fylkeCapacity(id) {
  const d = NVE.fylker[id];
  if (!d) return { capacity: 0, husholdning_kW: 0, andre_kW: 0 };
  return {
    capacity: Math.round((d.husholdning_kW + d.andre_kW) / 10) / 100, // MWp, 2 decimals
    husholdning_kW: d.husholdning_kW,
    andre_kW: d.andre_kW,
  };
}

const FYLKER = [
  {
    id: "finnmark",
    name: "Finnmark",
    d: "M 540 60 L 720 40 L 870 70 L 940 140 L 900 220 L 820 260 L 740 250 L 660 230 L 600 200 L 560 160 Z",
    ...fylkeCapacity("finnmark"),
  },
  {
    id: "troms",
    name: "Troms",
    d: "M 460 220 L 600 200 L 660 230 L 700 290 L 640 340 L 560 340 L 500 310 L 460 270 Z",
    ...fylkeCapacity("troms"),
  },
  {
    id: "nordland",
    name: "Nordland",
    d: "M 380 340 L 500 310 L 560 340 L 610 410 L 590 500 L 530 560 L 470 580 L 420 540 L 380 460 L 360 400 Z",
    ...fylkeCapacity("nordland"),
  },
  {
    id: "trondelag",
    name: "Trøndelag",
    d: "M 320 580 L 420 540 L 470 580 L 510 640 L 480 700 L 410 720 L 340 700 L 300 650 Z",
    ...fylkeCapacity("trondelag"),
  },
  {
    id: "more",
    name: "Møre og Romsdal",
    d: "M 220 700 L 340 700 L 410 720 L 400 770 L 320 790 L 240 780 L 200 740 Z",
    ...fylkeCapacity("more"),
  },
  {
    id: "vestland",
    name: "Vestland",
    d: "M 160 780 L 240 780 L 320 790 L 340 850 L 300 920 L 220 950 L 150 920 L 120 860 Z",
    ...fylkeCapacity("vestland"),
  },
  {
    id: "rogaland",
    name: "Rogaland",
    d: "M 130 920 L 220 950 L 260 1000 L 230 1060 L 160 1080 L 100 1040 L 90 980 Z",
    ...fylkeCapacity("rogaland"),
  },
  {
    id: "agder",
    name: "Agder",
    d: "M 230 1060 L 360 1030 L 420 1060 L 410 1110 L 320 1140 L 230 1130 L 200 1090 Z",
    ...fylkeCapacity("agder"),
  },
  {
    id: "telemark",
    name: "Telemark",
    d: "M 360 970 L 430 955 L 460 980 L 450 1020 L 420 1060 L 360 1030 Z",
    ...fylkeCapacity("telemark"),
  },
  {
    id: "vestfold",
    name: "Vestfold",
    d: "M 430 955 L 520 940 L 530 980 L 510 1020 L 450 1020 L 460 980 Z",
    ...fylkeCapacity("vestfold"),
  },
  {
    id: "buskerud",
    name: "Buskerud",
    d: "M 400 770 L 470 800 L 490 860 L 530 880 L 530 920 L 520 940 L 430 955 L 420 920 L 420 860 L 410 810 Z",
    ...fylkeCapacity("buskerud"),
  },
  {
    id: "akershus",
    name: "Akershus",
    d: "M 530 780 L 600 780 L 630 830 L 630 880 L 600 910 L 560 935 L 530 920 L 530 880 L 490 860 L 500 820 Z",
    ...fylkeCapacity("akershus"),
  },
  {
    id: "ostfold",
    name: "Østfold",
    d: "M 560 935 L 600 910 L 630 880 L 660 900 L 660 950 L 630 980 L 570 980 L 540 960 Z",
    ...fylkeCapacity("ostfold"),
  },
  {
    id: "innlandet",
    name: "Innlandet",
    d: "M 410 720 L 480 700 L 560 720 L 600 780 L 530 780 L 500 820 L 490 860 L 470 800 L 400 770 Z",
    ...fylkeCapacity("innlandet"),
  },
  {
    id: "oslo",
    name: "Oslo",
    d: "M 565 905 L 595 905 L 600 935 L 580 945 L 560 935 Z",
    ...fylkeCapacity("oslo"),
  },
];

// ── Compute fylke centroids from SVG paths ───────────────────────

// Parse "M x y L x y ... Z" path into [{x,y}, ...]
function parsePath(d) {
  const pts = [];
  const nums = d.match(/-?\d+(?:\.\d+)?/g);
  if (!nums) return pts;
  for (let i = 0; i < nums.length; i += 2) {
    pts.push({ x: parseFloat(nums[i]), y: parseFloat(nums[i + 1]) });
  }
  return pts;
}

// Polygon centroid (area-weighted)
function polygonCentroid(pts) {
  if (pts.length === 0) return { x: 500, y: 600 };
  let cx = 0, cy = 0, area = 0;
  for (let i = 0, n = pts.length; i < n; i++) {
    const j = (i + 1) % n;
    const cross = pts[i].x * pts[j].y - pts[j].x * pts[i].y;
    area += cross;
    cx += (pts[i].x + pts[j].x) * cross;
    cy += (pts[i].y + pts[j].y) * cross;
  }
  area /= 2;
  if (Math.abs(area) < 1) {
    // Degenerate polygon — use simple average
    const sx = pts.reduce((s, p) => s + p.x, 0) / pts.length;
    const sy = pts.reduce((s, p) => s + p.y, 0) / pts.length;
    return { x: sx, y: sy };
  }
  cx /= (6 * area);
  cy /= (6 * area);
  return { x: cx, y: cy };
}

// Bounding box of polygon
function polygonBounds(pts) {
  let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
  for (const p of pts) {
    if (p.x < minX) minX = p.x;
    if (p.x > maxX) maxX = p.x;
    if (p.y < minY) minY = p.y;
    if (p.y > maxY) maxY = p.y;
  }
  return { minX, maxX, minY, maxY };
}

// Point-in-polygon test (ray casting)
function pointInPolygon(px, py, pts) {
  let inside = false;
  for (let i = 0, j = pts.length - 1; i < pts.length; j = i++) {
    const yi = pts[i].y, yj = pts[j].y;
    const xi = pts[i].x, xj = pts[j].x;
    if ((yi > py) !== (yj > py) && px < (xj - xi) * (py - yi) / (yj - yi) + xi) {
      inside = !inside;
    }
  }
  return inside;
}

// Simple deterministic hash from string → 0..1
function nameHash(name, seed) {
  let h = seed | 0;
  for (let i = 0; i < name.length; i++) {
    h = ((h << 5) - h + name.charCodeAt(i)) | 0;
  }
  return ((h & 0x7fffffff) % 10000) / 10000;
}

// Pre-compute centroid and parsed points for each fylke
const _fylkeMeta = {};
for (const f of FYLKER) {
  const pts = parsePath(f.d);
  _fylkeMeta[f.id] = {
    centroid: polygonCentroid(pts),
    bounds: polygonBounds(pts),
    pts,
  };
}

// NVE fylke name → app fylke ID
const FYLKE_NAME_TO_ID = {};
for (const f of FYLKER) {
  FYLKE_NAME_TO_ID[f.name] = f.id;
  FYLKE_NAME_TO_ID[f.id] = f.id;
}
// Extra mappings for NVE names that differ
FYLKE_NAME_TO_ID["Møre og Romsdal"] = "more";
FYLKE_NAME_TO_ID["Trøndelag"] = "trondelag";
FYLKE_NAME_TO_ID["Østfold"] = "ostfold";

// Compute SVG position for a kommune within its fylke
function kommunePosition(name, fylkeId) {
  const meta = _fylkeMeta[fylkeId];
  if (!meta) return { x: 500, y: 600 };

  const { centroid, bounds, pts } = meta;
  const w = bounds.maxX - bounds.minX;
  const h = bounds.maxY - bounds.minY;
  // Spread radius — 30% of the smaller dimension, keeps points inside
  const spread = Math.min(w, h) * 0.3;

  // Generate a deterministic position using name hash
  // Try up to 5 offsets; pick first that lands inside the polygon
  for (let attempt = 0; attempt < 5; attempt++) {
    const angle = nameHash(name, attempt * 7919) * Math.PI * 2;
    const radius = nameHash(name, attempt * 7919 + 1) * spread;
    const px = centroid.x + Math.cos(angle) * radius;
    const py = centroid.y + Math.sin(angle) * radius;
    if (pointInPolygon(px, py, pts)) {
      return { x: Math.round(px), y: Math.round(py) };
    }
  }
  // Fallback: centroid itself
  return { x: Math.round(centroid.x), y: Math.round(centroid.y) };
}

// ── Build KOMMUNER from all NVE data ─────────────────────────────

const KOMMUNER = [];
for (const [name, data] of Object.entries(NVE.kommuner)) {
  const totalKWp = data.husholdning_kW + data.andre_kW;
  if (totalKWp <= 0) continue; // skip kommuner with no installed capacity

  const fylkeId = FYLKE_NAME_TO_ID[data.fylkeId] || data.fylkeId;
  const fylke = FYLKER.find((f) => f.id === fylkeId);
  if (!fylke) continue;

  const pos = kommunePosition(name, fylkeId);
  KOMMUNER.push({
    name,
    x: pos.x,
    y: pos.y,
    kWp: totalKWp,
    fylke: fylke.name,
  });
}

// Sort by kWp descending so the largest kommuner appear first
KOMMUNER.sort((a, b) => b.kWp - a.kWp);

// Expose centroids for map labels
const FYLKE_CENTROIDS = {};
for (const f of FYLKER) {
  FYLKE_CENTROIDS[f.id] = _fylkeMeta[f.id].centroid;
}

window.SOLKART_DATA = { FYLKER, KOMMUNER, FYLKE_CENTROIDS };
