<?php

// ==========================
// DB Ayarları (DOLDUR)
// ==========================
$DB_HOST = "localhost";
$DB_NAME = "univs";
$DB_USER = "root";
$DB_PASS = "Z15454drfdll8r8drtG";


// ==========================
// vendor/autoload.php bul (composer)
// ==========================
function find_vendor_autoload($startDir){
  $dir = $startDir;
  for ($i = 0; $i < 6; $i++){
    $candidate = $dir . '/vendor/autoload.php';
    if (is_file($candidate)) return $candidate;
    $parent = dirname($dir);
    if ($parent === $dir) break;
    $dir = $parent;
  }
  return null;
}

// Çıktı buffer'larını kapat (header/indirme bozulmasın)
function clean_all_output_buffers(){
  while (ob_get_level() > 0) { @ob_end_clean(); }
}


// ==========================
// Asset: PDF Türkçe font (DejaVu) - base64
// ==========================
// JS tarafında PDF üretirken Türkçe karakter sorunu yaşamamak için bu endpoint'ten font base64 çekilir.
// index.php?asset=dejavu_font
if (isset($_GET['asset']) && $_GET['asset'] === 'dejavu_font') {
  header('Content-Type: text/plain; charset=utf-8');
  $fontPath = '/usr/share/fonts/truetype/dejavu/DejaVuSansCondensed.ttf';
  if (!is_file($fontPath)) {
    http_response_code(404);
    echo '';
    exit;
  }
  header('Cache-Control: public, max-age=31536000');
  echo base64_encode(file_get_contents($fontPath));
  exit;
}


// ==========================
// PRINT VIEW (PDF/Yazdır)
// ==========================
// JS, seçilenleri JSON payload olarak POST eder. Bu sayfa da yazdırılabilir HTML üretir.
// PDF almak için tarayıcı yazdır ekranında "PDF olarak kaydet" seçilir.
// index.php?action=print   (POST: payload)
// index.php?action=print&autoprint=1  (POST: payload)
if (isset($_GET['action']) && $_GET['action'] === 'print') {
  header('Content-Type: text/html; charset=utf-8');

  $payload = '';
  if (isset($_POST['payload'])) $payload = $_POST['payload'];
  if ($payload === '' && isset($_GET['payload'])) $payload = $_GET['payload'];

  $data = json_decode($payload, true);
  if (!is_array($data)) {
    echo 'Hatalı veri (payload).';
    exit;
  }

  $ogLabel = isset($data['ogLabel']) ? (string)$data['ogLabel'] : '';
  $rows = (isset($data['rows']) && is_array($data['rows'])) ? $data['rows'] : [];
  $autoprint = (isset($_GET['autoprint']) && $_GET['autoprint'] == '1');

  $h = function($s){
    return htmlspecialchars((string)$s, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
  };

  // Açıklamalar metni (örnek PDF ile aynı)
  $aciklama1 = "SARIYLA RENKLENDİRİLEN KADROLAR YERLEŞMENİZİN RİSKLİ OLDUĞU KADROLARDIR. ANCAK ÇOK İSTİYORSANIZ TERCİH LİSTENİZE YAZMANIZDA YARAR VARDIR";
  $aciklama2 = "Yeni açılan kadroların taban puanları oluşmadığı için tercihlerinizde dikkat ediniz.";
  $aciklama3 = "Tüm veriler ÖSYM kaynaklı verilerdir.";

  echo "<!doctype html><html><head><meta charset='utf-8'><title>TercihSepeti</title>";
  echo "<style>
    @page { size: A4; margin: 18mm; }
    body { font-family: Arial, Helvetica, sans-serif; color:#000; }
    .top { font-size: 12px; margin: 0 0 12px; }
    table { width: 100%; border-collapse: collapse; table-layout: fixed; font-size: 10px; }
    th, td { border: 1px solid #000; padding: 6px; vertical-align: top; }
    th { font-weight: normal; }
    .col-sira { width: 40px; }
    .col-kadro { width: auto; }
    .col-n { width: 85px; }
    .col-kont { width: 90px; }
    .kadro { white-space: normal; word-break: break-word; line-height: 1.2; }
    .risk { background: #fff2a8; }
    .aciklama-title { margin: 14px 0 6px; font-size: 11px; font-weight: bold; }
    .aciklama { font-size: 9.5px; line-height: 1.35; }
    .toolbar { margin: 0 0 10px; display:flex; gap:8px; align-items:center; }
    .btn { border:1px solid #333; padding:6px 10px; border-radius:6px; background:#f5f5f5; cursor:pointer; font-size:12px; }
    .hint { font-size: 11px; color:#333; }
    @media print { .toolbar { display:none; } }
  

/* Export errors */
.export-error{
  margin-top: 10px;
  padding: 10px 12px;
  border: 1px solid #f2c9c9;
  background: #fff3f3;
  color: #7a1f1f;
  border-radius: 10px;
  font-size: 14px;
  line-height: 1.35;
}

/* Print area (same page print, no new tab) */
.print-area{ display:block; }
@media print{
  body *{ visibility: hidden !important; }
  #printArea, #printArea *{ visibility: visible !important; }
  #printArea{
    position: fixed;
    left: 0; top: 0;
    width: 100%;
    padding: 0;
  }
}
</style></head><body>";

  echo "<div class='toolbar'>
          <button class='btn' onclick='window.print()'>Yazdır / PDF Kaydet</button>
          <span class='hint'>PDF için: Yazdır &gt; PDF olarak kaydet</span>
        </div>";

  echo "<div class='top'>Öğrenim Durumu : " . $h($ogLabel) . "</div>";

  echo "<table><thead><tr>
        <th class='col-sira'>Sıra</th>
        <th class='col-kadro'>Kadro</th>
        <th class='col-n'>Taban Puan</th>
        <th class='col-n'>Adayın<br>Puanı</th>
        <th class='col-kont'>Kontenjan</th>
      </tr></thead><tbody>";

  $i = 0;
  foreach ($rows as $r) {
    $i++;
    $sira = isset($r['sira']) ? $r['sira'] : $i;
    $kadro = isset($r['kadro']) ? (string)$r['kadro'] : '';
    $taban = isset($r['taban']) ? (string)$r['taban'] : '';
    $aday  = isset($r['aday']) ? (string)$r['aday'] : '';
    $kont  = isset($r['kont']) ? (string)$r['kont'] : '';
    $risk  = !empty($r['risk']);

    // Kadro hücresinde satır sonlarını koru
    $kadroHtml = nl2br($h($kadro), false);

    echo "<tr class='".($risk ? "risk" : "")."'>
            <td>".$h($sira)."</td>
            <td><div class='kadro'>".$kadroHtml."</div></td>
            <td>".$h($taban)."</td>
            <td>".$h($aday)."</td>
            <td>".$h($kont)."</td>
          </tr>";
  }

  echo "</tbody></table>";

  echo "<div class='aciklama-title'>Açıklamalar</div>";
  echo "<div class='aciklama'>"
        . $h($aciklama1) . "<br>"
        . $h($aciklama2) . "<br>"
        . $h($aciklama3) .
       "</div>";

  if ($autoprint) {
    echo "<script>setTimeout(()=>{try{window.print();}catch(e){}}, 250);</script>";
  }

  echo "</body></html>";
  exit;
}


// ==========================
// DOWNLOAD PDF (Gerçek PDF - direkt indir)
// ==========================
// index.php?action=download_pdf  (POST: payload {ogLabel, rows[]})
if (isset($_GET['action']) && $_GET['action'] === 'download_pdf') {
  // Not: Bu özellik için mPDF gerekir. (composer require mpdf/mpdf)
  $payload = '';
  if (isset($_POST['payload'])) $payload = $_POST['payload'];
  if ($payload === '' && isset($_GET['payload'])) $payload = $_GET['payload'];

  $data = json_decode($payload, true);
  if (!is_array($data)) {
    header('Content-Type: text/plain; charset=utf-8');
    echo "Hatalı veri (payload).";
    exit;
  }

  $vendor = find_vendor_autoload(__DIR__);
  if (!$vendor) {
    header('Content-Type: text/plain; charset=utf-8');
    echo "vendor/autoload.php bulunamadı.\n\nComposer komutunu index.php'nin bulunduğu dizinde çalıştır:\n\ncomposer require mpdf/mpdf phpoffice/phpspreadsheet\n";
    exit;
  }
  require_once $vendor;

  if (!class_exists('\Mpdf\Mpdf')) {
    header('Content-Type: text/plain; charset=utf-8');
    echo "mPDF bulunamadı. Kurulum: composer require mpdf/mpdf";
    exit;
  }

  $ogLabel = isset($data['ogLabel']) ? (string)$data['ogLabel'] : '';
  $rows = (isset($data['rows']) && is_array($data['rows'])) ? $data['rows'] : [];

  $h = function($s){
    return htmlspecialchars((string)$s, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
  };

  // Örnek PDF ile aynı açıklamalar
  $aciklama1 = "SARIYLA RENKLENDİRİLEN KADROLAR YERLEŞMENİZİN RİSKLİ OLDUĞU KADROLARDIR. ANCAK ÇOK İSTİYORSANIZ TERCİH LİSTENİZE YAZMANIZDA YARAR VARDIR";
  $aciklama2 = "Yeni açılan kadroların taban puanları oluşmadığı için tercihlerinizde dikkat ediniz.";
  $aciklama3 = "Tüm veriler ÖSYM kaynaklı verilerdir.";

  $css = "
    @page { margin: 18mm; }
    body { font-family: dejavusans, DejaVu Sans, sans-serif; color:#000; }
    .top { font-size: 12pt; margin: 0 0 10pt; }
    table { width: 100%; border-collapse: collapse; table-layout: fixed; font-size: 9.5pt; }
    th, td { border: 1px solid #000; padding: 6pt; vertical-align: top; }
    th { font-weight: normal; }
    .col-sira { width: 12mm; }
    .col-n { width: 26mm; }
    .col-kont { width: 26mm; }
    .kadro { white-space: normal; word-wrap: break-word; word-break: break-word; line-height: 1.25; }
    .risk { background: #fff2a8; }
    .aciklama-title { margin: 10pt 0 5pt; font-size: 10.5pt; font-weight: bold; }
    .aciklama { font-size: 9pt; line-height: 1.35; }
  ";

  $html = "<!doctype html><html><head><meta charset='utf-8'><style>{$css}</style></head><body>";
  $html .= "<div class='top'>Öğrenim Durumu : ".$h($ogLabel)."</div>";
  $html .= "<table><thead><tr>
              <th class='col-sira'>Sıra</th>
              <th>Kadro</th>
              <th class='col-n'>Taban Puan</th>
              <th class='col-n'>Adayın<br>Puanı</th>
              <th class='col-kont'>Kontenjan</th>
            </tr></thead><tbody>";

  $i = 0;
  foreach ($rows as $r) {
    $i++;
    $sira = isset($r['sira']) ? $r['sira'] : $i;
    $kadro = isset($r['kadro']) ? (string)$r['kadro'] : '';
    $taban = isset($r['taban']) ? (string)$r['taban'] : '';
    $aday  = isset($r['aday']) ? (string)$r['aday'] : '';
    $kont  = isset($r['kont']) ? (string)$r['kont'] : '';
    $risk  = !empty($r['risk']);

    // satır sonlarını <br> olarak koru
    $kadroHtml = nl2br($h($kadro), false);

    $html .= "<tr class='".($risk ? "risk" : "")."'>
                <td>".$h($sira)."</td>
                <td><div class='kadro'>{$kadroHtml}</div></td>
                <td>".$h($taban)."</td>
                <td>".$h($aday)."</td>
                <td>".$h($kont)."</td>
              </tr>";
  }

  $html .= "</tbody></table>";
  $html .= "<div class='aciklama-title'>Açıklamalar</div>";
  $html .= "<div class='aciklama'>".$h($aciklama1)."<br>".$h($aciklama2)."<br>".$h($aciklama3)."</div>";
  $html .= "</body></html>";

  try {
    // mPDF
    $mpdf = new \Mpdf\Mpdf([
      'mode' => 'utf-8',
      'format' => 'A4',
      'orientation' => 'P',
      'margin_left' => 18,
      'margin_right' => 18,
      'margin_top' => 18,
      'margin_bottom' => 18,
      'default_font' => 'dejavusans',
      'tempDir' => sys_get_temp_dir()
    ]);
    $mpdf->autoLangToFont = true;
    $mpdf->autoScriptToLang = true;
    $mpdf->WriteHTML($html);

    // Direkt indir
    $filename = "TercihSepeti.pdf";
    // Bazı sunucularda önceki output buffer sorun çıkarabilir:
    clean_all_output_buffers();
    $mpdf->Output($filename, \Mpdf\Output\Destination::DOWNLOAD);
  } catch (Throwable $e) {
    header('Content-Type: text/plain; charset=utf-8');
    echo "PDF üretilemedi: " . $e->getMessage();
  }
  exit;
}


// ==========================
// DOWNLOAD XLSX (Gerçek Excel - .xlsx)
// ==========================
// index.php?action=download_xlsx (POST: payload {headers[], rows[][]})
if (isset($_GET['action']) && $_GET['action'] === 'download_xlsx') {
  // Not: Bu özellik için PhpSpreadsheet gerekir. (composer require phpoffice/phpspreadsheet)
  $payload = '';
  if (isset($_POST['payload'])) $payload = $_POST['payload'];
  if ($payload === '' && isset($_GET['payload'])) $payload = $_GET['payload'];

  $data = json_decode($payload, true);
  if (!is_array($data)) {
    header('Content-Type: text/plain; charset=utf-8');
    echo "Hatalı veri (payload).";
    exit;
  }

  $vendor = find_vendor_autoload(__DIR__);
  if (!$vendor) {
    header('Content-Type: text/plain; charset=utf-8');
    echo "vendor/autoload.php bulunamadı.\n\nComposer komutunu index.php'nin bulunduğu dizinde çalıştır:\n\ncomposer require mpdf/mpdf phpoffice/phpspreadsheet\n";
    exit;
  }
  require_once $vendor;

  if (!class_exists('\PhpOffice\PhpSpreadsheet\Spreadsheet')) {
    header('Content-Type: text/plain; charset=utf-8');
    echo "PhpSpreadsheet bulunamadı. Kurulum: composer require phpoffice/phpspreadsheet";
    exit;
  }

  $headers = (isset($data['headers']) && is_array($data['headers'])) ? $data['headers'] : [];
  $rows = (isset($data['rows']) && is_array($data['rows'])) ? $data['rows'] : [];

  try {
    $spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
    $sheet = $spreadsheet->getActiveSheet();
    $sheet->setTitle('Secilenler');

    // Header
    $col = 1;
    // PhpSpreadsheet v2+ may not expose setCellValueByColumnAndRow on Worksheet.
    // Use A1-style coordinates instead.
    foreach ($headers as $h) {
      $cellAddr = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($col) . '1';
      $sheet->setCellValue($cellAddr, (string)$h);
      $col++;
    }

    // Data
    $r = 2;
    foreach ($rows as $row) {
      if (!is_array($row)) continue;
      $c = 1;
      foreach ($row as $cell) {
        $cellAddr = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($c) . (string)$r;
        $sheet->setCellValue($cellAddr, (string)$cell);
        $c++;
      }
      $r++;
    }

    // Stil (basit)
    $lastCol = max(1, count($headers));
    $lastRow = max(1, $r - 1);
    $range = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($lastCol) . $lastRow;

    // Kalın header + wrap
    $sheet->getStyle('A1:' . \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($lastCol) . '1')
          ->getFont()->setBold(true);
    $sheet->getStyle('A1:' . $range)->getAlignment()->setWrapText(true);
    // Otomatik genişlik
    for ($i = 1; $i <= $lastCol; $i++){
      $sheet->getColumnDimensionByColumn($i)->setAutoSize(true);
    }

    $filename = 'secilen_kadrolar.xlsx';

    // Headers for download
    clean_all_output_buffers();
    clean_all_output_buffers();
    header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
    header('Content-Disposition: attachment; filename="'.$filename.'"');
    header('Cache-Control: max-age=0');
    header('Pragma: public');

    $writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
    $writer->save('php://output');
  } catch (Throwable $e) {
    header('Content-Type: text/plain; charset=utf-8');
    echo "Excel üretilemedi: " . $e->getMessage();
  }
  exit;
}


// Debug: URL'e ?debug=1 eklersen hata detayları JSON'da döner.
$DEBUG = (isset($_GET['debug']) && $_GET['debug'] == '1');
// ==========================
// PDO Bağlantısı
// ==========================
function db_pdo($DB_HOST, $DB_NAME, $DB_USER, $DB_PASS) {
  $dsn = "mysql:host={$DB_HOST};dbname={$DB_NAME};charset=utf8mb4";
  $opt = [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES => false,
  ];
  return new PDO($dsn, $DB_USER, $DB_PASS, $opt);
}

function tr_normalize_compare_text($value){
  $value = trim((string)$value);
  if ($value === '') return '';

  $value = strtr($value, [
    'Ç' => 'c', 'ç' => 'c',
    'Ğ' => 'g', 'ğ' => 'g',
    'İ' => 'i', 'I' => 'i', 'ı' => 'i',
    'Ö' => 'o', 'ö' => 'o',
    'Ş' => 's', 'ş' => 's',
    'Ü' => 'u', 'ü' => 'u',
  ]);

  if (function_exists('mb_strtolower')) $value = mb_strtolower($value, 'UTF-8');
  else $value = strtolower($value);

  $value = preg_replace('/\s+/u', ' ', $value);
  return trim($value);
}

function tr_sql_normalize_expr($expr){
  $expr = "LOWER(TRIM(CONVERT({$expr} USING utf8mb4)))";
  $pairs = [
    'Ç' => 'c', 'ç' => 'c',
    'Ğ' => 'g', 'ğ' => 'g',
    'İ' => 'i', 'I' => 'i', 'ı' => 'i',
    'Ö' => 'o', 'ö' => 'o',
    'Ş' => 's', 'ş' => 's',
    'Ü' => 'u', 'ü' => 'u',
  ];

  foreach($pairs as $from => $to){
    $expr = "REPLACE({$expr}, '" . str_replace("'", "''", $from) . "', '" . str_replace("'", "''", $to) . "')";
  }

  return $expr;
}

// ==========================
// AJAX: Mezuniyet alanlarını getir (lazy-load + arama)
// ==========================
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['ajax']) && ($_POST['ajax'] === 'mezun_alan' || $_POST['ajax'] === 'mezun_alan_all')) {
  header('Content-Type: application/json; charset=utf-8');

  $isAll = ($_POST['ajax'] === 'mezun_alan_all');


  $ogrenim = isset($_POST['ogrenim']) ? trim((string)$_POST['ogrenim']) : '';
  $q = isset($_POST['q']) ? trim((string)$_POST['q']) : '';
  $offset = $isAll ? 0 : (isset($_POST['offset']) ? max(0, (int)$_POST['offset']) : 0);
  $limit  = $isAll ? 5000 : (isset($_POST['limit']) ? (int)$_POST['limit'] : 40);
  if (!$isAll){
    if ($limit < 10) $limit = 10;
    if ($limit > 80) $limit = 80;
  }

  // Güvenlik: izinli öğrenim değerleri
  $table = '';
  if ($ogrenim === 'onlisans') $table = 'onlisansmezunalan';
  if ($ogrenim === 'lisans') $table = 'lisansmezunalan';
  if ($ogrenim === 'ortaogretim') $table = 'ortamezunalan';

  if ($table === '') {
    echo json_encode(['ok' => false, 'error' => 'Geçersiz öğrenim durumu.'], JSON_UNESCAPED_UNICODE);
    exit;
  }

  // Kolon adlarını normalize etmek için (Alan Adı / Alan Adi gibi farklar)
  $tr_map = [
    'ı' => 'i', 'İ' => 'i', 'ş' => 's', 'Ş' => 's', 'ğ' => 'g', 'Ğ' => 'g',
    'ü' => 'u', 'Ü' => 'u', 'ö' => 'o', 'Ö' => 'o', 'ç' => 'c', 'Ç' => 'c',
  ];
  $normalize = function($s) use ($tr_map) {
    $s = strtr((string)$s, $tr_map);
    if (function_exists('mb_strtolower')) $s = mb_strtolower($s, 'UTF-8');
    else $s = strtolower($s);
    $s = preg_replace('/\s+/', '', $s);
    $s = preg_replace('/[^a-z0-9_]/', '', $s);
    return $s;
  };

  try {
    $pdo = db_pdo($DB_HOST, $DB_NAME, $DB_USER, $DB_PASS);

    // Uygun collation seç (Türkçe varsa onu kullan)
    $collation = 'utf8mb4_turkish_ci';
    $colOk = $pdo->query("SHOW COLLATION LIKE 'utf8mb4_turkish_ci'")->fetch();
    if (!$colOk) $collation = 'utf8mb4_general_ci';

    // Kolonları bul
    $cols = [];
    $colRows = $pdo->query("SHOW COLUMNS FROM `{$table}`")->fetchAll();
    foreach ($colRows as $r) {
      $field = isset($r['Field']) ? (string)$r['Field'] : '';
      if ($field !== '') $cols[$normalize($field)] = $field;
    }

    $candidates_code = ['kod','kodu','code','alankod','alankodu','alankodlari','alankodları','alankod_','alan_kod','alankod','alankod'];
    $candidates_name = ['ad','adi','name','alanadi','alanadi','alanadi_deger','alan','alanadi'];
    // Ortaöğretim özel
    if ($table === 'ortamezunalan') {
      $candidates_code = array_merge(['alankod','alankodu','alankodlari','alan_kod','akod'], $candidates_code);
      $candidates_name = array_merge(['alanadi','alanadı','alan_adi','alanadi'], $candidates_name);
    }

    $pickCol = function($cands) use ($cols) {
      foreach ($cands as $c) {
        if (isset($cols[$c])) return $cols[$c];
      }
      return '';
    };

    $codeCol = $pickCol($candidates_code);
    $nameCol = $pickCol($candidates_name);

    // Son çare: "alan kod" / "alan adı" gibi alanlar
    if ($codeCol === '' || $nameCol === '') {
      foreach ($cols as $norm => $origField) {
        if ($codeCol === '' && strpos($norm, 'kod') !== false) $codeCol = $origField;
        if ($nameCol === '' && (strpos($norm, 'adi') !== false || strpos($norm, 'ad') === 0 || strpos($norm, 'name') !== false)) $nameCol = $origField;
      }
    }

    if ($codeCol === '' || $nameCol === '') {
      echo json_encode(['ok' => false, 'error' => 'Kolonlar bulunamadı. (Kod/Ad veya Alan Kod/Alan Adı)'], JSON_UNESCAPED_UNICODE);
      exit;
    }

    $whereSql = '';
    $params = [];
    if ($q !== '') {
      // Büyük/küçük harf duyarsız + Türkçe uyumlu
      $whereSql = " WHERE (CONVERT(`{$codeCol}` USING utf8mb4) COLLATE {$collation} LIKE :q1 OR CONVERT(`{$nameCol}` USING utf8mb4) COLLATE {$collation} LIKE :q2)";
      $params[':q1'] = '%' . $q . '%';
      $params[':q2'] = '%' . $q . '%';
    }

    // Total
    $stmtTotal = $pdo->prepare("SELECT COUNT(*) AS cnt FROM `{$table}`{$whereSql}");
    $stmtTotal->execute($params);
    $total = (int)($stmtTotal->fetchColumn() ?? 0);

    // Page
    $sql = "SELECT `{$codeCol}` AS code, `{$nameCol}` AS name
            FROM `{$table}`{$whereSql}
            ORDER BY `{$nameCol}` ASC
            LIMIT :limit OFFSET :offset";
    $stmt = $pdo->prepare($sql);
    foreach ($params as $k => $v) $stmt->bindValue($k, $v, PDO::PARAM_STR);
    $stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
    $stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
    $stmt->execute();
    $rows = $stmt->fetchAll();

    $items = [];
    foreach ($rows as $row) {
      $code = isset($row['code']) ? trim((string)$row['code']) : '';
      $name = isset($row['name']) ? trim((string)$row['name']) : '';
      if ($code === '' && $name === '') continue;
      $items[] = ['code' => $code, 'name' => $name];
    }

    $nextOffset = $offset + count($items);
    $hasMore = $nextOffset < $total;

    echo json_encode([
      'ok' => true,
      'items' => $items,
      'total' => $total,
      'nextOffset' => $nextOffset,
      'hasMore' => $hasMore,
    ], JSON_UNESCAPED_UNICODE);
    exit;

  } catch (Throwable $e) {
    echo json_encode(['ok' => false, 'error' => 'Veritabanı hatası: ' . $e->getMessage()], JSON_UNESCAPED_UNICODE);
    exit;
  }
}



// ==========================
// AJAX: Kadro Ünvanı (İL seçimine göre - sadece kadrolar tablosu)
// ==========================
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['ajax']) && $_POST['ajax'] === 'kadro_unvan') {
  header('Content-Type: application/json; charset=utf-8');

  $ogrenim = isset($_POST['ogrenim']) ? trim((string)$_POST['ogrenim']) : '';
  $cities  = isset($_POST['cities']) && is_array($_POST['cities']) ? $_POST['cities'] : [];

  $ogMap = [
    'lisans'      => 'Lisans',
    'onlisans'    => 'Önlisans',
    'ortaogretim' => 'Ortaöğretim',
  ];
  $ogDb = isset($ogMap[$ogrenim]) ? $ogMap[$ogrenim] : '';

  if ($ogDb === '') {
    echo json_encode(['ok' => false, 'error' => 'Geçersiz öğrenim durumu.'], JSON_UNESCAPED_UNICODE);
    exit;
  }

  // Şehirleri temizle
  $cities = array_values(array_filter(array_map(function($c){
    $c = trim((string)$c);
    if ($c === '' || mb_strlen($c, 'UTF-8') > 64) return '';
    return $c;
  }, $cities)));
  $normalizedCities = array_values(array_filter(array_unique(array_map('tr_normalize_compare_text', $cities))));

  if (count($normalizedCities) === 0) {
    echo json_encode(['ok' => true, 'items' => []], JSON_UNESCAPED_UNICODE);
    exit;
  }

  try{
    $pdo = db_pdo($DB_HOST, $DB_NAME, $DB_USER, $DB_PASS);

    $table = 'kadrolar';
    $qTable = $pdo->quote($table);
    $exists = $pdo->query("SHOW TABLES LIKE $qTable")->fetchColumn();
    if (!$exists){
      echo json_encode(['ok' => false, 'error' => 'Tablo bulunamadı: ' . $table], JSON_UNESCAPED_UNICODE);
      exit;
    }

    $cols = $pdo->query("SHOW COLUMNS FROM `$table`")->fetchAll(PDO::FETCH_COLUMN, 0);
    $colMap = [];
    foreach($cols as $c){
      $colMap[mb_strtolower((string)$c, 'UTF-8')] = $c;
    }

    $pickCol = function(array $cands) use ($colMap){
      foreach($cands as $cand){
        $k = mb_strtolower((string)$cand, 'UTF-8');
        if (isset($colMap[$k])) return $colMap[$k];
      }
      return '';
    };

    $colOg = $pickCol(['OgrenimDurumu','ÖğrenimDurumu','OGRENIMDURUMU','OGRENIM_DURUMU']);
    $colIL = $pickCol(['IlAdi','İlAdi','ILADI','IL_ADI','İL_ADI','IL','İL','SEHIR','ŞEHİR','SEHIR_ADI','ŞEHİR_ADI']);
    $colK  = $pickCol(['KadroUnvani','KADROUNVANI','KADRO_UNVANI','KADRO UNVANI','KADRO','UNVAN','KADRO_ADI','KADROADI']);

    if ($colOg === '' || $colIL === '' || $colK === ''){
      $missing = [];
      if ($colOg === '') $missing[] = 'OgrenimDurumu';
      if ($colIL === '') $missing[] = 'IlAdi';
      if ($colK === '')  $missing[] = 'KadroUnvani';
      echo json_encode([
        'ok' => false,
        'error' => 'Kadrolar tablosunda gerekli kolon bulunamadı: ' . implode(', ', $missing) . '. Bulunan kolonlar: ' . implode(', ', $cols)
      ], JSON_UNESCAPED_UNICODE);
      exit;
    }

    $collation = 'utf8mb4_turkish_ci';
    $colOk = $pdo->query("SHOW COLLATION LIKE 'utf8mb4_turkish_ci'")->fetch();
    if (!$colOk) $collation = 'utf8mb4_general_ci';

    $phC = implode(',', array_fill(0, count($normalizedCities), '?'));
    $cityExpr = tr_sql_normalize_expr("`$colIL`");

    $sql = "SELECT DISTINCT `$colK` AS kadro
            FROM `$table`
            WHERE CONVERT(`$colOg` USING utf8mb4) COLLATE $collation = ?
              AND {$cityExpr} IN ($phC)
              AND TRIM(COALESCE(`$colK`, '')) <> ''
            ORDER BY CONVERT(`$colK` USING utf8mb4) COLLATE $collation ASC";

    $vals = array_merge([$ogDb], $normalizedCities);
    $st = $pdo->prepare($sql);
    $i = 1;
    foreach($vals as $v){
      $st->bindValue($i, (string)$v, PDO::PARAM_STR);
      $i++;
    }
    $st->execute();

    $items = [];
    while ($row = $st->fetch(PDO::FETCH_ASSOC)) {
      $u = isset($row['kadro']) ? trim((string)$row['kadro']) : '';
      if ($u === '') continue;
      $items[] = $u;
    }

    echo json_encode(['ok' => true, 'items' => $items], JSON_UNESCAPED_UNICODE);
    exit;

  } catch (Throwable $e){
    if (!empty($DEBUG)){
      echo json_encode(['ok' => false, 'error' => 'Veritabanı hatası: ' . $e->getMessage()], JSON_UNESCAPED_UNICODE);
    } else {
      echo json_encode(['ok' => false, 'error' => 'Veritabanı hatası.'], JSON_UNESCAPED_UNICODE);
    }
    exit;
  }
}




// ==========================
// AJAX: Kadro Nitelik Kodları (Step5) - sadece kadrolar tablosu
// ==========================
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['ajax']) && $_POST['ajax'] === 'kadro_nitelikler') {
  header('Content-Type: application/json; charset=utf-8');

  $ogrenim  = isset($_POST['ogrenim']) ? trim((string)$_POST['ogrenim']) : '';
  $cities   = (isset($_POST['cities']) && is_array($_POST['cities'])) ? $_POST['cities'] : [];
  $unvanlar = (isset($_POST['unvanlar']) && is_array($_POST['unvanlar'])) ? $_POST['unvanlar'] : [];

  $ogMap = [
    'lisans'      => 'Lisans',
    'onlisans'    => 'Önlisans',
    'ortaogretim' => 'Ortaöğretim',
  ];
  $ogDb = isset($ogMap[$ogrenim]) ? $ogMap[$ogrenim] : '';

  $cities = array_values(array_filter(array_map(function($c){
    $c = trim((string)$c);
    if ($c === '' || mb_strlen($c, 'UTF-8') > 64) return '';
    return $c;
  }, $cities)));
  $unvanlar = array_values(array_filter(array_unique(array_map(function($u){
    $u = trim((string)$u);
    if ($u === '' || mb_strlen($u, 'UTF-8') > 190) return '';
    return $u;
  }, $unvanlar))));
  $normalizedCities = array_values(array_filter(array_unique(array_map('tr_normalize_compare_text', $cities))));

  if ($ogDb === '') {
    echo json_encode(['ok' => false, 'error' => 'Geçersiz öğrenim durumu.'], JSON_UNESCAPED_UNICODE);
    exit;
  }
  if (count($unvanlar) === 0) {
    echo json_encode(['ok' => true, 'nit_max' => 0, 'items' => []], JSON_UNESCAPED_UNICODE);
    exit;
  }

  try {
    $pdo = db_pdo($DB_HOST, $DB_NAME, $DB_USER, $DB_PASS);

    $table = 'kadrolar';
    $stmt = $pdo->query("SHOW TABLES LIKE " . $pdo->quote($table));
    $exists = $stmt->fetchColumn();
    if (!$exists){
      echo json_encode(['ok' => false, 'error' => 'Tablo bulunamadı: ' . $table], JSON_UNESCAPED_UNICODE);
      exit;
    }

    $cols = $pdo->query("SHOW COLUMNS FROM `$table`")->fetchAll(PDO::FETCH_COLUMN, 0);
    $colMap = [];
    foreach($cols as $c){
      $colMap[mb_strtolower((string)$c, 'UTF-8')] = $c;
    }
    $pickCol = function(array $cands) use ($colMap){
      foreach($cands as $cand){
        $k = mb_strtolower((string)$cand, 'UTF-8');
        if (isset($colMap[$k])) return $colMap[$k];
      }
      return '';
    };

    $colOg  = $pickCol(['OgrenimDurumu','ÖğrenimDurumu','OGRENIMDURUMU','OGRENIM_DURUMU']);
    $colIL  = $pickCol(['IlAdi','İlAdi','ILADI','IL_ADI','İL_ADI','IL','İL','SEHIR','ŞEHİR','SEHIR_ADI','ŞEHİR_ADI']);
    $colK   = $pickCol(['KadroUnvani','KADROUNVANI','KADRO_UNVANI','KADRO UNVANI','KADRO','UNVAN','KADRO_ADI','KADROADI']);
    $colNit = $pickCol(['NitelikKodlari','NITELIKKODLARI','NITELIK_KODLARI']);

    if ($colOg === '' || $colK === '' || $colNit === ''){
      $missing = [];
      if ($colOg === '')  $missing[] = 'OgrenimDurumu';
      if ($colK === '')   $missing[] = 'KadroUnvani';
      if ($colNit === '') $missing[] = 'NitelikKodlari';
      echo json_encode([
        'ok' => false,
        'error' => 'Kadrolar tablosunda gerekli kolon bulunamadı: ' . implode(', ', $missing) . '. Bulunan kolonlar: ' . implode(', ', $cols)
      ], JSON_UNESCAPED_UNICODE);
      exit;
    }

    $collation = 'utf8mb4_turkish_ci';
    $colOk = $pdo->query("SHOW COLLATION LIKE 'utf8mb4_turkish_ci'")->fetch();
    if (!$colOk) $collation = 'utf8mb4_general_ci';

    $where = [];
    $vals  = [];

    $where[] = "CONVERT(`$colOg` USING utf8mb4) COLLATE $collation = ?";
    $vals[]  = $ogDb;

    if (count($normalizedCities) > 0 && $colIL !== ''){
      $phC = implode(',', array_fill(0, count($normalizedCities), '?'));
      $cityExpr = tr_sql_normalize_expr("`$colIL`");
      $where[] = "{$cityExpr} IN ($phC)";
      $vals = array_merge($vals, $normalizedCities);
    }

    $phU = implode(',', array_fill(0, count($unvanlar), '?'));
    $where[] = "CONVERT(`$colK` USING utf8mb4) COLLATE $collation IN ($phU)";
    $vals = array_merge($vals, $unvanlar);

    $sql = "SELECT `$colK` AS kadro, `$colNit` AS nitelik_kodlari
            FROM `$table`
            WHERE " . implode(' AND ', $where);

    $st = $pdo->prepare($sql);
    $i = 1;
    foreach($vals as $v){
      $st->bindValue($i, (string)$v, PDO::PARAM_STR);
      $i++;
    }
    $st->execute();

    $normalizeNitCodes = function($raw){
      $raw = trim((string)$raw);
      if ($raw === '') return [];
      $parts = preg_split('/[^0-9]+/', $raw);
      $out = [];
      foreach((array)$parts as $p){
        $p = preg_replace('/[^0-9]/', '', (string)$p);
        if ($p === '') continue;
        $out[$p] = true;
      }
      return array_keys($out);
    };

    $out = [];
    $seen = [];
    while ($row = $st->fetch(PDO::FETCH_ASSOC)) {
      $u = isset($row['kadro']) ? trim((string)$row['kadro']) : '';
      if ($u === '') continue;

      if (!isset($out[$u]))  $out[$u] = [];
      if (!isset($seen[$u])) $seen[$u] = [];

      $codes = $normalizeNitCodes($row['nitelik_kodlari'] ?? '');
      foreach($codes as $code){
        if (!isset($seen[$u][$code])){
          $seen[$u][$code] = true;
          $out[$u][] = $code;
        }
      }
    }

    $allCodes = [];
    $allSeen = [];
    foreach ($out as $uu => $codesArr){
      foreach($codesArr as $c){
        if ($c === '' || isset($allSeen[$c])) continue;
        $allSeen[$c] = true;
        $allCodes[] = $c;
      }
    }

    $nitTable = '';
    $nitTables = ['NitelikKodlari','nitelikkodlari','nitelik_kodlari','nitelik','nitelikler','nitelik_kodu','nitelikKodu'];
    foreach($nitTables as $t){
      $stmtT = $pdo->query("SHOW TABLES LIKE " . $pdo->quote($t));
      if ($stmtT->fetchColumn()){
        $nitTable = $t;
        break;
      }
    }
    if ($nitTable === ''){
      echo json_encode(['ok' => false, 'error' => 'Nitelik tablosu bulunamadı (Kodu/Nitelik).'], JSON_UNESCAPED_UNICODE);
      exit;
    }

    $ncols = $pdo->query("SHOW COLUMNS FROM `$nitTable`")->fetchAll(PDO::FETCH_COLUMN, 0);
    $nMap = [];
    foreach($ncols as $c){
      $nMap[mb_strtolower((string)$c, 'UTF-8')] = $c;
    }
    $pickNCol = function(array $cands) use ($nMap){
      foreach($cands as $cand){
        $k = mb_strtolower((string)$cand, 'UTF-8');
        if (isset($nMap[$k])) return $nMap[$k];
      }
      return '';
    };

    $codeCol = $pickNCol(['Kodu','KODU','Kod','KOD','CODE','Code']);
    $nameCol = $pickNCol(['Nitelik','NITELIK','NitelikMetni','NITELIK_METIN','Metin','ACIKLAMA','Açıklama','Aciklama']);
    if ($codeCol === '' || $nameCol === ''){
      echo json_encode(['ok' => false, 'error' => 'Nitelik tablosunda Kodu ve/veya Nitelik kolonu bulunamadı.'], JSON_UNESCAPED_UNICODE);
      exit;
    }

    $codeToText = [];
    if (count($allCodes) > 0){
      $ph2 = implode(',', array_fill(0, count($allCodes), '?'));
      $sql2 = "SELECT `$codeCol` AS kod, `$nameCol` AS nitelik FROM `$nitTable` WHERE `$codeCol` IN ($ph2)";
      $st2 = $pdo->prepare($sql2);
      $st2->execute($allCodes);
      while($r = $st2->fetch(PDO::FETCH_ASSOC)){
        $k = trim((string)($r['kod'] ?? ''));
        $t = trim((string)($r['nitelik'] ?? ''));
        if ($k !== '' && $t !== '') $codeToText[$k] = $t;
      }
    }

    $items = [];
    foreach($unvanlar as $u){
      $codes = isset($out[$u]) ? $out[$u] : [];
      $pairs = [];
      $tseen = [];
      foreach($codes as $c){
        $t = isset($codeToText[$c]) ? $codeToText[$c] : '';
        if ($t === ''){
          $t = (!empty($DEBUG)) ? "Nitelik bulunamadı (Kodu: {$c})" : "Nitelik bulunamadı.";
        }
        $uniqKey = $c . '|' . $t;
        if (!isset($tseen[$uniqKey])){
          $tseen[$uniqKey] = true;
          $pairs[] = ['kod' => (string)$c, 'metin' => (string)$t];
        }
      }
      $items[] = ['unvan' => $u, 'nitelikler' => $pairs, 'count' => count($pairs)];
    }

    echo json_encode(['ok' => true, 'nit_max' => count($allCodes), 'items' => $items], JSON_UNESCAPED_UNICODE);
    exit;

  } catch (Throwable $e){
    if (!empty($DEBUG)){
      echo json_encode(['ok' => false, 'error' => 'Veritabanı hatası: ' . $e->getMessage()], JSON_UNESCAPED_UNICODE);
    } else {
      echo json_encode(['ok' => false, 'error' => 'Veritabanı hatası.'], JSON_UNESCAPED_UNICODE);
    }
    exit;
  }
}



// ==========================
// AJAX: Step6 Sonuç Listeleme (kadrolar tablosu)
// Seçilen nitelik kodları, kadrolar.NitelikKodlari alanı ile karşılaştırılır.
// ==========================
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['ajax']) && $_POST['ajax'] === 'kadrolar_list') {
  header('Content-Type: application/json; charset=utf-8');

  $ogrenim  = isset($_POST['ogrenim']) ? trim((string)$_POST['ogrenim']) : '';
  $cities   = (isset($_POST['cities']) && is_array($_POST['cities'])) ? $_POST['cities'] : [];
  $unvanlar = (isset($_POST['unvanlar']) && is_array($_POST['unvanlar'])) ? $_POST['unvanlar'] : [];
  $selectedNitCodes = (isset($_POST['nitelik_kodlari']) && is_array($_POST['nitelik_kodlari'])) ? $_POST['nitelik_kodlari'] : [];

  $offset = isset($_POST['offset']) ? max(0, (int)$_POST['offset']) : 0;
  $limit  = isset($_POST['limit']) ? (int)$_POST['limit'] : 25;
  if ($limit < 10) $limit = 10;
  if ($limit > 80) $limit = 80;

  $wantTotal = isset($_POST['want_total']) ? (int)$_POST['want_total'] : 0;

  // JS değerinden DB'deki görünen değere map
  $ogMap = [
    'lisans'      => 'Lisans',
    'onlisans'    => 'Önlisans',
    'ortaogretim' => 'Ortaöğretim',
  ];
  $ogDb = isset($ogMap[$ogrenim]) ? $ogMap[$ogrenim] : $ogrenim;

  // Temizle (trim + unique + limit)
  $cleanArr = function($arr, $maxLen=120, $maxCount=200){
    $out = [];
    foreach((array)$arr as $v){
      $t = trim((string)$v);
      if ($t === '') continue;
      if (function_exists('mb_strlen')){
        if (mb_strlen($t, 'UTF-8') > $maxLen) continue;
      } else {
        if (strlen($t) > $maxLen) continue;
      }
      $out[$t] = true;
      if (count($out) >= $maxCount) break;
    }
    return array_keys($out);
  };

  $cleanCodeArr = function($arr, $maxCount=200){
    $out = [];
    foreach((array)$arr as $v){
      $t = preg_replace('/[^0-9]/', '', (string)$v);
      if ($t === '') continue;
      $out[$t] = true;
      if (count($out) >= $maxCount) break;
    }
    return array_keys($out);
  };

  $cities   = $cleanArr($cities, 64, 90);
  $unvanlar = $cleanArr($unvanlar, 120, 300);
  $selectedNitCodes = $cleanCodeArr($selectedNitCodes, 200);
  $normalizedCities = array_values(array_filter(array_unique(array_map('tr_normalize_compare_text', $cities))));

  if ($ogDb === '' || count($normalizedCities) === 0 || count($unvanlar) === 0) {
    echo json_encode(['ok'=>false,'error'=>'Filtre değerleri eksik.'], JSON_UNESCAPED_UNICODE);
    exit;
  }

  try{
    $pdo = db_pdo($DB_HOST, $DB_NAME, $DB_USER, $DB_PASS);

    // Türkçe collation varsa onu kullan
    $collation = 'utf8mb4_turkish_ci';
    $colOk = $pdo->query("SHOW COLLATION LIKE 'utf8mb4_turkish_ci'")->fetch();
    if (!$colOk) $collation = 'utf8mb4_general_ci';

    // WHERE parçaları
    $where = [];
    $vals  = [];

    $where[] = "CONVERT(`OgrenimDurumu` USING utf8mb4) COLLATE $collation = ?";
    $vals[]  = $ogDb;

    $phC = implode(',', array_fill(0, count($normalizedCities), '?'));
    $cityExpr = tr_sql_normalize_expr('`IlAdi`');
    $where[] = "{$cityExpr} IN ($phC)";
    $vals = array_merge($vals, $normalizedCities);

    $phU = implode(',', array_fill(0, count($unvanlar), '?'));
    $where[] = "CONVERT(`KadroUnvani` USING utf8mb4) COLLATE $collation IN ($phU)";
    $vals = array_merge($vals, $unvanlar);

    $whereSql = " WHERE " . implode(" AND ", $where);

    $normalizeNitCodes = function($raw){
      $raw = trim((string)$raw);
      if ($raw === '') return [];
      $parts = preg_split('/[^0-9]+/', $raw);
      $out = [];
      foreach((array)$parts as $p){
        $p = preg_replace('/[^0-9]/', '', (string)$p);
        if ($p === '') continue;
        $out[$p] = true;
      }
      return array_keys($out);
    };

    $selectedNitLookup = [];
    foreach($selectedNitCodes as $code){
      $selectedNitLookup[(string)$code] = true;
    }

    $sql = "SELECT `Kodu`,`OgrenimDurumu`,`KurumAdi`,`KadroUnvani`,`IlAdi`,`MerkezTasra`,
                   `Sinif`,`Derece`,`Kontenjan`,
                   `TabanPuanAlt`,`TabanPuanUst`,`TavanPuanAlt`,`TavanPuanUst`,
                   `NitelikKodlari`
            FROM `kadrolar`
            $whereSql
            ORDER BY `TabanPuanAlt` DESC, `TabanPuanUst` DESC, `Kodu` DESC";

    $st = $pdo->prepare($sql);

    $i = 1;
    foreach($vals as $v){
      $st->bindValue($i, (string)$v, PDO::PARAM_STR);
      $i++;
    }
    $st->execute();

    $allItems = [];
    while($r = $st->fetch(PDO::FETCH_ASSOC)){
      $rowNitCodes = $normalizeNitCodes($r['NitelikKodlari'] ?? '');
      $passNit = true;

      if (count($selectedNitLookup) > 0 && count($rowNitCodes) > 0){
        foreach($rowNitCodes as $rowCode){
          if (!isset($selectedNitLookup[$rowCode])){
            $passNit = false;
            break;
          }
        }
      }

      if (!$passNit) continue;

      $allItems[] = [
        'kodu' => (string)($r['Kodu'] ?? ''),
        'ogrenim_durumu' => (string)($r['OgrenimDurumu'] ?? ''),
        'kurum_adi' => (string)($r['KurumAdi'] ?? ''),
        'kadro_unvani' => (string)($r['KadroUnvani'] ?? ''),
        'il' => (string)($r['IlAdi'] ?? ''),
        'merkez_tasra' => ($r['MerkezTasra'] !== null ? (int)$r['MerkezTasra'] : null),
        'sinif' => (string)($r['Sinif'] ?? ''),
        'derece' => (string)($r['Derece'] ?? ''),
        'kontenjan' => ($r['Kontenjan'] !== null ? (int)$r['Kontenjan'] : 0),

        'taban_alt' => ($r['TabanPuanAlt'] !== null ? (string)$r['TabanPuanAlt'] : ''),
        'taban_ust' => ($r['TabanPuanUst'] !== null ? (string)$r['TabanPuanUst'] : ''),
        'tavan_alt' => ($r['TavanPuanAlt'] !== null ? (string)$r['TavanPuanAlt'] : ''),
        'tavan_ust' => ($r['TavanPuanUst'] !== null ? (string)$r['TavanPuanUst'] : ''),
        'nitelik_kodlari' => (string)($r['NitelikKodlari'] ?? ''),
      ];
    }

    $filteredTotal = count($allItems);
    $total = $wantTotal ? $filteredTotal : null;
    $items = array_slice($allItems, $offset, $limit);

    $nextOffset = $offset + count($items);
    if ($nextOffset > $filteredTotal) $nextOffset = $filteredTotal;
    $hasMore = ($nextOffset < $filteredTotal);

    echo json_encode([
      'ok' => true,
      'items' => $items,
      'total' => $total,
      'nextOffset' => $nextOffset,
      'hasMore' => $hasMore,
    ], JSON_UNESCAPED_UNICODE);
    exit;

  } catch (Throwable $e){
    if (!empty($DEBUG)){
      echo json_encode(['ok'=>false,'error'=>'Veritabanı hatası: ' . $e->getMessage()], JSON_UNESCAPED_UNICODE);
    } else {
      echo json_encode(['ok'=>false,'error'=>'Veritabanı hatası.'], JSON_UNESCAPED_UNICODE);
    }
    exit;
  }
}



// ==========================
// AJAX: Nitelik/Kosul Metinleri (kod listesine göre) - Step6 açılır kutu için
// ==========================
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['ajax']) && $_POST['ajax'] === 'nitelik_texts') {
  header('Content-Type: application/json; charset=utf-8');

  $codes = [];
  if (isset($_POST['codes']) && is_array($_POST['codes'])) {
    $codes = $_POST['codes'];
  } elseif (isset($_POST['codes']) && is_string($_POST['codes'])) {
    $codes = explode(',', (string)$_POST['codes']);
  }

  // temizle: sadece rakam
  $uniq = [];
  foreach((array)$codes as $c){
    $k = preg_replace('/[^0-9]/', '', (string)$c);
    if ($k === '') continue;
    $uniq[$k] = true;
    if (count($uniq) >= 250) break;
  }
  $codes = array_keys($uniq);

  if (count($codes) === 0){
    echo json_encode(['ok'=>true,'items'=>[]], JSON_UNESCAPED_UNICODE);
    exit;
  }

  try{
    $pdo = db_pdo($DB_HOST, $DB_NAME, $DB_USER, $DB_PASS);

    // Nitelik tablosunu bul (Kodu -> Nitelik)
    $nitTable = '';
    $nitTables = ['NitelikKodlari','nitelikkodlari','nitelik_kodlari','nitelik','nitelikler','nitelik_kodu','nitelikKodu'];
    foreach($nitTables as $t){
      $stmtT = $pdo->query("SHOW TABLES LIKE " . $pdo->quote($t));
      if ($stmtT->fetchColumn()){
        $nitTable = $t;
        break;
      }
    }
    if ($nitTable === ''){
      echo json_encode(['ok'=>false,'error'=>'Nitelik tablosu bulunamadı (Kodu/Nitelik).'], JSON_UNESCAPED_UNICODE);
      exit;
    }

    // Kolonları bul
    $ncols = $pdo->query("SHOW COLUMNS FROM `$nitTable`")->fetchAll(PDO::FETCH_COLUMN, 0);
    $nMap = [];
    foreach($ncols as $c){
      $nMap[mb_strtolower((string)$c, 'UTF-8')] = $c;
    }
    $pickNCol = function(array $cands) use ($nMap){
      foreach($cands as $cand){
        $k = mb_strtolower((string)$cand, 'UTF-8');
        if (isset($nMap[$k])) return $nMap[$k];
      }
      return '';
    };

    $codeCol = $pickNCol(['Kodu','KODU','Kod','KOD','CODE','Code']);
    $nameCol = $pickNCol(['Nitelik','NITELIK','NitelikMetni','NITELIK_METIN','Metin','ACIKLAMA','Açıklama','Aciklama']);

    if ($codeCol === '' || $nameCol === ''){
      echo json_encode(['ok'=>false,'error'=>'Nitelik tablosunda Kodu ve/veya Nitelik kolonu bulunamadı.'], JSON_UNESCAPED_UNICODE);
      exit;
    }

    $ph = implode(',', array_fill(0, count($codes), '?'));
    $sql = "SELECT `$codeCol` AS kod, `$nameCol` AS metin
            FROM `$nitTable`
            WHERE `$codeCol` IN ($ph)";
    $st = $pdo->prepare($sql);
    $st->execute($codes);

    $items = [];
    while($r = $st->fetch(PDO::FETCH_ASSOC)){
      $k = trim((string)($r['kod'] ?? ''));
      $t = trim((string)($r['metin'] ?? ''));
      if ($k === '') continue;
      $items[] = ['kod'=>$k, 'metin'=>$t];
    }

    echo json_encode(['ok'=>true,'items'=>$items], JSON_UNESCAPED_UNICODE);
    exit;

  } catch (Throwable $e){
    if (!empty($DEBUG)){
      echo json_encode(['ok'=>false,'error'=>'Veritabanı hatası: ' . $e->getMessage()], JSON_UNESCAPED_UNICODE);
    } else {
      echo json_encode(['ok'=>false,'error'=>'Veritabanı hatası.'], JSON_UNESCAPED_UNICODE);
    }
    exit;
  }
}

?>
<!doctype html>
<html lang="tr">
<head>
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1345582547235607"
     crossorigin="anonymous"></script>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />

  <title>KPSS Tercih Robotu</title>
  <meta name="description" content="KPSS Tercih Robotu: Öğrenim durumu ve KPSS puanına göre kadro filtreleme." />
  <meta name="theme-color" content="#0b2a5b" />

<link rel="icon" href="https://www.tercihrobotu.com.tr/duyurular/wp-content/uploads/2026/01/ico.png" sizes="32x32" />
<link rel="icon" href="https://www.tercihrobotu.com.tr/duyurular/wp-content/uploads/2026/01/ico.png" sizes="192x192" />
<link rel="apple-touch-icon" href="https://www.tercihrobotu.com.tr/duyurular/wp-content/uploads/2026/01/ico.png" />
<meta name="msapplication-TileImage" content="https://www.tercihrobotu.com.tr/duyurular/wp-content/uploads/2026/01/ico.png" />
  
  <link rel="stylesheet" href="/css/styles.css?v=8" />
  


<script defer src="/css/main.js?v=8"></script>



<style>
  html{overflow-y:scroll;}

  /* Layout: sponsorun masaüstünde sağda kalması (aşağı düşmesin) */
  .layout{
    display:flex !important;
    align-items:flex-start !important;
    gap:18px !important;
  }
  .layout .maincol{
    flex: 1 1 0;
    min-width:0;
    max-width: calc(100% - 340px);
  }
  .layout .sidebar{
    flex: 0 0 320px;
    width: 320px;
    min-width: 320px;
    align-self:flex-start;
    position: sticky;
    top: 90px;
  }
  @media (max-width: 980px){
    .layout{flex-direction:column !important;}
    .layout .maincol{max-width:100%;}
    .layout .sidebar{
      width:100%;
      min-width:0;
      position: static;
    }
  }

  /* Step 1 filtreler */
  .kpss-filter{margin:14px 0 18px; padding:14px; border:1px solid rgba(0,0,0,.08); border-radius:12px; background:#fff}
  .kpss-filter .filter-row{display:flex; gap:12px; align-items:center; margin-bottom:10px; flex-wrap:wrap}
  .kpss-filter label{min-width:160px; font-weight:700}
  .kpss-filter select,.kpss-filter input{flex:1; min-width:220px; padding:10px 12px; border:1px solid rgba(0,0,0,.15); border-radius:10px}
  .kpss-filter .btn-primary{margin-top:6px; padding:10px 14px; border:0; border-radius:10px; cursor:pointer}

  /* Step 2 paneli */
  #mezunWrap[hidden]{display:none !important;}
  .mezun-panel{margin:14px 0 18px; padding:14px; border:1px solid rgba(0,0,0,.08); border-radius:14px; background:#fff}
  .mezun-head{display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap; margin: 0 0 10px}
  .mezun-head-left{display:flex; align-items:center; gap:10px; flex-wrap:wrap}
  .mezun-head h2{margin:0; font-size:18px}
  .mezun-head-right{display:flex; align-items:center; gap:10px; flex-wrap:wrap}
  #mezunSearch{min-width:260px; padding:10px 12px; border:1px solid rgba(0,0,0,.15); border-radius:10px}

  .mezun-error{padding:10px 12px; border:1px solid rgba(220,0,0,.25); background:rgba(220,0,0,.05); color:#b00000; margin: 0 0 10px; border-radius:10px; font-weight:700}
  .mezun-list{border:1px solid rgba(0,0,0,.10); border-radius:12px; background:#fff; padding:6px; max-width:100%}
  .mezun-item{min-width:0}
  .mezun-name{word-break:break-word}
  .mezun-item{display:flex; align-items:center; gap:10px; padding:10px 10px; border-radius:10px; cursor:pointer}
  .mezun-item:hover{background:rgba(11,42,91,.06)}
  .mezun-item input{width:18px; height:18px}
  .mezun-code{font-weight:900; min-width:92px; color:rgba(10,37,64,.92)}
  .mezun-name{color:rgba(15,23,42,.90); font-weight:800; line-height:1.25}
  .mezun-foot{margin-top:10px; display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap}
  .mezun-status{color: var(--muted, #475569); font-weight:800; font-size:13px}
  .mezun-tools{margin-top:10px; display:flex; align-items:center; gap:10px; flex-wrap:wrap}

  /* Arama kutuları (mezuniyet + kadro) */
  .mezun-tools input[type="search"]{
    flex: 1 1 320px;
    min-width: 240px;
    height: 44px;
    padding: 0 14px;
    border: 1px solid rgba(0,0,0,.15);
    border-radius: 12px;
    background: #fff;
    outline: none;
  }
  .mezun-tools input[type="search"]::placeholder{color: rgba(0,0,0,.45);}
  .mezun-tools input[type="search"]:focus{
    border-color: rgba(14, 90, 164, .55);
    box-shadow: 0 0 0 4px rgba(14, 90, 164, .12);
  }
  .mezun-status-mini{
    padding: 6px 10px;
    border-radius: 10px;
    background: rgba(0,0,0,.04);
    font-weight: 800;
    font-size: 13px;
  }

  .mezun-status-mini{color: var(--muted, #475569); font-weight:800; font-size:13px}
  .city-all{display:flex; align-items:center; gap:8px; padding:8px 10px; border:1px solid rgba(0,0,0,.10); border-radius:10px; background:#fff; cursor:pointer; user-select:none}
  .city-all input{width:18px; height:18px}


  .mezun-actions{display:flex; align-items:center; gap:10px; flex-wrap:wrap}
  #btnDevamEt2[disabled]{opacity:.55; cursor:not-allowed}

  @media (max-width: 780px){
    .kpss-filter label{min-width:120px}
    #mezunSearch{min-width:200px}
  }


  /* Kadro arama kutusu (tema override) */
  #kadroSearch{
    width: 100%;
    display: block;
    padding: 12px 14px;
    border: 1px solid rgba(0,0,0,.14);
    border-radius: 14px;
    background: #fff;
    line-height: 1.2;
    font-size: 14px;
    transition: box-shadow .15s ease, border-color .15s ease, transform .05s ease;
  }
  #kadroSearch:focus{
    outline: none;
    border-color: rgba(37,99,235,.55);
    box-shadow: 0 0 0 4px rgba(37,99,235,.14);
  }
  #kadroSearch::placeholder{ color: rgba(0,0,0,.45); }


  /* --- Spacing tweak: search inputs vs lists --- */
  .mezun-head{margin: 0 0 14px;}
  .mezun-tools{margin: 10px 0 16px;}
  /* keep list in normal flow (no iframe-like feel) */
  .mezun-list{margin: 0;}


/* Step5: Nitelik metinleri görünümü (seçilebilir) */
.nit-list{ display:flex; flex-direction:column; gap:10px; }
.nit-item{ display:flex; align-items:flex-start; gap:10px; padding:10px 12px; border:1px solid rgba(0,0,0,.10); border-radius:12px; background:#fff; cursor:pointer; }
.nit-item:hover{ background:rgba(11,42,91,.04); }
.nit-item input{ width:18px; height:18px; margin-top:2px; flex:0 0 auto; }
.nit-text{ font-weight:700; color:rgba(15,23,42,.92); line-height:1.35; user-select:text; }
.nit-empty{ opacity:.75; font-size:14px; padding:10px 12px; border:1px dashed rgba(0,0,0,.18); border-radius:12px; background:rgba(0,0,0,.02); }

/* Step6: Sonuç kartları */
.result-list{ display:flex; flex-direction:column; gap:12px; }
.result-alert-overlay{position:fixed;inset:0;background:rgba(15,23,42,.55);display:flex;align-items:center;justify-content:center;padding:18px;z-index:99999;backdrop-filter:blur(3px);}
.result-alert-box{width:min(520px,100%);background:#fff;border-radius:22px;padding:24px 22px 20px;box-shadow:0 25px 80px rgba(15,23,42,.28);border:1px solid rgba(239,68,68,.14);animation:resultAlertIn .18s ease-out;}
.result-alert-icon{width:56px;height:56px;border-radius:50%;display:flex;align-items:center;justify-content:center;margin:0 auto 14px;font-size:28px;background:linear-gradient(135deg,#fff7ed,#fee2e2);box-shadow:inset 0 0 0 1px rgba(239,68,68,.12);}
.result-alert-title{margin:0 0 8px;text-align:center;font-size:22px;font-weight:800;color:#991b1b;}
.result-alert-text{margin:0;text-align:center;font-size:16px;line-height:1.55;color:#334155;}
.result-alert-actions{display:flex;justify-content:center;margin-top:18px;}
.result-alert-btn{appearance:none;border:0;border-radius:14px;padding:12px 22px;font-size:15px;font-weight:700;cursor:pointer;background:linear-gradient(135deg,#ef4444,#dc2626);color:#fff;box-shadow:0 12px 28px rgba(220,38,38,.28);}
.result-alert-btn:hover{transform:translateY(-1px);}
.result-alert-btn:active{transform:translateY(0);}
@keyframes resultAlertIn{from{opacity:0;transform:translateY(10px) scale(.98);}to{opacity:1;transform:translateY(0) scale(1);}}
.result-card{
  border:1px solid rgba(0,0,0,.10);
  border-radius:14px;
  background:#fff;
  padding:12px 14px;
  cursor:pointer;
  transition: box-shadow .15s ease, border-color .15s ease, transform .05s ease;
}
.result-card:hover{ border-color: rgba(37,99,235,.35); box-shadow: 0 10px 26px rgba(0,0,0,.06); }
.result-card:active{ transform: scale(.995); }
.result-card.is-selected{
  border-color: rgba(34,197,94,.95);
  box-shadow: 0 0 0 4px rgba(34,197,94,.14);
}
.result-top{ display:flex; align-items:flex-start; justify-content:space-between; gap:10px; flex-wrap:wrap; }
.result-title{ font-weight:900; color:rgba(15,23,42,.94); line-height:1.2; font-size:15px; }
.result-subtitle{ margin-top:4px; font-weight:800; color:rgba(15,23,42,.80); line-height:1.2; font-size:13px; }
.result-headtexts{ display:flex; flex-direction:column; min-width:0; }

.result-kodu{ font-weight:900; font-size:12px; padding:6px 10px; border-radius:999px; background:rgba(0,0,0,.05); }


.result-fields{
  margin-top:10px;
  display:grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap:8px 14px;
  font-size:13px;
}
.result-field{
  display:flex;
  gap:6px;
  align-items:baseline;
  flex-wrap:wrap;
  min-width:0;
}
.result-label{ color:rgba(0,0,0,.55); font-weight:900; line-height:1.2; }
.result-sep{ color:rgba(0,0,0,.55); font-weight:900; }
.result-value{ color:rgba(15,23,42,.92); font-weight:900; line-height:1.2; word-break:break-word; }

/* Step6: meta grid responsive */
@media (max-width: 840px){
  .result-fields{ grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 520px){
  .result-fields{ grid-template-columns: 1fr; }
}

/* Step6: seçim kutusu */
.result-left{ display:flex; align-items:flex-start; gap:10px; min-width:0; flex:1; }
.result-check{ width:18px; height:18px; margin-top:2px; flex:0 0 auto; }


/* Step6: Koşullar (açılır) */
.result-cond{ margin-top:10px; padding-top:10px; border-top:1px dashed rgba(0,0,0,.12); }
.result-cond summary{ cursor:pointer; font-weight:900; color:rgba(15,23,42,.86); outline:none; user-select:none; }
.result-cond summary::-webkit-details-marker{ display:none; }
.result-cond summary:after{ content:"▾"; float:right; opacity:.65; }
.result-cond[open] summary:after{ content:"▴"; }
.result-cond-body{ margin-top:8px; color:rgba(15,23,42,.84); font-weight:800; word-break:break-word; }
.result-cond-body ul{ margin:0; padding-left:18px; }
.result-cond-body li{ margin:4px 0; line-height:1.35; }


/* Step7: Seçimler - sürükle/bırak sıralama + dışa aktarım */
.final-actions{ display:flex; align-items:center; justify-content:flex-end; gap:10px; flex-wrap:wrap; }
.inline-form{ display:inline; margin:0; }
.final-hint{ font-size:12px; font-weight:900; opacity:.72; }
.final-card{ cursor:grab; }
.final-card:active{ cursor:grabbing; }
.final-card.dragging{ opacity:.6; }
.final-move{ display:flex; align-items:center; gap:8px; }
.final-index{ font-weight:950; opacity:.75; }
.drag-handle{ cursor:grab; user-select:none; font-size:18px; padding:2px 8px; border-radius:12px; background:rgba(2,132,199,.08); }
.btn-icon{ padding:6px 10px; line-height:1; font-weight:950; }
@media (max-width: 900px){
  .final-actions{ justify-content:flex-start; }
}



  /* Step7 export hata kutusu */
  .export-error{
    margin-top:10px;
    padding:10px 12px;
    border-radius:12px;
    border:1px solid rgba(220,0,0,.25);
    background: rgba(220,0,0,.06);
    color:#b00000;
    font-weight:800;
    white-space:pre-wrap;
  }

  /* Yazdır (aynı sayfa) */
  .print-area{ display:none; }
  .print-paper{ font-family: Arial, Helvetica, sans-serif; color:#000; padding:18mm; }
  .print-top{ font-size:14px; margin-bottom:10px; }
  .print-table{ width: 100%; border-collapse: collapse; table-layout: fixed; font-size:10px; }
  .print-table th,.print-table td{ border:1px solid #000; padding:6px 6px; vertical-align:top; }
  .print-table th{ font-weight: normal; }
  .print-table .c-sira{ width:10mm; }
  .print-table .c-num{ width:22mm; }
  .print-table .c-kont{ width:18mm; }
  .print-table .kadro{ word-break: break-word; overflow-wrap:anywhere; }
  .print-table tr.risk td{ background:#fff6b8; }
  .print-acik-title{ margin-top:12px; font-weight:bold; }
  .print-acik{ margin-top:6px; font-size:10px; line-height:1.35; }

  @media print{
    body > *:not(.print-area){ display:none !important; }
    .print-area{ display:block !important; }
    .print-area[hidden]{ display:block !important; }
  }

</style>

</head>


<body>
  <div class="topbar">
    <div class="container">
    <div class="topbar-inner">
        <a class="brand" href="/" aria-label="Tercih Robotu Ana Sayfa">
          <img class="brand-logo" src="/css/logo.png" alt="Tercih Robotu Logo" loading="eager" />
        </a>

        <div class="topbar-ad" aria-label="Sponsor">
          <a class="topbar-ad-link" href="/step1.php" aria-label="Sponsor - Step 1"><img class="topbar-ad-img" src="/a.png" alt="Sponsor" loading="eager" /></a>
        </div>

        <div class="social" aria-label="Sosyal Medya">
                  <a href="https://www.instagram.com/tercihrobotucom/" target="_blank" rel="noopener" aria-label="Instagram">
                    <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M7 2h10a5 5 0 0 1 5 5v10a5 5 0 0 1-5 5H7a5 5 0 0 1-5-5V7a5 5 0 0 1 5-5zm10 2H7a3 3 0 0 0-3 3v10a3 3 0 0 0 3 3h10a3 3 0 0 0 3-3V7a3 3 0 0 0-3-3zm-5 4.2A3.8 3.8 0 1 1 8.2 12 3.8 3.8 0 0 1 12 8.2zm0 2A1.8 1.8 0 1 0 13.8 12 1.8 1.8 0 0 0 12 10.2zM17.6 6.7a.8.8 0 1 1-.8-.8.8.8 0 0 1 .8.8z"/></svg>
                  </a>
                  <a href="https://x.com/tercihrobotucom/" target="_blank" rel="noopener" aria-label="X">
                    <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M18.9 2H22l-6.8 7.8L23 22h-6.7l-5.2-6.4L5.6 22H2l7.3-8.4L1.5 2h6.8l4.7 5.7L18.9 2zm-1.2 18h1.7L6.2 3.9H4.4L17.7 20z"/></svg>
                  </a>
                  <a href="https://www.youtube.com/user/tercihrobotu/" target="_blank" rel="noopener" aria-label="YouTube">
                    <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M21.6 7.2a3 3 0 0 0-2.1-2.1C17.7 4.6 12 4.6 12 4.6s-5.7 0-7.5.5A3 3 0 0 0 2.4 7.2 31.6 31.6 0 0 0 2 12a31.6 31.6 0 0 0 .4 4.8 3 3 0 0 0 2.1 2.1c1.8.5 7.5.5 7.5.5s5.7 0 7.5-.5a3 3 0 0 0 2.1-2.1A31.6 31.6 0 0 0 22 12a31.6 31.6 0 0 0-.4-4.8zM10 15.2V8.8L16 12l-6 3.2z"/></svg>
                  </a>
                  <a href="https://www.facebook.com/tercihrobotucom/" target="_blank" rel="noopener" aria-label="Facebook">
                    <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M13.5 22v-8h2.7l.4-3H13.5V9.1c0-.9.3-1.5 1.6-1.5h1.6V4.9c-.3 0-1.4-.1-2.7-.1-2.7 0-4.6 1.6-4.6 4.6V11H7v3h2.8v8h3.7z"/></svg>
                  </a>
                </div>
      </div>
    </div>
  </div>

 <!-- Mobilde: logo + sosyal aynı kalsın, sponsor (a.png) menünün üstünde görünsün -->
  <div class="mobile-top-ad" aria-label="Sponsor">
    <div class="container">
      <div class="mobile-top-ad-inner">
        <a class="mobile-top-ad-link" href="/step1.php" aria-label="Sponsor - Step 1"><img class="mobile-top-ad-img" src="/a.png" alt="Sponsor" loading="eager" /></a>
      </div>
    </div>
  </div>

  <nav class="nav" aria-label="Ana Menü">
    <div class="container">
      <div class="nav-inner">
        <button class="hamburger" id="hamburger" aria-controls="menu" aria-expanded="false">Menü</button>
        <div class="menu" id="menu">
          <a href="/" aria-current="page">Ana Sayfa</a>
   
		    <a href="/universiteler/">Üniversiteler</a>
          <a href="/bolumler/">Bölümler</a>
          <a href="/meslekler/">Meslekler</a>
          <a href="/tercihte-12-kural/">Tercihte 12 Kural</a>

        </div>
      </div>
    </div>
  </nav>




  <!-- MOBIL SPONSORLAR (Menünün hemen altında) -->
  <div class="mobile-sponsors" aria-label="Sponsorlar">
    <div class="container">
      <div class="mobile-sponsors-grid">
        <div class="ad-box">
          <div class="sponsor-badge" role="note" aria-label="Sponsor"><span>SPONSOR</span></div>
          <div class="ad-slot">
            <a class="ad-img-link" href="https://aday.esenyurt.edu.tr/?utm_source=TercihRobotu&utm_medium=Banner&utm_campaign=YKS2025" aria-label="Mobil Sponsor 1">
              <img src="/1-m.jpg" alt="Mobil Sponsor 1" loading="lazy">
            </a>
          </div>
        </div>

        <div class="ad-box">
          <div class="sponsor-badge" role="note" aria-label="Sponsor"><span>SPONSOR</span></div>
          <div class="ad-slot">
            <a class="ad-img-link" href="https://www.emu.edu.tr/ogrenciadaylari?utm_source=TercihRobotu&utm_medium=Banner&utm_campaign=YKS2025" aria-label="Mobil Sponsor 2">
              <img src="/2-m.jpg" alt="Mobil Sponsor 2" loading="lazy">
            </a>
          </div>
        </div>

        <div class="ad-box">
          <div class="sponsor-badge" role="note" aria-label="Sponsor"><span>SPONSOR</span></div>
          <div class="ad-slot">
            <a class="ad-img-link" href="https://aday.sanko.edu.tr/?utm_source=TercihRobotu&utm_medium=Banner&utm_campaign=YKS2025" aria-label="Mobil Sponsor 3">
              <img src="/3-m.jpg" alt="Mobil Sponsor 3" loading="lazy">
            </a>
          </div>
        </div>

        <div class="ad-box">
          <div class="sponsor-badge" role="note" aria-label="Sponsor"><span>SPONSOR</span></div>
          <div class="ad-slot">
            <a class="ad-img-link" href="https://run.admost.com/adx/goto.ashx?pbk=532117-379644-65342" aria-label="Mobil Sponsor 4">
              <img src="/4-m.jpg" alt="Mobil Sponsor 4" loading="lazy">
            </a>
          </div>
        </div>
      </div>
    </div>
  </div>
  
  <main class="container">
    <div class="layout">
      <div class="maincol">
          <div class="hero-decor" aria-hidden="true"></div>

          <br><br>

          
          <h1>KPSS Tercih Robotu : </h1>

          <!-- Step 1: Öğrenim + KPSS -->
          <div id="step1">
            <form id="kpssFilterForm" method="post" class="kpss-filter" autocomplete="off">
              <div class="filter-row">
                <label for="ogrenim">Öğrenim Durumu</label>
                <select name="ogrenim" id="ogrenim" required>
                  <option value="" selected disabled>Seçiniz</option>
                  <option value="lisans">Lisans</option>
                  <option value="onlisans">Önlisans</option>
                  <option value="ortaogretim">Ortaöğretim</option>
                </select>
              </div>

              <div class="filter-row">
                <label for="kpss_puan">KPSS Puanı (1 - 100)</label>
                <input type="number" name="kpss_puan" id="kpss_puan" min="1" max="100" step="1" placeholder="Örn: 85" required />
              </div>

              <button type="button" id="btnDevamEt" class="btn-primary">Devam Et</button>
            </form>
          </div>

          
          <!-- Step 2: Mezuniyet Alanları -->
          <div id="mezunWrap" class="mezun-panel" hidden>
            <div class="mezun-head">
              <div class="mezun-head-left">
                <button type="button" id="btnGeriDon" class="btn-secondary">← Geri Dön</button>
                <h2>Mezuniyet Alanları</h2>
              </div>
              <div class="mezun-head-right">
                <button type="button" id="btnDevamEt2" class="btn-primary">Devam Et</button>
              </div>
            </div>

            <div class="mezun-tools">
              <input type="search" id="mezunSearch" placeholder="Mezuniyet alanlarında ara..." autocomplete="off" />
              <div id="mezunMiniStatus" class="mezun-status-mini" aria-live="polite"></div>
            </div>

            <div id="mezunErr" class="mezun-error" hidden></div>
            <div id="mezunList" class="mezun-list" aria-label="Mezuniyet Alanları Listesi"></div>
          
            <div class="mezun-foot">
              <div id="mezunStatus" class="mezun-status"></div>
              <button type="button" id="btnMezunMore" class="btn-secondary" hidden>Daha Fazla Göster</button>
            </div>
          </div>

          <!-- Step 3: Şehir Seçimi -->
          <div id="cityWrap" class="mezun-panel" hidden>
            <div class="mezun-head">
              <div class="mezun-head-left">
                <button type="button" id="btnGeriDon3" class="btn-secondary">← Geri Dön</button>
                <h2>Şehir Seçimi</h2>
              </div>
              <div class="mezun-head-right">
                <button type="button" id="btnDevamEt3" class="btn-primary">Devam Et</button>
              </div>
            </div>

            <div class="mezun-tools">
              <label class="city-all">
                <input type="checkbox" id="chkAllTurkey" />
                <span>Tüm Türkiye</span>
              </label>
              <input type="search" id="citySearch" placeholder="Şehirlerde ara..." autocomplete="off" />
              <div id="cityMiniStatus" class="mezun-status-mini" aria-live="polite"></div>
            </div>

            <div id="cityErr" class="mezun-error" hidden></div>
            <div id="cityList" class="mezun-list" aria-label="Şehir Listesi"></div>
          </div>

          <!-- Step 4: Kadro Ünvanı -->
          <div id="kadroWrap" class="mezun-panel" hidden>
            <div class="mezun-head">
              <div class="mezun-head-left">
                <button type="button" id="btnGeriDon4" class="btn-secondary">← Geri Dön</button>
                <h2>Kadro Ünvanı</h2>
              </div>
              <div class="mezun-head-right">
                <button type="button" id="btnDevamEt4" class="btn-primary">Devam Et</button>
              </div>
            </div>

            <div class="mezun-tools">
              <input type="search" id="kadroSearch" placeholder="Kadro ünvanlarında ara..." autocomplete="off" />
              <div id="kadroMiniStatus" class="mezun-status-mini" aria-live="polite"></div>
            </div>

            <div id="kadroErr" class="mezun-error" hidden></div>
            <div id="kadroList" class="mezun-list" aria-label="Kadro Ünvanı Listesi"></div>
          </div>

	 


            <!-- Step 5: Nitelikler -->
      <div id="nitWrap" class="mezun-panel" hidden>
        <div class="mezun-head">
          <div class="mezun-head-left">
            <button type="button" id="btnGeriDon5" class="btn-secondary">← Geri Dön</button>
            <h2>Nitelikler: </h2>
			  <h3>⚠️ Aşağıdaki niteliklere sahip olmalısınız! </h3>
          </div>
          <div class="mezun-head-right">
            <button type="button" id="btnDevamEt5" class="btn-primary">Sonuçları Listele</button>
          </div>
        </div>

        <div id="nitInfo" class="mezun-status-mini" aria-live="polite"></div>
        <div id="nitErr" class="mezun-error" hidden></div>

        <div id="nitList" class="nit-list" aria-label="Nitelikler Listesi"></div>
      </div>

      <!-- Step 6: Sonuçlar -->
      <div id="resultWrap" class="mezun-panel" hidden>
        <div class="mezun-head">
          <div class="mezun-head-left">
            <button type="button" id="btnGeriDon6" class="btn-secondary">← Geri Dön</button>
            <h2>Sonuçlar</h2>
          </div>
          <div class="mezun-head-right">
            <div id="resultSelectMini" class="mezun-status-mini" aria-live="polite">Seçilen: 0</div>
            <button type="button" id="btnDevamEt6" class="btn-primary" disabled>Devam Et</button>
          </div>
        </div>

        <div class="mezun-tools">
          <div id="resultScoreInfo" class="mezun-status-mini" aria-live="polite"></div>
          <div id="resultMiniStatus" class="mezun-status-mini" aria-live="polite"></div>
        </div>

        <div id="resultErr" class="mezun-error" hidden></div>
        <div id="resultList" class="result-list" aria-label="Sonuç Listesi"></div>

        <div class="mezun-foot">
          <div id="resultStatus" class="mezun-status"></div>
          <button type="button" id="btnResultMore" class="btn-secondary" hidden>Daha Fazla Göster</button>
        </div>
      </div>

      <!-- Step 7: Seçimler -->
      <div id="finalWrap" class="mezun-panel" hidden>
        <div class="mezun-head">
          <div class="mezun-head-left">
            <button type="button" id="btnGeriDon7" class="btn-secondary">← Geri Dön</button>
            <h2>Seçimler</h2>
          </div>
        </div>

        <div class="mezun-tools">
          <div class="mezun-status-mini" aria-live="polite">Seçilen Kadro Sayısı: <b id="finalCount">0</b></div>

          <div class="final-actions">
            <div class="final-hint">Sıralamak için kartları sürükleyip bırakabilirsin.</div>

            <!-- Export payloads (JS doldurur) -->
            <input type="hidden" id="xlsxPayload" value="">
            <input type="hidden" id="pdfPayload" value="">

            <button type="button" id="btnExportExcel" class="btn-secondary" disabled>Excel İndir</button>
            <button type="button" id="btnExportPdf" class="btn-secondary" disabled>PDF İndir</button>
            <button type="button" id="btnPrint" class="btn-secondary" disabled>Yazdır</button>

            <div id="exportError" class="export-error" hidden></div>
          </div>
        </div>

        <div id="finalList" class="result-list" aria-label="Seçilen Sonuçlar"></div>

      </div>

      </div>

      <aside class="sidebar" aria-label="Sponsor Alanları">
        <div class="ad-box">
                            <div class="sponsor-badge" role="note" aria-label="Sponsor">
                <span>SPONSOR</span>
              </div>

<div class="ad-slot">
  <a class="ad-img-link" href="https://aday.esenyurt.edu.tr/?utm_source=TercihRobotu&utm_medium=Banner&utm_campaign=YKS2025" aria-label="Sponsor 1">
    <img src="/1.jpg" alt="Sponsor 1" loading="lazy">
  </a>
</div>
        </div>

        <div class="ad-box">
                            <div class="sponsor-badge" role="note" aria-label="Sponsor">
                <span>SPONSOR</span>
              </div>

<div class="ad-slot">
  <a class="ad-img-link" href="https://www.emu.edu.tr/ogrenciadaylari?utm_source=TercihRobotu&utm_medium=Banner&utm_campaign=YKS2025" aria-label="Sponsor 2">
    <img src="/2.jpg" alt="Sponsor 2" loading="lazy">
  </a>
</div>
        </div>

        <div class="ad-box">
                            <div class="sponsor-badge" role="note" aria-label="Sponsor">
                <span>SPONSOR</span>
              </div>

<div class="ad-slot">
  <a class="ad-img-link" href="https://aday.sanko.edu.tr/?utm_source=TercihRobotu&utm_medium=Banner&utm_campaign=YKS2025" aria-label="Sponsor 3">
    <img src="/3.jpg" alt="Sponsor 3" loading="lazy">
  </a>
</div>
        </div>

        <div class="ad-box">
                            <div class="sponsor-badge" role="note" aria-label="Sponsor">
                <span>SPONSOR</span>
              </div>

<div class="ad-slot">
  <a class="ad-img-link" href="https://run.admost.com/adx/goto.ashx?pbk=532117-379644-65342" aria-label="Sponsor 4">
    <img src="/4.jpg" alt="Sponsor 4" loading="lazy">
  </a>
</div>
        </div>

        <div class="ad-box">
                            <div class="sponsor-badge" role="note" aria-label="Sponsor">
                <span>SPONSOR</span>
              </div>

<div class="ad-slot">
  <a class="ad-img-link" href="https://ciu.edu.tr/tr/aday-ogrenci/tc-adaylar?utm_source=TercihRobotu&utm_medium=Banner&utm_campaign=YKS2025" aria-label="Sponsor 5">
    <img src="/5.jpg" alt="Sponsor 5" loading="lazy">
  </a>
</div>
        </div>
      </aside>

    </div>
  </main>


<footer>
    <div class="container">
      <div class="footer-links" aria-label="Alt Menü">
        <a href="/hakkimizda/">Hakkımızda</a>
        <a href="/kullanim-kosullari/">Kullanım Koşulları</a>
        <a href="/gizlilik-bildirimi/">Gizlilik Bildirimi</a>
        <a href="/sss/">Sıkça Sorulan Sorular</a>
        <a href="/yasal-uyari/">Yasal Uyarı</a>
        <a href="/bize-ulasin/">Bize Ulaşın</a>
      </div>

      <div class="footer-meta">
        <div class="footer-brand">Tercih Robotu bir Es Eğitim Danışmanlık markasıdır.</div>
        <div class="copyright">Copyright © 2026</div>
      </div>
    </div>
  </footer>

  <button class="to-top" id="toTop" aria-label="Yukarı çık">⬆️</button>

  
  <script src="https://cdn.jsdelivr.net/npm/jspdf@2.5.1/dist/jspdf.umd.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/jspdf-autotable@3.5.31/dist/jspdf.plugin.autotable.min.js"></script>

  <script>
    (function(){
      const btn = document.getElementById('toTop');
      if(!btn) return;
      function toggle(){
        btn.style.display = (window.scrollY > 400) ? 'block' : 'none';
      }
      window.addEventListener('scroll', toggle, {passive:true});
      toggle();
      btn.addEventListener('click', function(){
        window.scrollTo({top:0, behavior:'smooth'});
      });
    })();
  </script>

  <script>
(function(){
  const step1 = document.getElementById('step1');
  const wrap2 = document.getElementById('mezunWrap');
  const wrap3 = document.getElementById('cityWrap');
  const wrap4 = document.getElementById('kadroWrap');
  const wrap5 = document.getElementById('nitWrap');
  const wrap6 = document.getElementById('resultWrap');
  const wrap7 = document.getElementById('finalWrap');

  const btnStep1 = document.getElementById('btnDevamEt');

  const ogrenimEl = document.getElementById('ogrenim');
  const kpssEl = document.getElementById('kpss_puan');

  // Step2
  const btnBack2 = document.getElementById('btnGeriDon');
  const btnNext2 = document.getElementById('btnDevamEt2');
  const mezunSearch = document.getElementById('mezunSearch');
  const mezunList = document.getElementById('mezunList');
  const mezunErr = document.getElementById('mezunErr');
  const mezunMiniStatus = document.getElementById('mezunMiniStatus');
  const mezunStatus = document.getElementById('mezunStatus');
  const btnMezunMore = document.getElementById('btnMezunMore');

  // Step3
  const btnBack3 = document.getElementById('btnGeriDon3');
  const btnNext3 = document.getElementById('btnDevamEt3');
  const chkAllTurkey = document.getElementById('chkAllTurkey');
  const citySearch = document.getElementById('citySearch');
  const cityList = document.getElementById('cityList');
  const cityErr = document.getElementById('cityErr');
  const cityMiniStatus = document.getElementById('cityMiniStatus');

  // Step4
  const btnBack4 = document.getElementById('btnGeriDon4');
  const btnNext4 = document.getElementById('btnDevamEt4');
  const kadroSearch = document.getElementById('kadroSearch');
  const kadroList = document.getElementById('kadroList');
  const kadroErr = document.getElementById('kadroErr');
  const kadroMiniStatus = document.getElementById('kadroMiniStatus');
  // Step5
  const btnBack5 = document.getElementById('btnGeriDon5');
  const btnNext5 = document.getElementById('btnDevamEt5');
  // Step5'te kopyalama butonu yok (sadece seçilebilir liste)
  const nitInfo = document.getElementById('nitInfo');
  const nitErr  = document.getElementById('nitErr');
  const nitList = document.getElementById('nitList');
  let nitAbort = null;

  // Step6
  const btnBack6 = document.getElementById('btnGeriDon6');
  const resultScoreInfo = document.getElementById('resultScoreInfo');
  const resultMiniStatus = document.getElementById('resultMiniStatus');
  const resultStatus = document.getElementById('resultStatus');
  const resultErr = document.getElementById('resultErr');
  const resultList = document.getElementById('resultList');
  const btnResultMore = document.getElementById('btnResultMore');
  const btnNext6 = document.getElementById('btnDevamEt6');
  const resultSelectMini = document.getElementById('resultSelectMini');

  // Step7
  const btnBack7 = document.getElementById('btnGeriDon7');
  const finalCount = document.getElementById('finalCount');
  const finalList = document.getElementById('finalList');
  const btnExportExcel = document.getElementById('btnExportExcel');
  const btnExportPdf = document.getElementById('btnExportPdf');
  const btnPrint = document.getElementById('btnPrint');


  // State
  let currentOgrenim = '';
  let currentKpss = 0;

  // Step7 sıralama (DOM sırası)
  let finalOrder = [];

  let selectedMezunCode = '';
  let selectedMezunName = '';

  const allCities = [
    "Adana","Adıyaman","Afyonkarahisar","Ağrı","Aksaray","Amasya","Ankara","Antalya","Ardahan","Artvin","Aydın",
    "Balıkesir","Bartın","Batman","Bayburt","Bilecik","Bingöl","Bitlis","Bolu","Burdur","Bursa",
    "Çanakkale","Çankırı","Çorum","Denizli","Diyarbakır","Düzce","Edirne","Elazığ","Erzincan","Erzurum","Eskişehir",
    "Gaziantep","Giresun","Gümüşhane","Hakkari","Hatay","Iğdır","Isparta","İstanbul","İzmir",
    "Kahramanmaraş","Karabük","Karaman","Kars","Kastamonu","Kayseri","Kilis","Kırıkkale","Kırklareli","Kırşehir","Kocaeli","Konya","Kütahya",
    "Malatya","Manisa","Mardin","Mersin","Muğla","Muş","Nevşehir","Niğde","Ordu","Osmaniye",
    "Rize","Sakarya","Samsun","Şanlıurfa","Siirt","Sinop","Sivas","Şırnak",
    "Tekirdağ","Tokat","Trabzon","Tunceli",
    "Uşak","Van","Yalova","Yozgat","Zonguldak"
  ];
  let selectedCities = new Set(); // strings

  let kadroItemsAll = []; // strings
  let selectedKadroSet = new Set();

  // Step5 seçilen nitelikler
  let selectedNitSet = new Set();
  let nitTotalCount = 0;

  // Step6 sonuç state
  let resultAbort = null;
  let resultLoading = false;
  let resultOffset = 0;
  let resultTotal = null;
  let resultHasMore = false;
  const RESULT_LIMIT = 25;

  // Step6: Seçilen sonuçlar
  let selectedResultSet = new Set(); // kodu
  let resultItemMap = new Map(); // kodu -> item (özet için)

  // Helpers
  const trLower = (s) => (s || '').toString().toLocaleLowerCase('tr-TR');

  function showOnly(stepNo){
    step1.hidden = stepNo !== 1;
    wrap2.hidden = stepNo !== 2;
    wrap3.hidden = stepNo !== 3;
    wrap4.hidden = stepNo !== 4;
    wrap5.hidden = stepNo !== 5;
    wrap6.hidden = stepNo !== 6;
    if (wrap7) wrap7.hidden = stepNo !== 7;
    clearAllErrors();
  }

  function setErr(el, msg){
    if (!el) return;
    if (!msg){
      el.hidden = true;
      el.textContent = '';
    } else {
      el.hidden = false;
      el.textContent = msg;
    }
  }
  function clearAllErrors(){
    setErr(mezunErr, '');
    setErr(cityErr, '');
    setErr(kadroErr, '');
    setErr(nitErr, '');
    setErr(resultErr, '');
  }

  function setMiniStatus(el, msg){
    if (!el) return;
    el.textContent = msg || '';
  }

  function closeStyledResultAlert(){
    const old = document.getElementById('resultAlertOverlay');
    if (old) old.remove();
    document.body.style.overflow = '';
  }

  function showStyledResultAlert(message){
    closeStyledResultAlert();

    const overlay = document.createElement('div');
    overlay.id = 'resultAlertOverlay';
    overlay.className = 'result-alert-overlay';

    const box = document.createElement('div');
    box.className = 'result-alert-box';
    box.setAttribute('role', 'alertdialog');
    box.setAttribute('aria-modal', 'true');
    box.setAttribute('aria-labelledby', 'resultAlertTitle');
    box.setAttribute('aria-describedby', 'resultAlertText');

    const icon = document.createElement('div');
    icon.className = 'result-alert-icon';
    icon.textContent = '⚠️';

    const title = document.createElement('h3');
    title.id = 'resultAlertTitle';
    title.className = 'result-alert-title';
    title.textContent = 'Uyarı';

    const text = document.createElement('p');
    text.id = 'resultAlertText';
    text.className = 'result-alert-text';
    text.textContent = message || 'İlgili kadronun istenilen niteliklerine sahip değilsiniz!';

    const actions = document.createElement('div');
    actions.className = 'result-alert-actions';

    const btn = document.createElement('button');
    btn.type = 'button';
    btn.className = 'result-alert-btn';
    btn.textContent = 'Tamam';
    btn.addEventListener('click', closeStyledResultAlert);

    actions.appendChild(btn);
    box.appendChild(icon);
    box.appendChild(title);
    box.appendChild(text);
    box.appendChild(actions);
    overlay.appendChild(box);

    overlay.addEventListener('click', (e) => {
      if (e.target === overlay) closeStyledResultAlert();
    });

    document.addEventListener('keydown', function onKey(ev){
      if (ev.key === 'Escape'){
        closeStyledResultAlert();
        document.removeEventListener('keydown', onKey);
      }
    }, { once:true });

    document.body.appendChild(overlay);
    document.body.style.overflow = 'hidden';
    btn.focus();
  }

  // --------------------
// STEP 2: Mezuniyet Alanı (parça parça + "Daha Fazla Göster")
// --------------------
let mezunAbort = null;
let mezunLoading = false;
let mezunOffset = 0;
let mezunTotal = 0;
let mezunHasMore = false;
let mezunQ = '';
const MEZUN_LIMIT = 40;

function resetMezunList(){
  mezunOffset = 0;
  mezunTotal = 0;
  mezunHasMore = false;
  mezunQ = (mezunSearch.value || '').trim();
  mezunList.innerHTML = '';
  setErr(mezunErr, '');
  setMiniStatus(mezunMiniStatus, '');
  if (typeof mezunStatus !== 'undefined' && mezunStatus) mezunStatus.textContent = '';
  if (typeof btnMezunMore !== 'undefined' && btnMezunMore) btnMezunMore.hidden = true;
}

function updateMezunStatus(){
  const shown = mezunOffset;
  const total = mezunTotal;
  const msg = total ? (`Gösterilen: ${shown} / ${total}`) : (shown ? `Gösterilen: ${shown}` : '');
  setMiniStatus(mezunMiniStatus, msg);
  if (typeof mezunStatus !== 'undefined' && mezunStatus) mezunStatus.textContent = msg;
  if (typeof btnMezunMore !== 'undefined' && btnMezunMore){
    btnMezunMore.hidden = !mezunHasMore;
    btnMezunMore.disabled = mezunLoading;
  }
}

function appendMezunItems(items){
  const frag = document.createDocumentFragment();
  for (const it of (items || [])){
    const code = (it && it.code != null) ? String(it.code) : '';
    const name = (it && it.name != null) ? String(it.name) : '';
    if (!code && !name) continue;

    const label = document.createElement('label');
    label.className = 'mezun-item';

    const inp = document.createElement('input');
    inp.type = 'radio';
    inp.name = 'mezunRadio';
    inp.value = code;
    inp.dataset.name = name;
    if (code === selectedMezunCode) inp.checked = true;

    const c = document.createElement('div');
    c.className = 'mezun-code';
    c.textContent = code;

    const n = document.createElement('div');
    n.className = 'mezun-name';
    n.textContent = name;

    label.appendChild(inp);
    label.appendChild(c);
    label.appendChild(n);
    frag.appendChild(label);
  }
  mezunList.appendChild(frag);
}

async function loadMezunNextPage(reset=false){
  if (mezunLoading) return;
  mezunLoading = true;

  if (reset) resetMezunList();

  setErr(mezunErr, '');
  const qNow = (mezunSearch.value || '').trim();
  mezunQ = qNow;

  if (mezunAbort) mezunAbort.abort();
  mezunAbort = new AbortController();

  setMiniStatus(mezunMiniStatus, 'Yükleniyor…');
  updateMezunStatus();

  try{
    const params = new URLSearchParams();
    params.append('ajax', 'mezun_alan');
    params.append('ogrenim', currentOgrenim);
    params.append('q', mezunQ);
    params.append('offset', String(mezunOffset));
    params.append('limit', String(MEZUN_LIMIT));

    const res = await fetch(window.location.href, {
      method: 'POST',
      headers: {'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'},
      body: params.toString(),
      signal: mezunAbort.signal
    });

    const data = await res.json();
    if (!data || data.ok !== true){
      throw new Error((data && data.error) ? data.error : 'Mezuniyet alanları alınamadı.');
    }

    const items = Array.isArray(data.items) ? data.items : [];
    mezunTotal = Number.isFinite(+data.total) ? +data.total : (mezunTotal || 0);

    appendMezunItems(items);

    mezunOffset = Number.isFinite(+data.nextOffset) ? +data.nextOffset : (mezunOffset + items.length);
    mezunHasMore = !!data.hasMore;

    if (mezunOffset === 0 && mezunTotal === 0){
      setMiniStatus(mezunMiniStatus, 'Kayıt yok');
    }

  } catch(err){
    if (err && err.name === 'AbortError') {
      // yeni arama geldi, sessiz geç
    } else {
      setErr(mezunErr, (err && err.message) ? err.message : 'Bir hata oluştu.');
    }
  } finally {
    mezunLoading = false;
    updateMezunStatus();
  }
}

mezunList.addEventListener('change', (e) => {
  const t = e.target;
  if (!t || t.tagName !== 'INPUT' || t.type !== 'radio') return;
  selectedMezunCode = t.value || '';
  selectedMezunName = (t.dataset && t.dataset.name) ? t.dataset.name : '';
});

// Arama: debounce + ilk sayfaya dön
let mezunSearchTimer = null;
mezunSearch.addEventListener('input', () => {
  if (mezunSearchTimer) clearTimeout(mezunSearchTimer);
  mezunSearchTimer = setTimeout(() => {
    loadMezunNextPage(true);
  }, 250);
});

if (typeof btnMezunMore !== 'undefined' && btnMezunMore){
  btnMezunMore.addEventListener('click', () => {
    loadMezunNextPage(false);
  });
}

  // --------------------
  // STEP 3: Şehir seçimi (çoklu)
  // --------------------
  function renderCityList(){
    const q = trLower(citySearch.value || '').trim();
    const frag = document.createDocumentFragment();
    let shown = 0;

    for (const city of allCities){
      const hay = trLower(city);
      if (q && !hay.includes(q)) continue;

      const label = document.createElement('label');
      label.className = 'mezun-item';

      const inp = document.createElement('input');
      inp.type = 'checkbox';
      inp.value = city;
      inp.checked = selectedCities.has(city);

      const c = document.createElement('div');
      c.className = 'mezun-code';
      c.textContent = '📍';

      const n = document.createElement('div');
      n.className = 'mezun-name';
      n.textContent = city;

      label.appendChild(inp);
      label.appendChild(c);
      label.appendChild(n);

      frag.appendChild(label);
      shown++;
    }

    cityList.innerHTML = '';
    cityList.appendChild(frag);
    setMiniStatus(cityMiniStatus, shown ? ('Gösterilen: ' + shown + ' / ' + allCities.length) : 'Eşleşme yok');
    syncAllTurkeyCheckbox();
  }

  function syncAllTurkeyCheckbox(){
    const total = allCities.length;
    const sel = selectedCities.size;
    chkAllTurkey.indeterminate = sel > 0 && sel < total;
    chkAllTurkey.checked = sel === total;
  }

  chkAllTurkey.addEventListener('change', () => {
    if (chkAllTurkey.checked){
      selectedCities = new Set(allCities);
    } else {
      selectedCities = new Set();
    }
    renderCityList();
  });

  cityList.addEventListener('change', (e) => {
    const t = e.target;
    if (!t || t.tagName !== 'INPUT' || t.type !== 'checkbox') return;
    const city = t.value || '';
    if (!city) return;

    if (t.checked) selectedCities.add(city);
    else selectedCities.delete(city);

    syncAllTurkeyCheckbox();
  });

  citySearch.addEventListener('input', () => {
    renderCityList();
  });

  // --------------------
  // STEP 4: Kadro Ünvanı (DB’den şehir+öğrenim ile çek)
  // --------------------
  let kadroAbort = null;

  async function loadKadroUnvan(){
    setErr(kadroErr, '');
    setMiniStatus(kadroMiniStatus, 'Yükleniyor…');

    if (kadroAbort) kadroAbort.abort();
    kadroAbort = new AbortController();

    const params = new URLSearchParams();
    params.append('ajax', 'kadro_unvan');
    params.append('ogrenim', currentOgrenim);

    // cities[]=...
    for (const c of selectedCities){
      params.append('cities[]', c);
    }

    const res = await fetch(window.location.href, {
      method: 'POST',
      headers: {'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'},
      body: params.toString(),
      signal: kadroAbort.signal
    });

    const data = await res.json();
    if (!data || data.ok !== true){
      throw new Error((data && data.error) ? data.error : 'Kadro ünvanları alınamadı.');
    }

    kadroItemsAll = Array.isArray(data.items) ? data.items : [];
    setMiniStatus(kadroMiniStatus, kadroItemsAll.length ? ('Toplam ' + kadroItemsAll.length + ' ünvan') : 'Kayıt yok');
    renderKadroList();
  }

  function renderKadroList(){
    const q = trLower(kadroSearch.value || '').trim();
    const frag = document.createDocumentFragment();
    let shown = 0;

    for (const u of kadroItemsAll){
      const name = String(u || '').trim();
      if (!name) continue;

      const hay = trLower(name);
      if (q && !hay.includes(q)) continue;

      const label = document.createElement('label');
      label.className = 'mezun-item';

      const inp = document.createElement('input');
      inp.type = 'checkbox';
      inp.value = name;
      inp.checked = selectedKadroSet.has(name);

      const c = document.createElement('div');
      c.className = 'mezun-code';
      c.textContent = '🏷️';

      const n = document.createElement('div');
      n.className = 'mezun-name';
      n.textContent = name;

      label.appendChild(inp);
      label.appendChild(c);
      label.appendChild(n);

      frag.appendChild(label);
      shown++;
    }

    kadroList.innerHTML = '';
    kadroList.appendChild(frag);
    setMiniStatus(kadroMiniStatus, shown ? ('Gösterilen: ' + shown + ' / ' + kadroItemsAll.length) : 'Eşleşme yok');
  }

  kadroList.addEventListener('change', (e) => {
    const t = e.target;
    if (!t || t.tagName !== 'INPUT' || t.type !== 'checkbox') return;
    const v = t.value || '';
    if (!v) return;
    if (t.checked) selectedKadroSet.add(v);
    else selectedKadroSet.delete(v);
  });

  kadroSearch.addEventListener('input', () => {
    renderKadroList();
  });

  // --------------------
  // Navigation
  // --------------------
  btnStep1.addEventListener('click', async () => {
    // step1 validate
    const og = (ogrenimEl.value || '').trim();
    const kp = parseInt(kpssEl.value || '0', 10);

    if (!og){
      alert('Öğrenim durumunu seçin.');
      return;
    }
    if (!kp || kp < 1 || kp > 100){
      alert('KPSS puanını 1-100 aralığında girin.');
      return;
    }

    currentOgrenim = og;
    currentKpss = kp;

    // reset step2 selections
    selectedMezunCode = '';
    selectedMezunName = '';
    mezunSearch.value = '';

    showOnly(2);
    await loadMezunNextPage(true);
  });

  btnBack2.addEventListener('click', () => {
    showOnly(1);
  });

  btnNext2.addEventListener('click', () => {
    setErr(mezunErr, '');
    if (!selectedMezunCode){
      setErr(mezunErr, 'Lütfen bir mezuniyet alanı seçin.');
      return;
    }
    // Step3 prepare
    selectedCities = new Set();
    citySearch.value = '';
    cityList.innerHTML = '';
    setMiniStatus(cityMiniStatus, '');
    chkAllTurkey.checked = false;
    chkAllTurkey.indeterminate = false;

    showOnly(3);
    renderCityList();
  });

  btnBack3.addEventListener('click', () => {
    showOnly(2);
  });

  btnNext3.addEventListener('click', async () => {
    setErr(cityErr, '');
    if (selectedCities.size === 0){
      setErr(cityErr, 'Lütfen en az 1 şehir seçin (veya Tüm Türkiye).');
      return;
    }

    // Step4 prepare
    selectedKadroSet = new Set();
    kadroItemsAll = [];
    kadroSearch.value = '';
    kadroList.innerHTML = '';
    setMiniStatus(kadroMiniStatus, '');

    showOnly(4);

    try{
      await loadKadroUnvan();
    } catch(err){
      setErr(kadroErr, err && err.message ? err.message : 'Kadro ünvanları yüklenemedi.');
      setMiniStatus(kadroMiniStatus, '');
    }
  });

  

  async function loadKadroNitelikler(){
    setErr(nitErr, '');
    if (nitInfo) nitInfo.textContent = 'Yükleniyor…';
    nitList.innerHTML = '';

    if (nitAbort) nitAbort.abort();
    nitAbort = new AbortController();

    const params = new URLSearchParams();
    params.append('ajax', 'kadro_nitelikler');
    params.append('ogrenim', currentOgrenim);

    for (const c of selectedCities){
      params.append('cities[]', c);
    }

    for (const u of selectedKadroSet){
      params.append('unvanlar[]', u);
    }

    const res = await fetch(location.href, {
      method: 'POST',
      headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
      body: params.toString(),
      signal: nitAbort.signal
    });

    if (!res.ok) throw new Error('İstek başarısız: ' + res.status);

    const data = await res.json();
    if (!data || data.ok !== true){
      throw new Error((data && data.error) ? data.error : 'Nitelikler alınamadı.');
    }
    return data;
  }

  
  function updateNitMini(){
    const sel = selectedNitSet.size;
    const tot = nitTotalCount || 0;
    if (nitInfo){
      if (tot){
        nitInfo.textContent = `Toplam ${tot} nitelik · Seçilen: ${sel}`;
      } else if (sel){
        nitInfo.textContent = `Seçilen: ${sel}`;
      } else {
        nitInfo.textContent = '';
      }
    }
  }

function renderNitelikler(items){
    nitList.innerHTML = '';
    const frag = document.createDocumentFragment();

    // Ünvanları ekranda göstermiyoruz: tüm nitelikleri kod bazında tekilleştirip tek listede göster
    const uniq = [];
    const seen = new Set();
    for (const it of (items || [])){
      const nits = Array.isArray(it.nitelikler) ? it.nitelikler : [];
      for (const nit of nits){
        const kod = String((nit && nit.kod != null) ? nit.kod : '').trim();
        const txt = String((nit && nit.metin != null) ? nit.metin : '').trim();
        if (!kod || !txt) continue;
        if (seen.has(kod)) continue;
        seen.add(kod);
        uniq.push({kod, metin: txt});
      }
    }

    if (uniq.length === 0){
      const empty = document.createElement('div');
      empty.className = 'nit-empty';
      empty.textContent = 'Bu seçim için nitelik bulunamadı.';
      frag.appendChild(empty);
    } else {
      // İstersen alfabetik sıralama: aşağıdaki satırı aç
      // uniq.sort((a,b)=>a.metin.localeCompare(b.metin,'tr'));

      for (let i=0; i<uniq.length; i++){
        const row = document.createElement('label');
        row.className = 'nit-item';

        const cb = document.createElement('input');
        cb.type = 'checkbox';
        cb.value = uniq[i].kod;
        cb.dataset.text = uniq[i].metin;

        const text = document.createElement('span');
        text.className = 'nit-text';
        text.textContent = uniq[i].metin + ' (' + uniq[i].kod + ')';

        // Satıra tıklayınca checkbox değişsin
        row.addEventListener('click', (e) => {
          // direkt checkbox'a tıklanınca iki kez toggle olmasın
          if (e.target === cb) return;
          cb.checked = !cb.checked;
          cb.dispatchEvent(new Event('change', {bubbles:true}));
        });

        row.appendChild(cb);
        row.appendChild(text);
        frag.appendChild(row);
      }
    }

    nitList.appendChild(frag);

    nitTotalCount = uniq.length;
    selectedNitSet = new Set();
    if (nitTotalCount === 0){
      if (nitInfo) nitInfo.textContent = 'Nitelik yok';
    } else {
      updateNitMini();
    }

  }


  // Step5: nitelik seçimi takip et
  nitList.addEventListener('change', (e) => {
    const t = e.target;
    if (!t || t.tagName !== 'INPUT' || t.type !== 'checkbox') return;
    const v = (t.value || '').trim();
    if (!v) return;
    if (t.checked) selectedNitSet.add(v);
    else selectedNitSet.delete(v);
    updateNitMini();
  });


  // --------------------
  // STEP 6: Sonuç listeleme (kadrolar)
  // --------------------
  const nitCache = new Map(); // kod -> metin (koşul)

  function parseNitelikCodes(str){
    const raw = String(str || '').trim();
    if (!raw) return [];
    return raw.split(',').map(x => String(x).replace(/[^0-9]/g,'')).filter(Boolean);
  }

  function merkezTasraText(v){
    const n = (v === null || v === undefined) ? null : Number(v);
    if (n === 0) return 'Taşra';
    if (n === 1) return 'Merkez';
    return '-';
  }

  function pickScore(alt, ust){
    const a = String(alt || '').trim();
    const u = String(ust || '').trim();
    // öncelik: üst
    if (u && u !== '0' && u !== '0.00000') return u;
    if (a && a !== '0' && a !== '0.00000') return a;
    return '-';
  }

  async function fetchNitelikTexts(codes){
    const need = [];
    for (const c of (codes || [])){
      if (!nitCache.has(c)) need.push(c);
    }
    if (need.length === 0) return;

    const params = new URLSearchParams();
    params.append('ajax', 'nitelik_texts');
    for (const c of need) params.append('codes[]', c);

    const res = await fetch(location.href, {
      method: 'POST',
      headers: {'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'},
      body: params.toString(),
    });

    const data = await res.json();
    if (!data || data.ok !== true){
      throw new Error((data && data.error) ? data.error : 'Koşullar alınamadı.');
    }

    const items = Array.isArray(data.items) ? data.items : [];
    for (const it of items){
      const k = String(it.kod || '').trim();
      const t = String(it.metin || '').trim();
      if (k) nitCache.set(k, t || '');
    }

    // DB'de olmayan kodlar da cache'e düşsün (tekrar tekrar istemeyelim)
    for (const c of need){
      if (!nitCache.has(c)) nitCache.set(c, '');
    }
  }


  // Step6: seçim (kart seçme) + Devam Et
  function updateResultSelectedMini(){
    if (resultSelectMini) resultSelectMini.textContent = 'Seçilen: ' + String(selectedResultSet.size);
    if (btnNext6) btnNext6.disabled = (selectedResultSet.size === 0);
  }

  function setResultSelected(code, isSelected, card, checkbox, item){
    if (!code) return;
    if (isSelected){
      selectedResultSet.add(code);
      if (card) card.classList.add('is-selected');
      if (checkbox) checkbox.checked = true;
      if (item) resultItemMap.set(code, item);
    } else {
      selectedResultSet.delete(code);
      if (card) card.classList.remove('is-selected');
      if (checkbox) checkbox.checked = false;
    }
    updateResultSelectedMini();
  }

  function toggleResultSelection(code, card, checkbox, item){
    const next = !selectedResultSet.has(code);
    setResultSelected(code, next, card, checkbox, item);
  }

  function renderFinalSelections(){
    if (!finalCount || !finalList) return;

    finalCount.textContent = String(selectedResultSet.size);
    finalList.innerHTML = '';

    normalizeFinalOrder();

    if (selectedResultSet.size === 0){
      const empty = document.createElement('div');
      empty.className = 'mezun-status-mini';
      empty.textContent = 'Seçim yapılmadı.';
      finalList.appendChild(empty);
      updateFinalActionButtons();
      return;
    }

    const fmt = (v) => {
      if (v === 0) return '0';
      if (v === null || v === undefined) return '-';
      const s = String(v).trim();
      return s ? s : '-';
    };

    const mkField = (label, value) => {
      const row = document.createElement('div');
      row.className = 'result-field';

      const l = document.createElement('span');
      l.className = 'result-label';
      l.textContent = label;

      const sep = document.createElement('span');
      sep.className = 'result-sep';
      sep.textContent = ' : ';

      const v = document.createElement('span');
      v.className = 'result-value';
      v.textContent = fmt(value);

      row.appendChild(l);
      row.appendChild(sep);
      row.appendChild(v);
      return row;
    };

    const frag = document.createDocumentFragment();
    for (const code of finalOrder){
      const it = resultItemMap.get(code) || {};
      const card = document.createElement('div');
      card.className = 'result-card final-card is-selected';
      card.draggable = true;
      card.setAttribute('data-code', String(code || ''));

      const top = document.createElement('div');
      top.className = 'result-top';

      const headTexts = document.createElement('div');
      headTexts.className = 'result-headtexts';

      const title = document.createElement('div');
      title.className = 'result-title';
      title.textContent = (it.kurum_adi || '');

      const sub = document.createElement('div');
      sub.className = 'result-subtitle';
      sub.textContent = (it.kadro_unvani || '-');

      headTexts.appendChild(title);
      headTexts.appendChild(sub);

      const right = document.createElement('div');
      right.className = 'final-move';

      const idxEl = document.createElement('span');
      idxEl.className = 'final-index';
      idxEl.textContent = '';

      const handle = document.createElement('span');
      handle.className = 'drag-handle';
      handle.textContent = '⠿';

      const up = document.createElement('button');
      up.type = 'button';
      up.className = 'btn-secondary btn-icon';
      up.textContent = '↑';
      up.setAttribute('data-move', 'up');

      const down = document.createElement('button');
      down.type = 'button';
      down.className = 'btn-secondary btn-icon';
      down.textContent = '↓';
      down.setAttribute('data-move', 'down');

      const kod = document.createElement('div');
      kod.className = 'result-kodu';
      kod.textContent = code ? ('#' + code) : '';

      right.appendChild(idxEl);
      right.appendChild(handle);
      right.appendChild(up);
      right.appendChild(down);
      right.appendChild(kod);

      top.appendChild(headTexts);
      top.appendChild(right);

      const fields = document.createElement('div');
      fields.className = 'result-fields';
      fields.appendChild(mkField('İl Adı', (it.il || it.il_adi || '-')));
      fields.appendChild(mkField('Merkez/Taşra', merkezTasraText(it.merkez_tasra)));
      fields.appendChild(mkField('Taban Puan', pickScore(it.taban_alt, it.taban_ust)));
      fields.appendChild(mkField('Tavan Puan', pickScore(it.tavan_alt, it.tavan_ust)));
      fields.appendChild(mkField('Adayın Puanı', (currentKpss ?? '-')));
      fields.appendChild(mkField('Kontenjan', (it.kontenjan ?? '-')));
      fields.appendChild(mkField('Öğrenim Durumu', (it.ogrenim_durumu || '-')));
      fields.appendChild(mkField('Sınıf', (it.sinif || '-')));
      fields.appendChild(mkField('Derece', (it.derece || '-')));

      card.appendChild(top);
      card.appendChild(fields);

      frag.appendChild(card);
    }

    finalList.appendChild(frag);
    updateFinalIndexes();
    updateFinalActionButtons();
  }

  function resetResultList(){
    resultOffset = 0;
    resultTotal = null;
    resultHasMore = false;
    if (resultList) resultList.innerHTML = '';
    setErr(resultErr, '');
    setMiniStatus(resultMiniStatus, '');
    if (resultStatus) resultStatus.textContent = '';
    if (btnResultMore) btnResultMore.hidden = true;
  }

  function updateResultStatus(){
    const shown = resultOffset;
    const total = (resultTotal != null) ? resultTotal : null;
    const msg = (total != null)
      ? (total ? `Gösterilen: ${shown} / ${total}` : '')
      : (shown ? `Gösterilen: ${shown}` : '');

    setMiniStatus(resultMiniStatus, msg);
    if (resultStatus) resultStatus.textContent = msg;
    if (btnResultMore){
      btnResultMore.hidden = !resultHasMore;
      btnResultMore.disabled = resultLoading;
    }
  }

  function normalizeFinalOrder(){
    // finalOrder boşsa veya seçim değiştiyse güncelle
    const sel = Array.from(selectedResultSet).map(v => String(v));
    const selSet = new Set(sel);

    if (!Array.isArray(finalOrder)) finalOrder = [];
    // mevcut sıralamadan seçilmeyenleri at
    finalOrder = finalOrder.map(v => String(v)).filter(v => selSet.has(v));
    // yeni seçilenleri sona ekle (set insertion order)
    for (const c of sel){
      if (!finalOrder.includes(c)) finalOrder.push(c);
    }
  }

  function updateFinalActionButtons(){
    const has = selectedResultSet.size > 0;
    if (btnExportExcel) btnExportExcel.disabled = !has;
    if (btnExportPdf) btnExportPdf.disabled = !has;
    if (btnPrint) btnPrint.disabled = !has;
  }

  function updateFinalIndexes(){
    if (!finalList) return;
    const cards = finalList.querySelectorAll('.final-card');
    cards.forEach((c, i) => {
      const el = c.querySelector('.final-index');
      if (el) el.textContent = '#' + (i + 1);
    });
  }

  function syncFinalOrderFromDOM(){
    if (!finalList) return;
    const cards = Array.from(finalList.querySelectorAll('.final-card'));
    finalOrder = cards.map(c => String(c.getAttribute('data-code') || '')).filter(Boolean);
    updateFinalIndexes();
  }

  function getFinalExportRows(){
    // DOM sırasına göre export
    normalizeFinalOrder();
    const headers = ['Kurum Adı','Kadro Ünvanı','İl Adı','Merkez/Taşra','Taban Puan','Tavan Puan','Adayın Puanı','Kontenjan','Öğrenim Durumu','Sınıf','Derece'];
    const rows = [];

    for (const code of finalOrder){
      const it = resultItemMap.get(code) || {};
      const kurum = (it.kurum_adi || '-');
      const unvan = (it.kadro_unvani || '-');
      const il = (it.il || it.il_adi || '-');
      const mt = merkezTasraText(it.merkez_tasra);
      const taban = pickScore(it.taban_alt, it.taban_ust);
      const tavan = pickScore(it.tavan_alt, it.tavan_ust);
      const aday = (currentKpss ?? '-');
      const kont = (it.kontenjan ?? '-');
      const ogr = (it.ogrenim_durumu || '-');
      const sinif = (it.sinif || '-');
      const derece = (it.derece || '-');

      rows.push([kurum, unvan, il, mt, taban, tavan, aday, kont, ogr, sinif, derece]);
    }

    return { headers, rows };
  }

  function csvEscape(val){
    const s = (val === null || val === undefined) ? '' : String(val);
    if (/[";\n\r]/.test(s)){
      return '"' + s.replace(/"/g, '""') + '"';
    }
    return s;
  }

  function downloadFinalExcel(){
    const exp = getFinalExportRows();
    const headers = exp.headers;
    const rows = exp.rows;

    let csv = headers.map(csvEscape).join(';') + '\n';
    for (const r of rows){
      csv += r.map(csvEscape).join(';') + '\n';
    }

    // Excel için UTF-8 BOM
    const blob = new Blob(['\ufeff' + csv], { type: 'text/csv;charset=utf-8;' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'secilen_kadrolar.csv';
    document.body.appendChild(a);
    a.click();
    a.remove();
    setTimeout(() => URL.revokeObjectURL(url), 2500);
  }

  function escapeHtml(s){
    return String(s)
      .replace(/&/g,'&amp;')
      .replace(/</g,'&lt;')
      .replace(/>/g,'&gt;')
      .replace(/"/g,'&quot;')
      .replace(/'/g,'&#39;');
  }


  function toNum(val){
    const s = String(val ?? '').trim();
    if (!s) return NaN;
    return Number(s.replace(',', '.'));
  }

  function formatTr3(val, blankAsZero){
    // blankAsZero=true ise null/''/'-' -> 0,000
    if (val === null || val === undefined) return blankAsZero ? '0,000' : '-';
    const s = String(val).trim();
    if (s === '' || s === '-') return blankAsZero ? '0,000' : '-';
    const n = toNum(s);
    if (!isFinite(n)) return s;
    return n.toFixed(3).replace('.', ',');
  }

  function getPdfOgrenimLabel(){
    const o = String(currentOgrenim || '').trim();
    if (o === 'lisans') return 'Lisans';
    if (o === 'onlisans') return 'Önlisans';
    if (o === 'ortaogretim') return 'Ortaöğretim';
    // zaten metin ise
    if (o) return o.charAt(0).toUpperCase() + o.slice(1);
    return '-';
  }

  function getFinalPdfRows(){
    // DOM sırasına göre PDF satırları
    normalizeFinalOrder();
    const rows = [];
    const adayNum = toNum(currentKpss);

    for (const code of finalOrder){
      const it = resultItemMap.get(code) || {};

      const kurum = (it.kurum_adi || '-');
      const unvan = (it.kadro_unvani || '-');
      const il = (it.il || it.il_adi || '-');
      const mt = merkezTasraText(it.merkez_tasra); // 0=Taşra, 1=Merkez

      // Taban puan: varsa üst, yoksa alt; yoksa 0
      const tabanVal = (it.taban_ust !== undefined && it.taban_ust !== null && String(it.taban_ust).trim() !== '')
        ? it.taban_ust
        : ((it.taban_alt !== undefined && it.taban_alt !== null && String(it.taban_alt).trim() !== '') ? it.taban_alt : 0);

      const tabanNum = toNum(tabanVal);
      const tabanTxt = formatTr3(tabanVal, true);
      const adayTxt  = formatTr3(currentKpss ?? '-', false);

      // Risk: taban > 0 ve aday < taban
      const risk = (isFinite(tabanNum) && tabanNum > 0 && isFinite(adayNum) && adayNum < tabanNum);

      const kont = (it.kontenjan !== undefined && it.kontenjan !== null && String(it.kontenjan).trim() !== '')
        ? (String(it.kontenjan).trim() + ' Aday')
        : '-';

      const kadroCell =
        String(code) + ' ' + String(kurum) + '\n' +
        String(unvan) + '\n' +
        '(' + String(il) + ' - ' + String(mt) + ')';

      rows.push({
        sira: rows.length + 1,
        kadro: kadroCell,
        taban: tabanTxt,
        aday: adayTxt,
        kont: kont,
        risk: risk
      });
    }

    return rows;
  }

  function openPrintWindow(){
    const ogLabel = getPdfOgrenimLabel();
    const rows = getFinalPdfRows();
    const title = 'TercihSepeti';

    let html = '<!doctype html><html><head><meta charset="utf-8"><title>' + title + '</title>';
    html += '<style>'
      + '@page{size:A4; margin:18mm;}'
      + 'body{font-family:Arial,Helvetica,sans-serif; color:#000;}'
      + '.top{font-size:14px; margin:0 0 14px;}'
      + '.wrap{width:86%;}'
      + 'table{width:100%; border-collapse:collapse; font-size:11px;}'
      + 'th,td{border:1px solid #000; padding:6px; vertical-align:top;}'
      + 'th{font-weight:normal; text-align:left;}'
      + '.col-sira{width:40px;}'
      + '.col-kadro{width:70%;}'
      + '.col-n{width:90px;}'
      + '.risk{background:#fff2a8;}'
      + '.aciklama-title{margin:18px 0 6px; font-size:12px;}'
      + '.aciklama{font-size:11px; line-height:1.35;}'
      + '</style></head><body><div class="wrap">';

    html += '<div class="top">Öğrenim Durumu : ' + escapeHtml(ogLabel) + '</div>';

    html += '<table><thead><tr>'
      + '<th class="col-sira">Sıra</th>'
      + '<th class="col-kadro">Kadro</th>'
      + '<th class="col-n">Taban Puan</th>'
      + '<th class="col-n">Adayın<br>Puanı</th>'
      + '<th class="col-n">Kontenjan</th>'
      + '</tr></thead><tbody>';

    for (const r of rows){
      html += '<tr class="' + (r.risk ? 'risk' : '') + '">'
        + '<td>' + escapeHtml(String(r.sira)) + '</td>'
        + '<td>' + escapeHtml(String(r.kadro)).replace(/\n/g,'<br>') + '</td>'
        + '<td>' + escapeHtml(String(r.taban)) + '</td>'
        + '<td>' + escapeHtml(String(r.aday)) + '</td>'
        + '<td>' + escapeHtml(String(r.kont)) + '</td>'
        + '</tr>';
    }

    html += '</tbody></table>';

    html += '<div class="aciklama-title">Açıklamalar</div>';
    html += '<div class="aciklama">'
      + 'SARIYLA RENKLENDİRİLEN KADROLAR YERLEŞMENİZİN RİSKLİ OLDUĞU KADROLARDIR. ANCAK ÇOK İSTİYORSANIZ TERCİH LİSTENİZE YAZMANIZDA YARAR VARDIR<br>'
      + 'Yeni açılan kadroların taban puanları oluşmadığı için tercihlerinizde dikkat ediniz.<br>'
      + 'Tüm veriler ÖSYM kaynaklı verilerdir.'
      + '</div>';

    html += '</div></body></html>';

    const w = window.open('', '_blank', 'noopener,noreferrer,width=900,height=900');
    if (!w) return;
    w.document.open();
    w.document.write(html);
    w.document.close();
    w.focus();
    setTimeout(() => { try{ w.print(); }catch(e){} }, 250);
  }

  async function downloadFinalPdf(){
    // En düzgün Türkçe + layout için tarayıcı Yazdır (PDF olarak kaydet)
    openPrintWindow();
    return;
    // Örnek PDF formatına (TercihSepeti) mümkün olduğunca benzer çıktı üretir
    try{
      const rows = getFinalPdfRows();
      const ogLabel = getPdfOgrenimLabel();

      if (!(window.jspdf && window.jspdf.jsPDF)) throw new Error('jsPDF yok');

      const { jsPDF } = window.jspdf;
      const doc = new jsPDF({ orientation:'portrait', unit:'pt', format:'a4' });

      // Türkçe karakterler için DejaVu fontunu yükle (server-side base64 endpoint)
      async function ensureTrFont(){
        try{
          const cacheKey = 'dejavu_font_b64_v1';
          let b64 = null;
          try{ b64 = localStorage.getItem(cacheKey); }catch(e){}

          if (!b64 || b64.length < 1000){
            const u = new URL(window.location.href);
            u.searchParams.set('asset','dejavu_font');
            // debug paramı gibi şeyler sorun çıkarmaz ama temizleyelim
            u.searchParams.delete('debug');
            const res = await fetch(u.toString(), { cache:'force-cache' });
            b64 = await res.text();
            try{ if (b64 && b64.length > 1000) localStorage.setItem(cacheKey, b64); }catch(e){}
          }

          if (b64 && b64.length > 1000 && doc.addFileToVFS){
            doc.addFileToVFS('DejaVuSansCondensed.ttf', b64);
            doc.addFont('DejaVuSansCondensed.ttf', 'DejaVu', 'normal');
            doc.setFont('DejaVu','normal');
            return true;
          }
        }catch(e){}
        // fallback
        doc.setFont('helvetica','normal');
        return false;
      }

      await ensureTrFont();

      const pageW = doc.internal.pageSize.getWidth();
      const pageH = doc.internal.pageSize.getHeight();

      // Referans PDF'te tablo dar ve solda; aynı hissi vermek için genişliği sabitliyoruz
      const marginL = 40;
      const marginT = 40;
      const marginB = 50;

      const tableX = marginL;
      const tableW = Math.min(400, pageW - marginL - 160); // sağda boşluk bıraksın
      const wSira = 28;
      const wTaban = 62;
      const wAday  = 62;
      const wKont  = 70;
      const wKadro = tableW - (wSira + wTaban + wAday + wKont);

      const pad = 4;
      const headerH = 22;
      const lineH = 10;
      const rowMinH = 22;

      doc.setLineWidth(0.5);

      function drawGrid(x, yy, h){
        doc.rect(x, yy, tableW, h);
        doc.line(x + wSira, yy, x + wSira, yy + h);
        doc.line(x + wSira + wKadro, yy, x + wSira + wKadro, yy + h);
        doc.line(x + wSira + wKadro + wTaban, yy, x + wSira + wKadro + wTaban, yy + h);
        doc.line(x + wSira + wKadro + wTaban + wAday, yy, x + wSira + wKadro + wTaban + wAday, yy + h);
      }

      function drawTitleAndHeader(resetY){
        let y = resetY;

        doc.setFontSize(9);
        doc.text('Öğrenim Durumu : ' + ogLabel, marginL, y);
        y += 12;

        // Başlık satırı
        doc.setFontSize(7.5);
        drawGrid(tableX, y, headerH);

        doc.text('Sıra', tableX + (wSira/2), y + 14, { align:'center' });
        doc.text('Kadro', tableX + wSira + pad, y + 14);

        doc.text('Taban Puan', tableX + wSira + wKadro + (wTaban/2), y + 14, { align:'center' });

        // Adayın Puanı iki satır gibi (referanstaki gibi)
        const ax = tableX + wSira + wKadro + wTaban + (wAday/2);
        doc.text('Adayın', ax, y + 10, { align:'center' });
        doc.text('Puanı',  ax, y + 18, { align:'center' });

        doc.text('Kontenjan', tableX + wSira + wKadro + wTaban + wAday + (wKont/2), y + 14, { align:'center' });

        y += headerH;
        return y;
      }

      let y = drawTitleAndHeader(marginT + 10);

      for (const r of rows){
        doc.setFontSize(7.5);

        // Kadro hücresini satır satır yazdır; her satırı hücre genişliğine göre sar
        const parts = String(r.kadro || '').split('\n');
        let kadroLines = [];
        for (const p of parts){
          const lns = doc.splitTextToSize(p, wKadro - 2*pad);
          kadroLines = kadroLines.concat(lns);
        }

        const rowH = Math.max(rowMinH, (kadroLines.length * lineH) + (2*pad));

        // Sayfa sonu kontrol
        if (y + rowH + 90 > (pageH - marginB)){
          doc.addPage();
          y = drawTitleAndHeader(marginT + 10);
        }

        // Riskli satır sarı
        if (r.risk){
          doc.setFillColor(255, 255, 153);
          doc.rect(tableX, y, tableW, rowH, 'F');
        }

        drawGrid(tableX, y, rowH);

        // Sıra
        doc.text(String(r.sira), tableX + (wSira/2), y + 14, { align:'center' });

        // Kadro
        let yy = y + pad + 8;
        for (const ln of kadroLines){
          if (yy > y + rowH - pad) break;
          doc.text(String(ln), tableX + wSira + pad, yy);
          yy += lineH;
        }

        // Taban / Aday / Kontenjan
        doc.text(String(r.taban), tableX + wSira + wKadro + (wTaban/2), y + 14, { align:'center' });
        doc.text(String(r.aday),  tableX + wSira + wKadro + wTaban + (wAday/2), y + 14, { align:'center' });
        doc.text(String(r.kont),  tableX + wSira + wKadro + wTaban + wAday + (wKont/2), y + 14, { align:'center' });

        y += rowH;
      }

      // Açıklamalar
      y += 10;
      if (y + 70 > (pageH - marginB)){
        doc.addPage();
        y = marginT + 10;
      }

      doc.setFontSize(8.5);
      doc.text('Açıklamalar', tableX, y);
      y += 12;

      doc.setFontSize(7.5);
      const wrapW = tableW;
      const exp1 = "SARIYLA RENKLENDİRİLEN KADROLAR YERLEŞMENİZİN RİSKLİ OLDUĞU KAD...ANCAK ÇOK İSTİYORSANIZ TERCİH LİSTENİZE YAZMANIZDA YARAR VARDIR";
      const exp2 = "Yeni açılan kadroların taban puanları oluşmadığı için tercihlerinizde dikkat ediniz.";
      const exp3 = "Tüm veriler ÖSYM kaynaklı verilerdir.";

      const l1 = doc.splitTextToSize(exp1, wrapW);
      doc.text(l1, tableX, y); y += l1.length * lineH;

      const l2 = doc.splitTextToSize(exp2, wrapW);
      doc.text(l2, tableX, y); y += l2.length * lineH;

      const l3 = doc.splitTextToSize(exp3, wrapW);
      doc.text(l3, tableX, y);

      doc.save('TercihSepeti.pdf');
      return;
    }catch(e){
      // fallthrough
    }

    // Fallback: tarayıcıdan "PDF olarak kaydet"
    openPrintWindow();
  }


  // Final list reorder (delegation)
  (function wireFinalReorder(){
    if (!finalList) return;

    let draggingEl = null;

    function getDragAfterElement(container, y){
      const els = [...container.querySelectorAll('.final-card:not(.dragging)')];
      return els.reduce((closest, child) => {
        const box = child.getBoundingClientRect();
        const offset = y - box.top - box.height / 2;
        if (offset < 0 && offset > closest.offset){
          return { offset, element: child };
        } else {
          return closest;
        }
      }, { offset: Number.NEGATIVE_INFINITY, element: null }).element;
    }

    finalList.addEventListener('dragstart', (e) => {
      const card = e.target && e.target.closest ? e.target.closest('.final-card') : null;
      if (!card) return;
      draggingEl = card;
      card.classList.add('dragging');
      try{
        e.dataTransfer.effectAllowed = 'move';
        e.dataTransfer.setData('text/plain', card.getAttribute('data-code') || '');
      } catch(err){}
    });

    finalList.addEventListener('dragover', (e) => {
      if (!draggingEl) return;
      e.preventDefault();
      const afterEl = getDragAfterElement(finalList, e.clientY);
      if (!afterEl){
        finalList.appendChild(draggingEl);
      } else if (afterEl !== draggingEl){
        finalList.insertBefore(draggingEl, afterEl);
      }
    });

    finalList.addEventListener('dragend', () => {
      if (draggingEl){
        draggingEl.classList.remove('dragging');
        draggingEl = null;
      }
      syncFinalOrderFromDOM();
    });

    // Up/Down buttons
    finalList.addEventListener('click', (e) => {
      const btn = e.target && e.target.closest ? e.target.closest('button[data-move]') : null;
      if (!btn) return;

      const dir = btn.getAttribute('data-move');
      const card = btn.closest('.final-card');
      if (!card) return;

      e.preventDefault();
      e.stopPropagation();

      if (dir === 'up'){
        const prev = card.previousElementSibling;
        if (prev) finalList.insertBefore(card, prev);
      } else if (dir === 'down'){
        const next = card.nextElementSibling;
        if (next) finalList.insertBefore(next, card);
      }
      syncFinalOrderFromDOM();
    });
  })();
  // Export buttons (server-side PDF/XLSX)
  // PDF/Yazdır: popup blocker'a takılmamak için form POST ile yeni sekmede yazdırılabilir HTML açıyoruz
  
// ==========================
// Export / Yazdır (Step7) - aynı sekmede, popup yok
// ==========================
const exportErrorBox = document.getElementById('exportError');

function showExportError(msg){
  if (!exportErrorBox){ alert(msg); return; }
  exportErrorBox.textContent = msg;
  exportErrorBox.hidden = false;
}
function clearExportError(){
  if (!exportErrorBox) return;
  exportErrorBox.textContent = '';
  exportErrorBox.hidden = true;
}

// İndirme (Form POST) - kullanıcı tıklamasıyla direkt başlar, popup yok
function postDownload(action, payloadObj){
  clearExportError();

  const form = document.createElement('form');
  form.method = 'POST';
  form.action = '?action=' + encodeURIComponent(action);
  form.style.display = 'none';

  const input = document.createElement('input');
  input.type = 'hidden';
  input.name = 'payload';
  input.value = JSON.stringify(payloadObj);

  form.appendChild(input);
  document.body.appendChild(form);
  form.submit();

  setTimeout(() => { try{ form.remove(); }catch(e){} }, 1000);
}

// Export butonları
const btnExportExcel2 = document.getElementById('btnExportExcel');
const btnExportPdf2   = document.getElementById('btnExportPdf');
const btnPrint2       = document.getElementById('btnPrint');

if (btnExportExcel2){
  btnExportExcel2.addEventListener('click', () => {
    if (btnExportExcel2.disabled || selectedResultSet.size === 0) return;
    const exp = getFinalExportRows();
    postDownload('download_xlsx', { headers: exp.headers, rows: exp.rows });
  });
}

if (btnExportPdf2){
  btnExportPdf2.addEventListener('click', () => {
    if (btnExportPdf2.disabled || selectedResultSet.size === 0) return;
    postDownload('download_pdf', { ogLabel: getPdfOgrenimLabel(), rows: getFinalPdfRows() });
  });
}

// Yazdır (aynı sayfa)
function escapeHtml(s){
  return String(s ?? '').replace(/[&<>"']/g, (ch) => ({
    '&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'
  }[ch]));
}

function renderPrintArea(){
  const area = document.getElementById('printArea');
  if (!area) return;

  const ogLabel = getPdfOgrenimLabel();
  const rows = getFinalPdfRows();

  let html = '';
  html += '<div class="print-paper">';
  html += '<div class="print-top">Öğrenim Durumu : ' + escapeHtml(ogLabel) + '</div>';

  html += '<table class="print-table"><thead><tr>';
  html += '<th class="c-sira">Sıra</th>';
  html += '<th class="c-kadro">Kadro</th>';
  html += '<th class="c-num">Taban Puan</th>';
  html += '<th class="c-num">Adayın<br>Puanı</th>';
  html += '<th class="c-kont">Kontenjan</th>';
  html += '</tr></thead><tbody>';

  for (const r of rows){
    const bg = r.risk ? ' class="risk"' : '';
    const kadro = escapeHtml(r.kadro).replace(/\n/g,'<br>');
    html += '<tr' + bg + '>';
    html += '<td>' + escapeHtml(r.sira) + '</td>';
    html += '<td class="kadro">' + kadro + '</td>';
    html += '<td>' + escapeHtml(r.taban) + '</td>';
    html += '<td>' + escapeHtml(r.aday) + '</td>';
    html += '<td>' + escapeHtml(r.kont) + '</td>';
    html += '</tr>';
  }

  html += '</tbody></table>';

  html += '<div class="print-acik-title">Açıklamalar</div>';
  html += '<div class="print-acik">';
  html += 'SARIYLA RENKLENDİRİLEN KADROLAR YERLEŞMENİZİN RİSKLİ OLDUĞU KADROLARDIR. ÇOK İSTİYORSANIZ TERCİH LİSTENİZE YAZMANIZDA YARAR VARDIR<br>';
  html += 'Yeni açılan kadroların taban puanları oluşmadığı için tercihlerinizde dikkat ediniz.<br>';
  html += 'Tüm veriler ÖSYM kaynaklı verilerdir.';
  html += '</div>';

  html += '</div>';

  area.innerHTML = html;
  area.hidden = false;

  setTimeout(() => { try{ window.print(); }catch(e){} }, 50);
}

if (btnPrint2){
  btnPrint2.addEventListener('click', () => {
    if (btnPrint2.disabled || selectedResultSet.size === 0) return;
    renderPrintArea();
  });
}

window.addEventListener('afterprint', () => {
  const area = document.getElementById('printArea');
  if (area){
    area.hidden = true;
    area.innerHTML = '';
  }
});

function appendResultItems(items){
    const frag = document.createDocumentFragment();

    const fmt = (v) => {
      if (v === 0) return '0';
      if (v === null || v === undefined) return '-';
      const s = String(v).trim();
      return s ? s : '-';
    };

    const mkField = (label, value) => {
      const row = document.createElement('div');
      row.className = 'result-field';

      const l = document.createElement('span');
      l.className = 'result-label';
      l.textContent = label;

      const sep = document.createElement('span');
      sep.className = 'result-sep';
      sep.textContent = ' : ';

      const v = document.createElement('span');
      v.className = 'result-value';
      v.textContent = fmt(value);

      row.appendChild(l);
      row.appendChild(sep);
      row.appendChild(v);
      return row;
    };

    for (const it of (items || [])){
      const code = it.kodu ? String(it.kodu).trim() : '';

      const card = document.createElement('div');
      card.className = 'result-card';
      if (code) card.dataset.kodu = code;

      // Daha önce seçildiyse (sayfalama), yeşil olsun
      if (code && selectedResultSet.has(code)) card.classList.add('is-selected');

            // Seçim kutusu
      const chk = document.createElement('input');
      chk.type = 'checkbox';
      chk.className = 'result-check';
      chk.checked = (code && selectedResultSet.has(code));
      chk.addEventListener('click', (e) => { e.stopPropagation(); });
      chk.addEventListener('change', () => {
        setResultSelected(code, chk.checked, card, chk, it);
      });

      // Kart tıklanınca seç/kaldır (koşullar hariç)
      if (code){
        card.addEventListener('click', (e) => {
          if (e.target && e.target.closest && (e.target.closest('details') || e.target.closest('input.result-check'))) return;
          toggleResultSelection(code, card, chk, it);
        });
      }

      const top = document.createElement('div');
      top.className = 'result-top';

      const left = document.createElement('div');
      left.className = 'result-left';

      const headTexts = document.createElement('div');
      headTexts.className = 'result-headtexts';

      const title = document.createElement('div');
      title.className = 'result-title';
      title.textContent = (it.kurum_adi || '');

      const sub = document.createElement('div');
      sub.className = 'result-subtitle';
      sub.textContent = (it.kadro_unvani || '-');

      headTexts.appendChild(title);
      headTexts.appendChild(sub);

      left.appendChild(chk);
      left.appendChild(headTexts);

      const kod = document.createElement('div');
      kod.className = 'result-kodu';
      kod.textContent = code ? ('#' + code) : '';

      top.appendChild(left);
      top.appendChild(kod);
const fields = document.createElement('div');
      fields.className = 'result-fields';

      const mt = merkezTasraText(it.merkez_tasra);

      // İstenen alanlar (alt alta + ':' formatı)
      fields.appendChild(mkField('İl Adı', (it.il || it.il_adi || '-')));
      fields.appendChild(mkField('Merkez/Taşra', mt));
      fields.appendChild(mkField('Taban Puan', pickScore(it.taban_alt, it.taban_ust)));
      fields.appendChild(mkField('Tavan Puan', pickScore(it.tavan_alt, it.tavan_ust)));
      fields.appendChild(mkField('Adayın Puanı', (currentKpss ?? '-')));
      fields.appendChild(mkField('Kontenjan', (it.kontenjan ?? '-')));
      fields.appendChild(mkField('Öğrenim Durumu', (it.ogrenim_durumu || '-')));
      fields.appendChild(mkField('Sınıf', (it.sinif || '-')));
      fields.appendChild(mkField('Derece', (it.derece || '-')));

      // Koşullar (Nitelik kodları) - açılır alan
      const details = document.createElement('details');
      details.className = 'result-cond';

      const summary = document.createElement('summary');
      summary.textContent = 'Koşullar (aç/kapat)';
      details.appendChild(summary);

      const body = document.createElement('div');
      body.className = 'result-cond-body';
      body.textContent = 'Koşullar yükleniyor…';
      details.appendChild(body);

      // Koşullara tıklayınca kart seçilmesin
      details.addEventListener('click', (e) => { e.stopPropagation(); });

      details.addEventListener('toggle', async () => {
        if (!details.open) return;

        // daha önce yüklendiyse tekrar çizme
        if (details.dataset.loaded === '1') return;

        const codes = parseNitelikCodes(it.nitelik_kodlari || '');
        if (!codes.length){
          body.textContent = 'Koşul yok.';
          details.dataset.loaded = '1';
          return;
        }

        try{
          await fetchNitelikTexts(codes);

          const ul = document.createElement('ul');
          for (const c of codes){
            const li = document.createElement('li');
            const t = nitCache.get(c) || '';
            li.textContent = t ? `${c} — ${t}` : `${c} — Koşul bulunamadı.`;
            ul.appendChild(li);
          }
          body.innerHTML = '';
          body.appendChild(ul);
          details.dataset.loaded = '1';
        } catch(err){
          body.textContent = (err && err.message) ? err.message : 'Koşullar yüklenemedi.';
          // hata olursa retry için loaded set etme
        }
      });

      card.appendChild(top);
      card.appendChild(fields);
      card.appendChild(details);

      // Özet için item map
      if (code) resultItemMap.set(code, it);

      frag.appendChild(card);
    }

    if (resultList) resultList.appendChild(frag);
  }
  async function loadResultNextPage(reset=false){
    if (resultLoading) return;
    resultLoading = true;

    if (reset) {
      resetResultList();
      selectedResultSet = new Set();
      resultItemMap = new Map();
      updateResultSelectedMini();
    }

    if (resultAbort) resultAbort.abort();
    resultAbort = new AbortController();

    setMiniStatus(resultMiniStatus, 'Yükleniyor…');
    updateResultStatus();

    try{
      const params = new URLSearchParams();
      params.append('ajax', 'kadrolar_list');
      params.append('ogrenim', currentOgrenim);
      params.append('offset', String(resultOffset));
      params.append('limit', String(RESULT_LIMIT));
      params.append('want_total', reset ? '1' : '0');

      for (const c of selectedCities) params.append('cities[]', c);
      for (const u of selectedKadroSet) params.append('unvanlar[]', u);
      for (const kod of selectedNitSet) params.append('nitelik_kodlari[]', kod);

      const res = await fetch(location.href, {
        method: 'POST',
        headers: {'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'},
        body: params.toString(),
        signal: resultAbort.signal
      });

      const data = await res.json();
      if (!data || data.ok !== true){
        throw new Error((data && data.error) ? data.error : 'Sonuçlar alınamadı.');
      }

      const items = Array.isArray(data.items) ? data.items : [];
      if (reset && Number.isFinite(+data.total)) resultTotal = +data.total;

      appendResultItems(items);

      resultOffset = Number.isFinite(+data.nextOffset) ? +data.nextOffset : (resultOffset + items.length);
      resultHasMore = !!data.hasMore;

      if (resultOffset === 0 && ((resultTotal != null && resultTotal === 0) || items.length === 0)){
        setMiniStatus(resultMiniStatus, 'Sonuç bulunamadı');
        if (reset){
          showStyledResultAlert('İlgili kadronun istenilen niteliklerine sahip değilsiniz!');
        }
      }

    } catch(err){
      if (err && err.name === 'AbortError'){
        // sessiz
      } else {
        setErr(resultErr, (err && err.message) ? err.message : 'Bir hata oluştu.');
      }
    } finally {
      resultLoading = false;
      updateResultStatus();
    }
  }

btnBack4.addEventListener('click', () => {
    showOnly(3);
  });

  btnBack5.addEventListener('click', () => {
    showOnly(4);
  });



  // Step6 geri dön
  if (btnBack6){
    btnBack6.addEventListener('click', () => {
      showOnly(5);
    });
  }

  // Step7 geri dön
  if (btnBack7){
    btnBack7.addEventListener('click', () => {
      showOnly(6);
    });
  }

  // Step6 Devam Et (seçilenleri kaydet / özetle)
  if (btnNext6){
    btnNext6.addEventListener('click', () => {
      setErr(resultErr, '');
      if (selectedResultSet.size === 0){
        setErr(resultErr, 'Lütfen en az 1 sonuç seçin.');
        return;
      }
      renderFinalSelections();
      showOnly(7);
    });
  }

  // Step5 -> Step6
  if (btnNext5){
    btnNext5.addEventListener('click', async () => {
      setErr(nitErr, '');
      showOnly(6);
      updateResultSelectedMini();
      if (resultScoreInfo) resultScoreInfo.textContent = 'Adayın Puanı : ' + String(currentKpss || '');
      await loadResultNextPage(true);
    });
  }

  if (btnResultMore){
    btnResultMore.addEventListener('click', () => {
      loadResultNextPage(false);
    });
  }

  btnNext4.addEventListener('click', async () => {
    setErr(kadroErr, '');
    if (selectedKadroSet.size === 0){
      setErr(kadroErr, 'Lütfen en az 1 kadro ünvanı seçin.');
      return;
    }

    // Step5'e geç ve nitelikleri getir
    showOnly(5);
    setErr(nitErr, '');
    if (nitInfo) nitInfo.textContent = '';
    nitList.innerHTML = '';
    selectedNitSet = new Set();
    nitTotalCount = 0;
    updateNitMini();

    try{
      const data = await loadKadroNitelikler();
      renderNitelikler(data.items || []);
    } catch(err){
      setErr(nitErr, err && err.message ? err.message : 'Nitelikler yüklenemedi.');
      if (nitInfo) nitInfo.textContent = '';
    }
  });

  // İlk durum
  showOnly(1);
  updateResultSelectedMini();
})();
</script>


  <div id="printArea" class="print-area" hidden></div>
  
  <!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-TLZ841LTVZ"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'G-TLZ841LTVZ');
</script>
</body>
</html>
