/**
 * unitur (üniversite tipi) NULL onarımı + üniversite adı normalizasyonu.
 *
 * YÖK Atlas API'si bazı kayıtlarda universiteTuru döndürmüyor; DB'de ~2.081
 * satır unitur=NULL kalıyor ve bunlar hem devlet/vakıf filtrelerinden hem
 * sihirbaz sayaçlarından sessizce düşüyor. Onarım üç aşamalı:
 *
 *   A) Aynı üniversitenin dolu satırından kopyala (Nişantaşı, Beykent…)
 *   B) Kalanlarda il KKTC yerleşimiyse unitur='KKTC'
 *   C) Küçük manuel eşleme (Cerrahpaşa, MSB/İçişleri, Alanya, Manas…)
 *
 * Ayrıca "İSTANBUL ÜNİVERSİTESİ- CERRAHPAŞA" gibi tire etrafı boşluklu
 * duplikat adlar normalize edilir; refresh.ts insert yolunda da aynı
 * normalizasyon uygulanır ki duplikat bir daha oluşmasın.
 *
 * İdempotenttir; yalnızca NULL satırlara dokunur.
 *
 * Kullanım: npx tsx scripts/unitur-onar.ts   (dev sunucu KAPALIYKEN —
 * uygulama DB'yi readonly açar ama WAL checkpoint için tek yazar olmalı)
 */
import path from "node:path";
import Database from "better-sqlite3";

/** Tire etrafı boşluk + çift boşluk temizliği (üniversite adı için). */
export function uniAdiNormalize(ad: string): string {
  return ad.replace(/\s*-\s*/g, "-").replace(/\s{2,}/g, " ").trim();
}

const KKTC_ILLERI = [
  "GİRNE",
  "LEFKOŞA",
  "GAZİMAĞUSA",
  "LEFKE",
  "GÜZELYURT",
  "KIBRIS",
];

// Hiçbir satırında unitur olmayan ve il'den de çıkarılamayan kurumlar.
const MANUEL_UNITUR: Record<string, string> = {
  "İSTANBUL ÜNİVERSİTESİ-CERRAHPAŞA": "DEVLET",
  "İÇİŞLERİ BAKANLIĞI VE MİLLİ SAVUNMA BAKANLIĞI ADINA SAĞLIK BİLİMLERİ ÜNİVERSİTESİNDE EĞİTİM ALACAKLAR":
    "DEVLET",
  "ALANYA ÜNİVERSİTESİ": "VAKIF",
  "KIRGIZİSTAN-TÜRKİYE MANAS ÜNİVERSİTESİ": "YURTDISI KAMU",
  "HOCA AHMET YESEVİ ULUSLARARASI TÜRK-KAZAK ÜNİVERSİTESİ": "YURTDISI KAMU",
  "AZERBAYCAN DEVLET PEDAGOJİ ÜNİVERSİTESİ": "YURTDISI KAMU",
};

// İl'i hiç olmayan kampüsler için ad → il eşlemesi (yalnızca kesin olanlar).
const MANUEL_IL: Record<string, string> = {
  "İSTANBUL ÜNİVERSİTESİ-CERRAHPAŞA": "İSTANBUL",
};

export function uniturOnar(db: Database.Database): void {
  // 0) Üniversite adı normalizasyonu (Cerrahpaşa duplikatını birleştirir)
  const adlar = db
    .prepare("SELECT DISTINCT universite FROM programs")
    .all() as { universite: string }[];
  const adDuzelt = db.prepare(
    "UPDATE programs SET universite = ? WHERE universite = ?"
  );
  let duzeltilen = 0;
  for (const { universite } of adlar) {
    const temiz = uniAdiNormalize(universite);
    if (temiz !== universite) {
      adDuzelt.run(temiz, universite);
      duzeltilen++;
    }
  }
  if (duzeltilen > 0) console.log(`Ad normalizasyonu: ${duzeltilen} kurum`);

  // A) Aynı üniversitenin dolu satırından kopyala. Birden fazla FARKLI dolu
  // değer varsa sessizce seçim yapma — kaynak veride tutarsızlık demektir.
  const celiskiler = db
    .prepare(
      `SELECT universite, COUNT(DISTINCT unitur) AS n FROM programs
       WHERE unitur IS NOT NULL GROUP BY universite HAVING n > 1`
    )
    .all() as { universite: string; n: number }[];
  if (celiskiler.length > 0) {
    throw new Error(
      `Aynı üniversitede birden fazla unitur: ${celiskiler
        .map((c) => c.universite)
        .join(", ")} — önce kaynak veriyi kontrol et.`
    );
  }
  const aKopya = db
    .prepare(
      `UPDATE programs SET unitur = (
         SELECT p2.unitur FROM programs p2
         WHERE p2.universite = programs.universite AND p2.unitur IS NOT NULL
         LIMIT 1
       )
       WHERE unitur IS NULL AND EXISTS (
         SELECT 1 FROM programs p3
         WHERE p3.universite = programs.universite AND p3.unitur IS NOT NULL
       )`
    )
    .run();
  console.log(`Aşama A (üniversiteden kopya): ${aKopya.changes} satır`);

  // B) Kalan NULL'larda il KKTC yerleşimiyse
  const bKktc = db
    .prepare(
      `UPDATE programs SET unitur = 'KKTC'
       WHERE unitur IS NULL AND il IN (${KKTC_ILLERI.map(() => "?").join(",")})`
    )
    .run(...KKTC_ILLERI);
  console.log(`Aşama B (KKTC ili): ${bKktc.changes} satır`);

  // C) Manuel eşlemeler
  const cUnitur = db.prepare(
    "UPDATE programs SET unitur = ? WHERE unitur IS NULL AND universite = ?"
  );
  let cToplam = 0;
  for (const [ad, tur] of Object.entries(MANUEL_UNITUR)) {
    cToplam += cUnitur.run(tur, ad).changes;
  }
  console.log(`Aşama C (manuel): ${cToplam} satır`);

  const ilDuzelt = db.prepare(
    "UPDATE programs SET il = ? WHERE il IS NULL AND universite = ?"
  );
  let ilToplam = 0;
  for (const [ad, il] of Object.entries(MANUEL_IL)) {
    ilToplam += ilDuzelt.run(il, ad).changes;
  }
  if (ilToplam > 0) console.log(`İl doldurma (manuel): ${ilToplam} satır`);

  // Rapor: kalan NULL'lar
  const kalan = db
    .prepare(
      `SELECT universite, COUNT(*) AS adet FROM programs
       WHERE unitur IS NULL GROUP BY universite ORDER BY adet DESC`
    )
    .all() as { universite: string; adet: number }[];
  if (kalan.length === 0) {
    console.log("Kalan NULL unitur: 0 ✓");
  } else {
    console.log(`Kalan NULL unitur (${kalan.length} kurum):`);
    for (const k of kalan) console.log(`  ${k.universite}: ${k.adet}`);
  }
}

// Doğrudan koşulduğunda (npx tsx scripts/unitur-onar.ts)
if (process.argv[1]?.endsWith("unitur-onar.ts")) {
  const db = new Database(path.join(process.cwd(), "data", "yokatlas.db"));
  db.pragma("journal_mode = WAL");
  db.transaction(() => uniturOnar(db))();
  db.pragma("wal_checkpoint(TRUNCATE)");
  const dagilim = db
    .prepare(
      "SELECT COALESCE(unitur,'(NULL)') AS t, COUNT(*) AS n FROM programs GROUP BY unitur ORDER BY n DESC"
    )
    .all() as { t: string; n: number }[];
  console.log("Dağılım:", dagilim.map((d) => `${d.t}=${d.n}`).join(" "));
  db.close();
}
