// Rapordan Türkiye haritası pinleri türetir — /sonuc ve /listem ortak kullanır.

import type { RaporSonuc } from "@/features/rapor/types/rapor";
import type { HaritaPin } from "@/features/liste/components/tercih-haritasi";
import { ilKonum, uniAdiNormalize, uniKonum } from "@/lib/harita";
import {
  yurtdisiIlKonum,
  yurtdisiUniKonum,
  type UlkeKodu,
} from "@/lib/harita-ulkeler";
import { dilimdenRisk, riskHesapla, type RiskSeviyesi } from "@/lib/risk";

const RISK_AGIRLIK: Record<RiskSeviyesi, number> = {
  guvenli: 0,
  "az-riskli": 1,
  riskli: 2,
};

/** Türkiye dışındaki tercihlerin ülke mini haritalarında şehir başına pini. */
export type YurtdisiPin = {
  id: string;
  ulke: UlkeKodu;
  ulkeAd: string;
  sehir: string;
  x: number;
  y: number;
  /** Bu şehirdeki tercihlerin liste sıraları (1-24) */
  tercihSiralari: number[];
  /** tercihSiralari ile hizalı — pin rengi çoğunluk riskiyle belirlenir */
  riskler: RiskSeviyesi[];
};

/**
 * Yurtdışı tercihini şehir pinine ekler; şehir çözülemezse false (harita
 * dışı). Kilitli satırlarda da üniversite adı verilebilir: ad yalnızca şehri
 * çözmek için okunur (KKTC satırlarının çoğunda şehir adın parantez ekinde),
 * üretilen pin yalnızca ülke/şehir/sayı taşır — üniversite kimliği görünmez.
 */
export function yurtdisiPinKaydet(
  gruplar: Map<string, YurtdisiPin>,
  universite: string | null,
  il: string | null,
  sira: number,
  risk: RiskSeviyesi,
): boolean {
  const konum = universite
    ? yurtdisiUniKonum(universite, il)
    : yurtdisiIlKonum(il);
  if (!konum) return false;
  const key = `${konum.ulke}|${konum.sehir}`;
  const mevcut = gruplar.get(key);
  if (mevcut) {
    mevcut.tercihSiralari.push(sira);
    mevcut.riskler.push(risk);
  } else {
    gruplar.set(key, {
      id: key,
      ...konum,
      tercihSiralari: [sira],
      riskler: [risk],
    });
  }
  return true;
}

/**
 * Rapordan harita pinleri türetir. Açık satırlar üniversite bazında gruplanır
 * (kampüs konumunda, adıyla); kilitli satırlar il başına tek adsız "?" pinine
 * toplanır — maskeli veride üniversite adı zaten client'a inmediği için
 * harita paywall'ı delemez. Türkiye dışındaki tercihler ülke mini haritaları
 * için şehir bazlı yurtdışı pinlerine ayrılır; orada da karşılığı olmayanlar
 * sayılır.
 */
export function pinleriTuret(
  rapor: RaporSonuc,
  adaySira: number,
  kilitliBaslangic: number,
): {
  pinler: HaritaPin[];
  yurtdisiPinler: YurtdisiPin[];
  haritaDisi: number;
} {
  const gruplar = new Map<string, HaritaPin>();
  const yurtdisi = new Map<string, YurtdisiPin>();
  let haritaDisi = 0;

  rapor.tercihler.forEach((t, i) => {
    const p = rapor.programlar[t.programId];
    if (!p) return;
    const risk = riskHesapla(p.efektifSira, adaySira) ?? dilimdenRisk(t.dilim);
    const kilitli = i >= kilitliBaslangic;

    if (kilitli) {
      const konum = ilKonum(p.il);
      if (!konum) {
        // Şehir çözümü için ad okunur, pine yazılmaz (bkz. yurtdisiPinKaydet)
        if (!yurtdisiPinKaydet(yurtdisi, p.universite, p.il, t.sira, risk))
          haritaDisi += 1;
        return;
      }
      const key = `kilit|${p.il}`;
      const mevcut = gruplar.get(key);
      if (mevcut) {
        mevcut.tercihSiralari.push(t.sira);
        // Kilitli satırda bölüm adı da gösterilmez — şeritte "Kilitli tercih"
        mevcut.bolumler.push("");
        if (RISK_AGIRLIK[risk] > RISK_AGIRLIK[mevcut.risk]) mevcut.risk = risk;
      } else {
        // Açık pinlerle üst üste binmesin diye il merkezinin hafif altına
        gruplar.set(key, {
          id: key,
          universite: "",
          il: p.il,
          x: konum.x,
          y: konum.y + 9,
          tercihSiralari: [t.sira],
          bolumler: [""],
          risk,
          kilitli: true,
        });
      }
      return;
    }

    const konum = uniKonum(p.universite, p.il);
    if (!konum) {
      if (!yurtdisiPinKaydet(yurtdisi, p.universite, p.il, t.sira, risk))
        haritaDisi += 1;
      return;
    }
    const key = `${uniAdiNormalize(p.universite)}|${p.il ?? ""}`;
    const mevcut = gruplar.get(key);
    if (mevcut) {
      mevcut.tercihSiralari.push(t.sira);
      mevcut.bolumler.push(p.isim);
      if (RISK_AGIRLIK[risk] > RISK_AGIRLIK[mevcut.risk]) mevcut.risk = risk;
    } else {
      gruplar.set(key, {
        id: key,
        universite: p.universite,
        il: p.il,
        x: konum.x,
        y: konum.y,
        tercihSiralari: [t.sira],
        bolumler: [p.isim],
        risk,
      });
    }
  });

  return {
    pinler: [...gruplar.values()],
    yurtdisiPinler: [...yurtdisi.values()],
    haritaDisi,
  };
}
