// Türkiye dışındaki (KKTC ve yurtdışı) üniversitelerin ülke haritası çözümü.
// Kontür verisi harita-ulkeler-verisi.ts'te (scripts/ulke-harita-uret.ts üretir).

import {
  ULKE_HARITALARI,
  type UlkeKodu,
  type UlkeHarita,
} from "./harita-ulkeler-verisi";
import type { LatLng } from "./uni-koordinatlar";

export {
  ULKE_HARITALARI,
  ULKE_HARITA_GENISLIK,
  ULKE_HARITA_YUKSEKLIK,
} from "./harita-ulkeler-verisi";
export type { UlkeKodu, UlkeHarita } from "./harita-ulkeler-verisi";

/** Schema.org addressCountry için ISO 3166-1 alpha-2 kodları. */
export const ULKE_ISO: Record<UlkeKodu, string> = {
  kktc: "CY",
  azerbaycan: "AZ",
  kirgizistan: "KG",
  kazakistan: "KZ",
  "bosna-hersek": "BA",
  makedonya: "MK",
  arnavutluk: "AL",
};

type Sehir = { ulke: UlkeKodu; ad: string; koord: LatLng };

/** DB'deki il değerlerinden ve düzeltme tablosundan şehir anahtarları. */
const SEHIRLER: Record<string, Sehir> = {
  GİRNE: { ulke: "kktc", ad: "Girne", koord: [35.341, 33.319] },
  LEFKOŞA: { ulke: "kktc", ad: "Lefkoşa", koord: [35.19, 33.365] },
  GAZİMAĞUSA: { ulke: "kktc", ad: "Gazimağusa", koord: [35.125, 33.941] },
  GÜZELYURT: { ulke: "kktc", ad: "Güzelyurt", koord: [35.198, 32.994] },
  LEFKE: { ulke: "kktc", ad: "Lefke", koord: [35.111, 32.849] },
  "BAKÜ-AZERBAYCAN": {
    ulke: "azerbaycan",
    ad: "Bakü",
    koord: [40.409, 49.867],
  },
  "BİŞKEK-KIRGIZİSTAN": {
    ulke: "kirgizistan",
    ad: "Bişkek",
    koord: [42.875, 74.603],
  },
  "TÜRKİSTAN-KAZAKİSTAN": {
    ulke: "kazakistan",
    ad: "Türkistan",
    koord: [43.297, 68.252],
  },
  "SARAYBOSNA - BOSNA - HERSEK": {
    ulke: "bosna-hersek",
    ad: "Saraybosna",
    koord: [43.856, 18.413],
  },
  ÜSKÜP: { ulke: "makedonya", ad: "Üsküp", koord: [41.997, 21.428] },
  TİRAN: { ulke: "arnavutluk", ad: "Tiran", koord: [41.328, 19.818] },
};

type SehirAnahtari = keyof typeof SEHIRLER;

/**
 * Kaynak verideki gürültü için üniversite adına göre düzeltme:
 * - Uluslararası Balkan Üniversitesi Üsküp'tedir; YÖK Atlas satırlarının
 *   çoğu il'i yanlışlıkla "SARAYBOSNA - BOSNA - HERSEK" der.
 * - Tiran New York Üniversitesi'nin il alanı boştur.
 * - ODTÜ ve ASBÜ'nün KKTC kampüs satırları vardır ama ana kampüs Türkiye'de;
 *   null → Türkiye haritasında kalır.
 * Anahtar: uniAdiNormalize edilmiş adın tr-TR büyük harf hali.
 */
const UNI_DUZELTME: Record<string, SehirAnahtari | null> = {
  "ULUSLARARASI BALKAN ÜNİVERSİTESİ": "ÜSKÜP",
  "TİRAN NEW YORK ÜNİVERSİTESİ": "TİRAN",
  "KIBRIS AYDIN ÜNİVERSİTESİ": "GİRNE", // il alanı yalnızca "KIBRIS"
  "ORTA DOĞU TEKNİK ÜNİVERSİTESİ": null,
  "ANKARA SOSYAL BİLİMLER ÜNİVERSİTESİ": null,
};

/** il değeri Türkiye dışını mı gösteriyor? ("KIBRIS" genel değeri dahil) */
const YURTDISI_IL = new Set([...Object.keys(SEHIRLER), "KIBRIS"]);

/**
 * Ad sonundaki "(KKTC-LEFKOŞA)" ekinden şehir anahtarı. YÖK Atlas'ta 100'den
 * fazla KKTC satırının il alanı şehir değil genel "KIBRIS"tır (Doğu Akdeniz,
 * Yakın Doğu, Lefke Avrupa, Uluslararası Final, Kıbrıs Sağlık ve Toplum
 * Bilimleri); şehir yalnızca üniversite adının parantezinde durur. Bu ek
 * okunmazsa o programlar hiçbir haritaya düşmez, "haritada gösterilemiyor"
 * sayısına yazılır.
 */
function ektenSehir(universite: string): SehirAnahtari | null {
  const ek = universite.match(/\(([^)]*)\)\s*$/)?.[1];
  if (!ek) return null;
  // "KKTC-GAZİMAĞUSA" → "GAZİMAĞUSA"; ülke öneki olmayan "(ANKARA)" gibi
  // ekler SEHIRLER'de karşılık bulmadığından kendiliğinden elenir.
  const sehir = ek.split("-").pop()!.trim().toLocaleUpperCase("tr-TR");
  return sehir in SEHIRLER ? (sehir as SehirAnahtari) : null;
}

/** Üniversite adı + il'den şehir anahtarı; şehri bilinmeyen KKTC'de ülke. */
type Cozum = { anahtar: SehirAnahtari } | { ulke: UlkeKodu } | null;

function coz(universite: string, il: string | null): Cozum {
  const ad = universite
    .replace(/\s*\([^)]*\)\s*$/, "")
    .trim()
    .toLocaleUpperCase("tr-TR");

  if (ad in UNI_DUZELTME) {
    const anahtar = UNI_DUZELTME[ad];
    return anahtar === null ? null : { anahtar };
  }
  if (!il || !YURTDISI_IL.has(il)) return null;
  if (il in SEHIRLER) return { anahtar: il as SehirAnahtari };
  // il "KIBRIS": ülke bilinir, şehir adın parantez ekinden okunur;
  // o da yoksa ülke seviyesinde kalır (şehir pini çizilemez)
  const ekSehir = ektenSehir(universite);
  return ekSehir ? { anahtar: ekSehir } : { ulke: "kktc" };
}

export type UlkeKonum = {
  ulke: UlkeKodu;
  ulkeAd: string;
  iso: string;
  harita: UlkeHarita;
  /** Şehir adı; genel "KIBRIS" gibi şehri bilinmeyen durumda null */
  sehir: string | null;
};

/**
 * Üniversite Türkiye dışındaysa ülke haritası + şehir adı döner;
 * Türkiye'deyse (veya çözülemiyorsa) null — Türkiye haritası kullanılır.
 */
export function uniUlkeKonum(
  universite: string,
  il: string | null,
): UlkeKonum | null {
  const cozum = coz(universite, il);
  if (!cozum) return null;
  const ulke = "anahtar" in cozum ? SEHIRLER[cozum.anahtar].ulke : cozum.ulke;
  const harita = ULKE_HARITALARI[ulke];
  return {
    ulke,
    ulkeAd: harita.ad,
    iso: ULKE_ISO[ulke],
    harita,
    sehir: "anahtar" in cozum ? SEHIRLER[cozum.anahtar].ad : null,
  };
}

/** Yurtdışı şehir merkezinin kendi ülke haritasındaki viewBox konumu. */
export type YurtdisiKonum = {
  ulke: UlkeKodu;
  ulkeAd: string;
  sehir: string;
  x: number;
  y: number;
};

function sehirKonumu(anahtar: SehirAnahtari): YurtdisiKonum {
  const sehir = SEHIRLER[anahtar];
  const { ad, proje } = ULKE_HARITALARI[sehir.ulke];
  const [lat, lng] = sehir.koord;
  return {
    ulke: sehir.ulke,
    ulkeAd: ad,
    sehir: sehir.ad,
    x: proje.ax * lng + proje.bx,
    y: proje.ay * lat + proje.by,
  };
}

/** Yurtdışı üniversitenin şehir konumu; şehir çözülemiyorsa null. */
export function yurtdisiUniKonum(
  universite: string,
  il: string | null,
): YurtdisiKonum | null {
  const cozum = coz(universite, il);
  return cozum && "anahtar" in cozum ? sehirKonumu(cozum.anahtar) : null;
}

/** Yalnızca il değerinden (kilitli satırlar) yurtdışı şehir konumu. */
export function yurtdisiIlKonum(il: string | null): YurtdisiKonum | null {
  return il && il in SEHIRLER ? sehirKonumu(il as SehirAnahtari) : null;
}
