<?php
declare(strict_types=1);

/**
 * TEST TANIMLARI (Lokal Testler) - FULL WIDTH (TOPBAR ONLY)
 * - Tablo: test_tanimlari
 * - DışLab eşleme: dislab_mapping_id -> dislab_test_listesi.id
 * - Mobil: kart, Desktop: tablo
 * - Otomatik Test Kodu: seçilen branşa göre PREFIX-### üretir
 *
 * Not: Sidebar/Header YOK. Sadece topbar.php include edilir.
 */

if (session_status() === PHP_SESSION_NONE) { session_start(); }

/* -----------------------------
   Helper
------------------------------ */
if (!function_exists('e')) {
  function e(?string $s): string { return htmlspecialchars((string)($s ?? ''), ENT_QUOTES, 'UTF-8'); }
}
function as_int($v, $d=0){ return is_numeric($v) ? (int)$v : $d; }
function as_str($v, $d=''){ $v = (string)($v ?? ''); return $v !== '' ? $v : $d; }

/* -----------------------------
   DB resolve
------------------------------ */
global $db, $conn, $pdo;
$db_obj = is_object($db) ? $db : (is_object($conn) ? $conn : $pdo);
if (!$db_obj) {
  $db_path = realpath(__DIR__ . '/../core/db.php');
  if ($db_path && file_exists($db_path)) require_once $db_path;
  $db_obj = is_object($db) ? $db : (is_object($conn) ? $conn : $pdo);
}
if (!$db_obj || !($db_obj instanceof PDO)) { die("DB bağlantısı bulunamadı."); }

/* -----------------------------
   Enum values (SHOW COLUMNS ile)
------------------------------ */
function enum_values(PDO $pdo, string $table, string $col): array {
  try {
    $st = $pdo->query("SHOW COLUMNS FROM `$table` LIKE " . $pdo->quote($col));
    $row = $st->fetch(PDO::FETCH_ASSOC);
    if (!$row) return [];
    $type = (string)$row['Type'];
    if (!str_starts_with($type, 'enum(')) return [];
    $inside = substr($type, 5, -1);
    $vals = array_map(fn($x) => trim($x, " '\""), explode(',', $inside));
    return array_values(array_filter($vals, fn($x) => $x !== ''));
  } catch (Throwable $e) {
    return [];
  }
}

/* ---------------------------------------------------------
   Otomatik Kod - Branş -> PREFIX üret
------------------------------------------------------------ */
function brans_to_prefix(string $brans): string {
  $s = trim($brans);
  if ($s === '') return '';

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

  $s = preg_replace('/[^A-Z0-9]/u', '', $s) ?? '';
  if ($s === '') return 'TST';

  return substr($s, 0, 3);
}

function next_test_code(PDO $pdo, string $brans): ?string {
  $prefix = brans_to_prefix($brans);
  if ($prefix === '') return null;

  $st = $pdo->prepare("
    SELECT test_kodu
    FROM test_tanimlari
    WHERE brans = ?
      AND test_kodu IS NOT NULL
      AND test_kodu REGEXP CONCAT('^', ?, '-[0-9]+$')
    ORDER BY CAST(SUBSTRING_INDEX(test_kodu,'-',-1) AS UNSIGNED) DESC
    LIMIT 1
  ");
  $st->execute([$brans, $prefix]);
  $last = (string)($st->fetchColumn() ?: '');

  $next = 1;
  if ($last !== '' && preg_match('/-(\d+)$/', $last, $m)) {
    $next = ((int)$m[1]) + 1;
  }

  $num = str_pad((string)$next, 3, '0', STR_PAD_LEFT);
  return $prefix . '-' . $num;
}

/* ---------------------------------------------------------
   AJAX
------------------------------------------------------------ */
if (isset($_GET['action'])) {
  while (ob_get_level()) { ob_end_clean(); }
  header('Content-Type: application/json; charset=utf-8');

  // JSON kırılmasın
  ini_set('display_errors', '0');
  ini_set('html_errors', '0');
  error_reporting(E_ALL);

  try {
    $action = as_str($_GET['action']);

    // 0) Branşa göre otomatik kod üret
    if ($action === 'gen_code') {
      $brans = trim(as_str($_GET['brans'] ?? ''));
      if ($brans === '') {
        echo json_encode(['success'=>false,'error'=>'Branş boş'], JSON_UNESCAPED_UNICODE);
        exit;
      }
      $code = next_test_code($db_obj, $brans);
      if (!$code) {
        echo json_encode(['success'=>false,'error'=>'Kod üretilemedi'], JSON_UNESCAPED_UNICODE);
        exit;
      }
      echo json_encode(['success'=>true,'code'=>$code], JSON_UNESCAPED_UNICODE);
      exit;
    }

    // 1) Liste getir (arama+filtre)
    if ($action === 'fetch_list') {
      $q       = trim(as_str($_GET['q'] ?? ''));
      $only    = as_str($_GET['only'] ?? 'all');        // all|active|passive
      $brans   = trim(as_str($_GET['brans'] ?? ''));
      $labtip  = trim(as_str($_GET['labtip'] ?? ''));   // Ic|Dis
      $testtip = trim(as_str($_GET['testtip'] ?? ''));  // Ana Test|Alt Test|Panel/Grup
      $limit   = max(20, min(200, as_int($_GET['limit'] ?? 120)));

      $sql = "
        SELECT
          t.*,
          d.dislab_kodu AS dislab_kodu,
          d.dislab_adi  AS dislab_adi
        FROM test_tanimlari t
        LEFT JOIN dislab_test_listesi d ON d.id = t.dislab_mapping_id
        WHERE 1=1
      ";
      $params = [];

      if ($only === 'active') { $sql .= " AND t.is_active = 1"; }
      if ($only === 'passive') { $sql .= " AND t.is_active = 0"; }

      if ($brans !== '') { $sql .= " AND t.brans = ?"; $params[] = $brans; }
      if ($labtip !== '') { $sql .= " AND t.laboratuvar_tipi = ?"; $params[] = $labtip; }
      if ($testtip !== '') { $sql .= " AND t.test_tipi = ?"; $params[] = $testtip; }

      if ($q !== '') {
        $sql .= " AND (
          t.test_adi LIKE ?
          OR t.test_kodu LIKE ?
          OR t.sut_kodu LIKE ?
          OR d.dislab_kodu LIKE ?
          OR d.dislab_adi  LIKE ?
        )";
        $like = "%{$q}%";
        $params[] = $like; $params[] = $like; $params[] = $like; $params[] = $like; $params[] = $like;
      }

      $sql .= " ORDER BY t.is_active DESC, t.brans ASC, t.siralama ASC, t.test_adi ASC LIMIT {$limit}";

      $st = $db_obj->prepare($sql);
      $st->execute($params);
      $items = $st->fetchAll(PDO::FETCH_ASSOC);

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

    // 2) Tek kayıt getir (edit)
    if ($action === 'get_one') {
      $id = as_int($_GET['id'] ?? 0);
      if ($id <= 0) throw new Exception("Geçersiz ID");

      $st = $db_obj->prepare("
        SELECT t.*,
               d.dislab_kodu AS dislab_kodu,
               d.dislab_adi  AS dislab_adi
        FROM test_tanimlari t
        LEFT JOIN dislab_test_listesi d ON d.id = t.dislab_mapping_id
        WHERE t.id = ?
        LIMIT 1
      ");
      $st->execute([$id]);
      $row = $st->fetch(PDO::FETCH_ASSOC);
      if (!$row) throw new Exception("Kayıt bulunamadı");

      echo json_encode(['success'=>true,'item'=>$row], JSON_UNESCAPED_UNICODE);
      exit;
    }

    // 3) Parent listesi
    if ($action === 'parents') {
      $exclude = as_int($_GET['exclude'] ?? 0);

      $sql = "SELECT id, test_adi, test_kodu, test_tipi FROM test_tanimlari WHERE is_active=1";
      $params = [];
      if ($exclude > 0) { $sql .= " AND id <> ?"; $params[] = $exclude; }
      $sql .= " ORDER BY test_tipi DESC, test_adi ASC LIMIT 500";

      $st = $db_obj->prepare($sql);
      $st->execute($params);
      $rows = $st->fetchAll(PDO::FETCH_ASSOC);

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

    // 4) Kaydet (insert/update)
    if ($action === 'save') {
      $payload = $_POST;

      $id = as_int($payload['id'] ?? 0);

      $test_adi = trim(as_str($payload['test_adi'] ?? ''));
      $test_kodu = trim(as_str($payload['test_kodu'] ?? ''));
      $sut_kodu = trim(as_str($payload['sut_kodu'] ?? ''));
      $brans = trim(as_str($payload['brans'] ?? ''));
      $test_tipi = trim(as_str($payload['test_tipi'] ?? ''));
      $parent_id = as_int($payload['parent_id'] ?? 0);
      $numune_kabi = trim(as_str($payload['numune_kabi'] ?? ''));
      $numune_turu = trim(as_str($payload['numune_turu'] ?? ''));
      $stabilite_sartlari = trim(as_str($payload['stabilite_sartlari'] ?? ''));
      $laboratuvar_tipi = trim(as_str($payload['laboratuvar_tipi'] ?? 'Ic'));
      $dislab_mapping_id = ($payload['dislab_mapping_id'] ?? '') === '' ? null : as_int($payload['dislab_mapping_id']);
      $maliyet = (string)($payload['maliyet'] ?? '0');
      $birim_fiyat = (string)($payload['birim_fiyat'] ?? '0');
      $is_active = as_int($payload['is_active'] ?? 1);
      $siralama = as_int($payload['siralama'] ?? 0);

      if ($test_adi === '') throw new Exception("Test adı zorunlu.");
      if ($brans === '') throw new Exception("Branş seçmelisin.");
      if ($test_tipi === '') throw new Exception("Test tipi seçmelisin.");
      if ($laboratuvar_tipi !== 'Ic' && $laboratuvar_tipi !== 'Dis') throw new Exception("Laboratuvar tipi hatalı.");

      // Dış lab ise eşleme zorunlu
      if ($laboratuvar_tipi === 'Dis' && (!$dislab_mapping_id || $dislab_mapping_id <= 0)) {
        throw new Exception("Dış laboratuvar testi için Dış Lab Test Eşlemesi seçmelisin.");
      }

      $parent_db = $parent_id > 0 ? $parent_id : 0;

      // test_kodu boş bırakılırsa backend de otomatik üret
      if ($test_kodu === '') {
        $auto = next_test_code($db_obj, $brans);
        if ($auto) $test_kodu = $auto;
      }

      if ($id > 0) {
        $st = $db_obj->prepare("
          UPDATE test_tanimlari SET
            test_adi=?, test_kodu=?, sut_kodu=?, brans=?, test_tipi=?, parent_id=?,
            numune_kabi=?, numune_turu=?, stabilite_sartlari=?, laboratuvar_tipi=?,
            dislab_mapping_id=?, maliyet=?, birim_fiyat=?, is_active=?, siralama=?
          WHERE id=?
        ");
        $st->execute([
          $test_adi, $test_kodu ?: null, $sut_kodu ?: null, $brans, $test_tipi, $parent_db,
          $numune_kabi ?: null, $numune_turu ?: null, $stabilite_sartlari ?: null, $laboratuvar_tipi,
          $dislab_mapping_id, $maliyet, $birim_fiyat, $is_active, $siralama,
          $id
        ]);
      } else {
        $st = $db_obj->prepare("
          INSERT INTO test_tanimlari
            (test_adi, test_kodu, sut_kodu, brans, test_tipi, parent_id,
             numune_kabi, numune_turu, stabilite_sartlari, laboratuvar_tipi,
             dislab_mapping_id, maliyet, birim_fiyat, is_active, siralama)
          VALUES
            (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
        ");
        $st->execute([
          $test_adi, $test_kodu ?: null, $sut_kodu ?: null, $brans, $test_tipi, $parent_db,
          $numune_kabi ?: null, $numune_turu ?: null, $stabilite_sartlari ?: null, $laboratuvar_tipi,
          $dislab_mapping_id, $maliyet, $birim_fiyat, $is_active, $siralama
        ]);
        $id = (int)$db_obj->lastInsertId();
      }

      echo json_encode(['success'=>true,'id'=>$id,'test_kodu'=>$test_kodu], JSON_UNESCAPED_UNICODE);
      exit;
    }

    // 5) Sil
    if ($action === 'delete') {
      $id = as_int($_POST['id'] ?? 0);
      if ($id <= 0) throw new Exception("Geçersiz ID");
      $st = $db_obj->prepare("DELETE FROM test_tanimlari WHERE id=?");
      $st->execute([$id]);
      echo json_encode(['success'=>true], JSON_UNESCAPED_UNICODE);
      exit;
    }

    // 6) Çoklu sil
    if ($action === 'bulk_delete') {
      $ids_raw = $_POST['ids'] ?? [];
      if (!is_array($ids_raw)) throw new Exception("IDs format hatalı");
      $ids = array_values(array_filter(array_map('intval', $ids_raw), fn($x)=>$x>0));
      if (!$ids) throw new Exception("Seçim yok.");

      $in = implode(',', array_fill(0, count($ids), '?'));
      $st = $db_obj->prepare("DELETE FROM test_tanimlari WHERE id IN ($in)");
      $st->execute($ids);

      echo json_encode(['success'=>true,'deleted'=>count($ids)], JSON_UNESCAPED_UNICODE);
      exit;
    }

    echo json_encode(['success'=>false,'error'=>'Bilinmeyen action.'], JSON_UNESCAPED_UNICODE);
    exit;

  } catch (Throwable $e) {
    echo json_encode(['success'=>false,'error'=>$e->getMessage()], JSON_UNESCAPED_UNICODE);
    exit;
  }
}

/* ---------------------------------------------------------
   UI data
------------------------------------------------------------ */
$brans_list = enum_values($db_obj, 'test_tanimlari', 'brans');
$testtip_list = enum_values($db_obj, 'test_tanimlari', 'test_tipi');
$labtip_list = enum_values($db_obj, 'test_tanimlari', 'laboratuvar_tipi');

if (!$testtip_list) $testtip_list = ['Ana Test','Alt Test','Panel/Grup'];
if (!$labtip_list) $labtip_list = ['Ic','Dis'];

$total = (int)$db_obj->query("SELECT COUNT(*) FROM test_tanimlari")->fetchColumn();

/* ---------------------------------------------------------
   TOPBAR include (SIDEBAR/HEADER YOK)
------------------------------------------------------------ */
$topbar_path = realpath(__DIR__ . '/../layout/topbar.php');
if ($topbar_path && file_exists($topbar_path)) {
  require_once $topbar_path;
}
?>
<!-- Viewport fallback (topbar içinde yoksa mobil kurtarır) -->
<script>
(function(){
  try{
    if(!document.querySelector('meta[name="viewport"]')){
      const m=document.createElement('meta');
      m.name='viewport';
      m.content='width=device-width, initial-scale=1, viewport-fit=cover';
      document.head.appendChild(m);
    }
  }catch(e){}
})();
</script>

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css" rel="stylesheet">

<style>
  :root{
    --bg:#f6f8fc;
    --card:#ffffff;
    --border: rgba(15,23,42,.10);
    --text:#0f172a;
    --muted:#64748b;
    --primary:#2563eb;
    --primary-soft: rgba(37,99,235,.10);
    --success:#16a34a;
    --danger:#ef4444;
    --radius:18px;
  }

  html, body{
    background: var(--bg) !important;
    width:100%;
    max-width:100%;
    overflow-x:hidden;
  }

  /* Full-Width alan */
  .tt-scope{
    font-family: "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
    padding: 18px 16px 26px;
    max-width: none;
    width: 100%;
  }

  .tt-shell{
    width: 100%;
    max-width: none;
    margin: 0;
  }

  .tt-card{
    background:var(--card);
    border:1px solid var(--border);
    border-radius:var(--radius);
    box-shadow: 0 14px 42px rgba(15,23,42,.06);
  }

  .tt-title{
    font-weight: 900;
    letter-spacing: -.02em;
    color: var(--text);
    line-height: 1.15;
  }
  .tt-sub{ color:var(--muted); font-weight:600; }

  .tt-pill{
    border-radius:999px;
    padding:.45rem .75rem;
    font-weight:800;
    font-size:.78rem;
  }

  .tt-input{
    border-radius:14px;
    border:1px solid rgba(15,23,42,.12);
    padding:.70rem .90rem;
    font-weight:600;
    background:#fff;
  }
  .tt-input:focus{
    box-shadow:0 0 0 .18rem rgba(37,99,235,.14);
    border-color:rgba(37,99,235,.45);
    outline:0;
  }

  .tt-btn{ border-radius:14px; font-weight:800; }
  .tt-btn.btn-primary{
    box-shadow: 0 12px 26px rgba(37,99,235,.18);
  }

  .tt-table thead th{
    font-size:.78rem;
    color:#475569;
    letter-spacing:.04em;
    text-transform:uppercase;
    white-space: nowrap;
  }
  .tt-table tbody td{ vertical-align:middle; }
  .tt-small{ font-size:.82rem; }
  .tt-xsmall{ font-size:.72rem; color:var(--muted); }
  .tt-strong{ font-weight:800; color:var(--text); }

  .tt-badge-active{ background:rgba(22,163,74,.12); color:#166534; border:1px solid rgba(22,163,74,.25); }
  .tt-badge-passive{ background:rgba(100,116,139,.12); color:#334155; border:1px solid rgba(100,116,139,.25); }

  /* Toolbar görünümü */
  .tt-toolbar{
    position: sticky;
    top: 76px; /* topbar yüksekliğine yakın */
    z-index: 10;
  }
  @media (max-width: 991px){
    .tt-toolbar{ position: static; }
  }

  /* loader */
  #ttWait{
    position:fixed;
    inset:0;
    display:none;
    align-items:center;
    justify-content:center;
    background:rgba(246,248,252,.88);
    z-index:99999;
    backdrop-filter: blur(8px);
  }
  #ttWait .box{
    background:#fff;
    border:1px solid var(--border);
    border-radius:18px;
    padding:18px 20px;
    box-shadow:0 18px 60px rgba(15,23,42,.16);
    display:flex;
    gap:12px;
    align-items:center;
    min-width: 260px;
  }
  #ttWait .msg{ font-weight:900; color:var(--text); letter-spacing:-.02em; }
  #ttWait .sub{ font-size:.85rem; color:var(--muted); font-weight:600; margin-top:-2px; }

  /* mobile cards */
  .tt-mobile{ display:none; }
  @media (max-width: 991px){
    .tt-desktop{ display:none; }
    .tt-mobile{ display:block; }
  }

  .tt-itemcard{
    border:1px solid var(--border);
    border-radius:18px;
    background:#fff;
    padding:14px;
    box-shadow:0 12px 30px rgba(15,23,42,.06);
  }
  .tt-itemcard .row1{ display:flex; align-items:flex-start; justify-content:space-between; gap:10px; }
  .tt-itemcard .name{ font-weight:900; letter-spacing:-.02em; line-height:1.2; }
  .tt-itemcard .meta{ color:var(--muted); font-weight:700; font-size:.85rem; margin-top:4px; }
  .tt-itemcard .line{ display:flex; gap:10px; flex-wrap:wrap; margin-top:10px; }
  .tt-kv{ font-size:.82rem; color:var(--muted); font-weight:700; }
  .tt-kv b{ color:var(--text); font-weight:900; }
  .tt-actions{ display:flex; gap:8px; margin-top:12px; }

  /* Modal */
  .modal-backdrop.show{ opacity:.55 !important; }
  .tt-modal{
    border:1px solid var(--border);
    border-radius:22px;
    overflow:hidden;
    box-shadow: 0 26px 84px rgba(15,23,42,.20);
    background:#fff;
  }
  .tt-modal .modal-header{
    border-bottom:1px solid var(--border);
    background: linear-gradient(180deg, #ffffff 0%, #f8fafc 100%);
    padding:16px 18px;
  }
  .tt-modal .modal-header .fw-bold,
  .tt-modal .modal-title{
    font-weight:900 !important;
    letter-spacing:-.02em;
    color:var(--text);
  }
  .tt-modal .btn-close{
    border-radius:12px;
    padding:10px;
  }
  .tt-modal .btn-close:focus{ box-shadow:0 0 0 .2rem rgba(37,99,235,.14); }
  .tt-modal .modal-body{ padding:18px; background:#fff; }
  .tt-modal .form-label{
    font-size:.78rem;
    letter-spacing:.06em;
    text-transform:uppercase;
    color:#475569;
    font-weight:800 !important;
    margin-bottom:.35rem;
  }
  .tt-modal .tt-input{ background:#fff !important; border:1px solid rgba(15,23,42,.12) !important; }
  .tt-modal .tt-input:focus{
    border-color:rgba(37,99,235,.45) !important;
    box-shadow:0 0 0 .18rem rgba(37,99,235,.14) !important;
  }
  .tt-modal .modal-footer{
    position: sticky;
    bottom: 0;
    z-index: 2;
    background: rgba(255,255,255,.92);
    backdrop-filter: blur(10px);
    border-top:1px solid var(--border);
    padding:14px 18px;
  }

  .tt-section{
    border:1px solid rgba(15,23,42,.10);
    border-radius:18px;
    padding:14px;
    background: linear-gradient(180deg, #ffffff 0%, #fbfdff 100%);
    box-shadow: 0 10px 26px rgba(15,23,42,.05);
  }
  .tt-section + .tt-section{ margin-top:12px; }

  .tt-section-title{
    display:flex;
    align-items:center;
    gap:10px;
    margin-bottom:10px;
  }
  .tt-section-title .ico{
    width:34px; height:34px;
    display:inline-flex;
    align-items:center; justify-content:center;
    border-radius:12px;
    background: var(--primary-soft);
    color: var(--primary);
  }
  .tt-section-title .t{
    font-weight:900;
    color:var(--text);
    letter-spacing:-.02em;
  }
  .tt-section-title .s{
    margin-left:auto;
    font-size:.78rem;
    font-weight:800;
    color:#475569;
    background: rgba(100,116,139,.10);
    border:1px solid rgba(100,116,139,.18);
    padding:.35rem .6rem;
    border-radius:999px;
  }

  /* Modal scroll fix */
  #editModal .modal-content{ max-height: calc(100vh - 2rem); }
  #editModal .modal-body{
    overflow-y:auto !important;
    -webkit-overflow-scrolling: touch;
    max-height: calc(100vh - 190px);
  }
  @media (max-width: 576px){
    #editModal .modal-body{ max-height: calc(100vh - 165px); }
  }

  /* Dislab modal table polish */
  #dislabCatalogModal .table thead th{
    font-size:.78rem;
    letter-spacing:.04em;
    text-transform:uppercase;
    color:#475569;
    white-space: nowrap;
  }
  #dislabCatalogModal .table tbody tr:hover{ background: rgba(37,99,235,.04); }
</style>

<div id="ttWait">
  <div class="box">
    <div class="spinner-border text-primary"></div>
    <div>
      <div class="msg" id="ttWaitMsg">İşleniyor...</div>
      <div class="sub" id="ttWaitSub">Lütfen bekle</div>
    </div>
  </div>
</div>

<div class="tt-scope">
  <div class="tt-shell">

    <div class="d-flex flex-wrap gap-3 align-items-center justify-content-between mb-3">
      <div>
        <div class="tt-title fs-4">Test Tanımları</div>
        <div class="tt-sub">Toplam <b><?= (int)$total ?></b> kayıt</div>
      </div>
      <div class="d-flex gap-2">
        <button class="btn btn-primary tt-btn px-3" onclick="openCreate()">
          <i class="bi bi-plus-lg me-1"></i> Yeni Test
        </button>
        <button class="btn btn-outline-danger tt-btn px-3" onclick="bulkDelete()">
          <i class="bi bi-trash me-1"></i> Seçilenleri Sil
        </button>
      </div>
    </div>

    <div class="tt-card p-3 mb-3 tt-toolbar">
      <div class="row g-2 align-items-center">
        <div class="col-12 col-lg-4 position-relative">
          <i class="bi bi-search position-absolute top-50 translate-middle-y ms-3 text-muted"></i>
          <input id="q" class="form-control tt-input ps-5" placeholder="Ara: test adı / kod / SUT / dış kod">
        </div>

        <div class="col-6 col-lg-2">
          <select id="only" class="form-select tt-input">
            <option value="all">Tümü</option>
            <option value="active">Aktif</option>
            <option value="passive">Pasif</option>
          </select>
        </div>

        <div class="col-6 col-lg-2">
          <select id="brans" class="form-select tt-input">
            <option value="">Branş (Tümü)</option>
            <?php foreach($brans_list as $b): ?>
              <option value="<?= e($b) ?>"><?= e($b) ?></option>
            <?php endforeach; ?>
          </select>
        </div>

        <div class="col-6 col-lg-2">
          <select id="labtip" class="form-select tt-input">
            <option value="">Lab Tip (Tümü)</option>
            <?php foreach($labtip_list as $lt): ?>
              <option value="<?= e($lt) ?>"><?= e($lt) ?></option>
            <?php endforeach; ?>
          </select>
        </div>

        <div class="col-6 col-lg-2">
          <select id="testtip" class="form-select tt-input">
            <option value="">Test Tipi (Tümü)</option>
            <?php foreach($testtip_list as $tt): ?>
              <option value="<?= e($tt) ?>"><?= e($tt) ?></option>
            <?php endforeach; ?>
          </select>
        </div>
      </div>
    </div>

    <!-- Desktop table -->
    <div class="tt-card overflow-hidden tt-desktop">
      <div class="table-responsive">
        <table class="table tt-table align-middle mb-0">
          <thead class="table-light">
            <tr>
              <th style="width:46px" class="text-center">
                <input class="form-check-input" type="checkbox" id="chkAll" onclick="toggleAll(this)">
              </th>
              <th>Test</th>
              <th style="width:110px" class="text-center">Durum</th>
              <th style="width:110px" class="text-center">Kod</th>
              <th style="width:110px" class="text-center">SUT</th>
              <th style="width:130px" class="text-center">Branş</th>
              <th style="width:120px" class="text-center">Tip</th>
              <th style="width:90px" class="text-center">Lab</th>
              <th style="width:240px">Dış Eşleme</th>
              <th style="width:140px" class="text-end pe-3">İşlem</th>
            </tr>
          </thead>
          <tbody id="tbody">
            <tr><td colspan="10" class="text-center py-5 text-muted">Yükleniyor...</td></tr>
          </tbody>
        </table>
      </div>
    </div>

    <!-- Mobile cards -->
    <div class="tt-mobile" id="mobileWrap">
      <div class="px-1" id="cards"></div>
    </div>

  </div>
</div>

<!-- EDIT/CREATE MODAL -->
<div class="modal fade" id="editModal" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-xl modal-dialog-centered modal-dialog-scrollable">
    <div class="modal-content tt-modal">
      <div class="modal-header">
        <div class="fw-bold">
          <i class="bi bi-pencil-square me-2"></i>
          <span id="modalTitle">Yeni Test</span>
        </div>
        <button class="btn-close" data-bs-dismiss="modal" aria-label="Kapat"></button>
      </div>

      <form id="editForm" onsubmit="saveForm(event)">
        <div class="modal-body">
          <input type="hidden" name="id" id="id">

          <!-- 1) Temel Bilgiler -->
          <div class="tt-section">
            <div class="tt-section-title">
              <span class="ico"><i class="bi bi-ui-checks-grid"></i></span>
              <div class="t">Temel Bilgiler</div>
              <div class="s">Zorunlu alanlar *</div>
            </div>

            <div class="row g-3">
              <div class="col-12 col-lg-8">
                <label class="form-label">Test Adı *</label>
                <input class="form-control tt-input" name="test_adi" id="test_adi" required>
              </div>

              <div class="col-12 col-lg-4">
                <label class="form-label">Durum</label>
                <select class="form-select tt-input" name="is_active" id="is_active">
                  <option value="1">Aktif</option>
                  <option value="0">Pasif</option>
                </select>
              </div>

              <div class="col-12 col-md-4">
                <label class="form-label">Branş *</label>
                <select class="form-select tt-input" name="brans" id="brans2" required>
                  <option value="">Seçiniz...</option>
                  <?php foreach($brans_list as $b): ?>
                    <option value="<?= e($b) ?>"><?= e($b) ?></option>
                  <?php endforeach; ?>
                </select>
                <div class="tt-xsmall mt-1">Branş değişince test kodu otomatik üretilir.</div>
              </div>

              <div class="col-12 col-md-4">
                <label class="form-label">Test Tipi *</label>
                <select class="form-select tt-input" name="test_tipi" id="test_tipi" required>
                  <option value="">Seçiniz...</option>
                  <?php foreach($testtip_list as $tt): ?>
                    <option value="<?= e($tt) ?>"><?= e($tt) ?></option>
                  <?php endforeach; ?>
                </select>
                <div class="tt-xsmall mt-1">Ana Test / Alt Test / Panel-Grup</div>
              </div>

              <div class="col-12 col-md-4">
                <label class="form-label">Laboratuvar Tipi *</label>
                <select class="form-select tt-input" name="laboratuvar_tipi" id="laboratuvar_tipi" required onchange="onLabTipChange()">
                  <?php foreach($labtip_list as $lt): ?>
                    <option value="<?= e($lt) ?>"><?= e($lt) ?></option>
                  <?php endforeach; ?>
                </select>
              </div>
            </div>
          </div>

          <!-- 2) Kodlar & Hiyerarşi -->
          <div class="tt-section">
            <div class="tt-section-title">
              <span class="ico"><i class="bi bi-upc-scan"></i></span>
              <div class="t">Kodlar ve Hiyerarşi</div>
              <div class="s">Düzenli kalsın</div>
            </div>

            <div class="row g-3">
              <div class="col-12 col-md-4">
                <label class="form-label">Test Kodu</label>
                <div class="input-group">
                  <input class="form-control tt-input" name="test_kodu" id="test_kodu" placeholder="Branşa göre otomatik" data-auto="1">
                  <button class="btn btn-outline-secondary tt-btn" type="button" title="Otomatik kod üret" onclick="regenCode()">
                    <i class="bi bi-arrow-repeat"></i>
                  </button>
                </div>
                <div class="tt-xsmall mt-1">Elle yazarsan otomatik ezmez.</div>
              </div>

              <div class="col-12 col-md-4">
                <label class="form-label">SUT Kodu</label>
                <input class="form-control tt-input" name="sut_kodu" id="sut_kodu" placeholder="901420">
              </div>

              <div class="col-12 col-md-4">
                <label class="form-label">Sıralama</label>
                <input type="number" class="form-control tt-input" name="siralama" id="siralama" value="0">
              </div>

              <div class="col-12 col-lg-10">
                <label class="form-label">Parent (Opsiyonel)</label>
                <select class="form-select tt-input" name="parent_id" id="parent_id">
                  <option value="0">Yok</option>
                </select>
                <div class="tt-xsmall mt-1">Panel/Grup veya üst test seçebilirsin.</div>
              </div>

              <div class="col-12 col-lg-2 d-flex align-items-end">
                <button class="btn btn-outline-secondary tt-btn w-100" type="button" onclick="loadParents()">
                  <i class="bi bi-arrow-repeat me-1"></i> Yenile
                </button>
              </div>
            </div>
          </div>

          <!-- 3) Numune -->
          <div class="tt-section">
            <div class="tt-section-title">
              <span class="ico"><i class="bi bi-droplet"></i></span>
              <div class="t">Numune Bilgisi</div>
              <div class="s">Opsiyonel</div>
            </div>

            <div class="row g-3">
              <div class="col-12 col-md-6">
                <label class="form-label">Numune Kabı</label>
                <input class="form-control tt-input" name="numune_kabi" id="numune_kabi" placeholder="Sarı Kap (Jelli)">
              </div>

              <div class="col-12 col-md-6">
                <label class="form-label">Numune Türü</label>
                <input class="form-control tt-input" name="numune_turu" id="numune_turu" placeholder="Serum">
              </div>

              <div class="col-12">
                <label class="form-label">Stabilite Şartları</label>
                <textarea class="form-control tt-input" name="stabilite_sartlari" id="stabilite_sartlari" rows="3"></textarea>
              </div>
            </div>
          </div>

          <!-- 4) Fiyatlandırma -->
          <div class="tt-section">
            <div class="tt-section-title">
              <span class="ico"><i class="bi bi-cash-coin"></i></span>
              <div class="t">Fiyatlandırma</div>
              <div class="s">0.00 olabilir</div>
            </div>

            <div class="row g-3">
              <div class="col-12 col-md-6">
                <label class="form-label">Maliyet</label>
                <input class="form-control tt-input" name="maliyet" id="maliyet" value="0.00">
              </div>

              <div class="col-12 col-md-6">
                <label class="form-label">Birim Fiyat</label>
                <input class="form-control tt-input" name="birim_fiyat" id="birim_fiyat" value="0.00">
              </div>
            </div>
          </div>

          <!-- 5) Dış Lab -->
          <div class="tt-section" id="dislabBlock">
            <div class="tt-section-title">
              <span class="ico"><i class="bi bi-link-45deg"></i></span>
              <div class="t">Dış Lab Eşlemesi</div>
              <div class="s">Lab=Dis ise zorunlu</div>
            </div>

            <label class="form-label">Dış Lab Test Eşlemesi (dislab_test_listesi)</label>

            <div class="input-group">
              <input type="number" class="form-control tt-input" name="dislab_mapping_id" id="dislab_mapping_id" placeholder="Dış test seçmek için Seç'e tıkla" readonly>
              <button class="btn btn-outline-primary tt-btn" type="button" onclick="openDislabCatalog('dislab_mapping_id')">
                <i class="bi bi-search me-1"></i> Seç
              </button>
              <button class="btn btn-outline-danger tt-btn" type="button" onclick="clearDislabMapping()">
                <i class="bi bi-x-lg"></i>
              </button>
            </div>

            <div class="tt-xsmall mt-2">
              Seçilen: <span data-dislab-label-for="dislab_mapping_id">-</span><br>
              <b>Dış laboratuvar</b> testi seçtiysen eşleme zorunlu.
            </div>

            <div class="alert alert-warning tt-small mt-2 mb-0" id="dislabWarn" style="display:none;">
              <i class="bi bi-exclamation-triangle me-1"></i> Laboratuvar Tipi <b>Dis</b> ise dış test eşlemesi seçmelisin.
            </div>
          </div>

        </div>

        <div class="modal-footer">
          <button class="btn btn-light tt-btn px-3" type="button" data-bs-dismiss="modal">Kapat</button>
          <button class="btn btn-primary tt-btn px-4" type="submit">
            <i class="bi bi-check2-circle me-1"></i> Kaydet
          </button>
        </div>
      </form>
    </div>
  </div>
</div>

<!-- DIŞ LAB KATALOG MODAL -->
<div class="modal fade" id="dislabCatalogModal" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable">
    <div class="modal-content tt-modal">
      <div class="modal-header">
        <h5 class="modal-title fw-bold m-0">
          <i class="bi bi-link-45deg me-1"></i> Dış Lab Test Eşle
        </h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Kapat"></button>
      </div>

      <div class="modal-body">
        <div class="tt-section">
          <div class="tt-section-title">
            <span class="ico"><i class="bi bi-search"></i></span>
            <div class="t">Katalog Arama</div>
            <div class="s">min 2 karakter</div>
          </div>

          <div class="d-flex gap-2 align-items-center">
            <div class="flex-grow-1 position-relative">
              <i class="bi bi-search position-absolute top-50 translate-middle-y ms-3 text-muted"></i>
              <input id="dislabSearch" class="form-control tt-input ps-5" placeholder="Ara: test adı, kod, SUT..." autocomplete="off">
            </div>
            <button class="btn btn-outline-secondary tt-btn" type="button" onclick="loadDislabCatalog(true)">
              <i class="bi bi-arrow-repeat"></i>
            </button>
          </div>

          <div id="dislabCatalogLoading" class="py-4 text-center text-muted" style="display:none;">
            <div class="spinner-border mb-2"></div>
            <div class="fw-semibold">Katalog yükleniyor...</div>
          </div>
        </div>

        <div class="tt-section mt-3">
          <div class="table-responsive">
            <table class="table table-hover align-middle mb-0">
              <thead class="table-light">
                <tr>
                  <th>Test</th>
                  <th style="width:140px;">Kod</th>
                  <th style="width:160px;">Örnek / Kap</th>
                  <th style="width:110px;">SUT</th>
                  <th style="width:90px;" class="text-end">Seç</th>
                </tr>
              </thead>
              <tbody id="dislabCatalogBody">
                <tr><td colspan="5" class="text-muted text-center py-4">Arama yapınca sonuçlar gelecek.</td></tr>
              </tbody>
            </table>
          </div>

          <div class="small text-muted mt-2">
            Seçtiğin kayıt <b>dislab_mapping_id</b> alanına yazılır.
          </div>
        </div>
      </div>

      <div class="modal-footer">
        <button class="btn btn-light tt-btn" type="button" data-bs-dismiss="modal">Kapat</button>
      </div>
    </div>
  </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<script>
/* ✅ Hardcode yok: dosya neredeyse API orası */
const API_PATH = location.pathname; // bu dosyanın kendisi
const DISLAB_CATALOG_API = new URL('dislab-catalog.php', location.href).toString();

let editModal = null;
let dislabModal = null;
let dislabTargetInputId = null;
let dislabDebounce = null;

function waitOn(msg='İşleniyor...', sub='Lütfen bekle'){
  document.getElementById('ttWaitMsg').textContent = msg;
  document.getElementById('ttWaitSub').textContent = sub;
  document.getElementById('ttWait').style.display = 'flex';
}
function waitOff(){ document.getElementById('ttWait').style.display = 'none'; }

function escapeHtml(str){
  return String(str ?? '').replace(/[&<>"']/g, s => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#039;'}[s]));
}

function toggleAll(el){
  document.querySelectorAll('.rowChk').forEach(c => c.checked = el.checked);
}

/* ===== Otomatik Kod Üretimi ===== */
function markManualCode(){
  const inp = document.getElementById('test_kodu');
  if(!inp) return;
  inp.dataset.auto = '0';
}
function markAutoCode(){
  const inp = document.getElementById('test_kodu');
  if(!inp) return;
  inp.dataset.auto = '1';
}
function canAutoFillCode(){
  const inp = document.getElementById('test_kodu');
  if(!inp) return false;
  const v = (inp.value || '').trim();
  return v === '' || inp.dataset.auto === '1';
}
function generateCode(force=false){
  const br = document.getElementById('brans2')?.value || '';
  if(!br) return;
  if(!force && !canAutoFillCode()) return;

  fetch(`${API_PATH}?action=gen_code&brans=${encodeURIComponent(br)}`, { cache:'no-store' })
    .then(r => r.json())
    .then(d => {
      if(!d.success) return;
      const inp = document.getElementById('test_kodu');
      if(!inp) return;
      inp.value = d.code || '';
      markAutoCode();
    })
    .catch(()=>{});
}
function regenCode(){ generateCode(true); }

/* ===== Liste ===== */
function loadList(){
  const q = document.getElementById('q').value.trim();
  const only = document.getElementById('only').value;
  const brans = document.getElementById('brans').value;
  const labtip = document.getElementById('labtip').value;
  const testtip = document.getElementById('testtip').value;

  waitOn('Liste yükleniyor...', 'Filtreler uygulanıyor');
  fetch(`${API_PATH}?action=fetch_list&q=${encodeURIComponent(q)}&only=${encodeURIComponent(only)}&brans=${encodeURIComponent(brans)}&labtip=${encodeURIComponent(labtip)}&testtip=${encodeURIComponent(testtip)}&limit=160`, { cache:'no-store' })
    .then(r => r.json())
    .then(d => {
      if(!d.success) throw new Error(d.error || 'Listeleme hatası');
      renderTable(d.items || []);
      renderCards(d.items || []);
    })
    .catch(err => {
      console.error(err);
      document.getElementById('tbody').innerHTML = `<tr><td colspan="10" class="text-center py-5 text-danger">${escapeHtml(err.message)}</td></tr>`;
      document.getElementById('cards').innerHTML = `<div class="text-danger text-center py-3">${escapeHtml(err.message)}</div>`;
    })
    .finally(waitOff);
}

function renderTable(items){
  const tbody = document.getElementById('tbody');
  if(!items.length){
    tbody.innerHTML = `<tr><td colspan="10" class="text-center py-5 text-muted">Kayıt bulunamadı.</td></tr>`;
    return;
  }
  tbody.innerHTML = items.map(it => {
    const active = (parseInt(it.is_active,10)===1);
    const badge = active
      ? `<span class="tt-pill tt-badge-active">AKTİF</span>`
      : `<span class="tt-pill tt-badge-passive">PASİF</span>`;

    const dis = it.dislab_mapping_id
      ? `<div class="tt-small fw-bold">${escapeHtml(it.dislab_kodu || '')}</div><div class="tt-xsmall">${escapeHtml(it.dislab_adi || '')}</div>`
      : `<div class="tt-xsmall text-muted">-</div>`;

    return `
      <tr>
        <td class="text-center"><input class="form-check-input rowChk" type="checkbox" value="${it.id}"></td>
        <td>
          <div class="tt-strong">${escapeHtml(it.test_adi)}</div>
          <div class="tt-xsmall">#${it.id} · Sıra: ${escapeHtml(it.siralama ?? 0)}</div>
        </td>
        <td class="text-center">${badge}</td>
        <td class="text-center tt-small fw-bold">${escapeHtml(it.test_kodu || '-')}</td>
        <td class="text-center tt-small">${escapeHtml(it.sut_kodu || '-')}</td>
        <td class="text-center tt-small">${escapeHtml(it.brans || '-')}</td>
        <td class="text-center tt-small fw-bold">${escapeHtml(it.test_tipi || '-')}</td>
        <td class="text-center tt-small fw-bold">${escapeHtml(it.laboratuvar_tipi || '-')}</td>
        <td>${dis}</td>
        <td class="text-end pe-3">
          <button class="btn btn-sm btn-outline-primary tt-btn" onclick="openEdit(${it.id})" title="Düzenle"><i class="bi bi-pencil"></i></button>
          <button class="btn btn-sm btn-outline-danger tt-btn" onclick="deleteOne(${it.id})" title="Sil"><i class="bi bi-trash"></i></button>
        </td>
      </tr>
    `;
  }).join('');
}

function renderCards(items){
  const wrap = document.getElementById('cards');
  if(!items.length){
    wrap.innerHTML = `<div class="text-center text-muted py-3">Kayıt bulunamadı.</div>`;
    return;
  }

  wrap.innerHTML = items.map(it => {
    const badge = (parseInt(it.is_active,10)===1)
      ? `<span class="tt-pill tt-badge-active">AKTİF</span>`
      : `<span class="tt-pill tt-badge-passive">PASİF</span>`;

    const dis = it.dislab_mapping_id
      ? `<div class="tt-kv"><b>Dış:</b> ${escapeHtml(it.dislab_kodu||'')} · ${escapeHtml(it.dislab_adi||'')}</div>`
      : '';

    return `
      <div class="tt-itemcard mb-3">
        <div class="row1">
          <div style="min-width:0">
            <div class="name">${escapeHtml(it.test_adi)}</div>
            <div class="meta">${badge} · #${escapeHtml(it.id)}</div>
          </div>
        </div>

        <div class="line">
          <div class="tt-kv"><b>Kod:</b> ${escapeHtml(it.test_kodu||'-')}</div>
          <div class="tt-kv"><b>SUT:</b> ${escapeHtml(it.sut_kodu||'-')}</div>
          <div class="tt-kv"><b>Branş:</b> ${escapeHtml(it.brans||'-')}</div>
          <div class="tt-kv"><b>Tip:</b> ${escapeHtml(it.test_tipi||'-')}</div>
          <div class="tt-kv"><b>Lab:</b> ${escapeHtml(it.laboratuvar_tipi||'-')}</div>
        </div>
        ${dis ? `<div class="mt-2">${dis}</div>` : ''}

        <div class="tt-actions">
          <button class="btn btn-outline-primary tt-btn w-100" onclick="openEdit(${it.id})"><i class="bi bi-pencil me-1"></i>Düzenle</button>
          <button class="btn btn-outline-danger tt-btn" style="width:56px" onclick="deleteOne(${it.id})" title="Sil"><i class="bi bi-trash"></i></button>
        </div>
      </div>
    `;
  }).join('');
}

// Filters live
['q','only','brans','labtip','testtip'].forEach(id => {
  document.addEventListener('DOMContentLoaded', () => {
    const el = document.getElementById(id);
    if(!el) return;
    el.addEventListener(id==='q' ? 'input' : 'change', () => {
      clearTimeout(window.__ttDeb);
      window.__ttDeb = setTimeout(loadList, 260);
    });
  });
});

function openCreate(){
  editModal = editModal || new bootstrap.Modal(document.getElementById('editModal'));
  document.getElementById('modalTitle').textContent = 'Yeni Test';
  document.getElementById('editForm').reset();
  document.getElementById('id').value = '';
  document.getElementById('is_active').value = '1';
  document.getElementById('laboratuvar_tipi').value = 'Ic';
  document.querySelector('[data-dislab-label-for="dislab_mapping_id"]').textContent = '-';
  document.getElementById('test_kodu').value = '';
  markAutoCode();

  loadParents(0);
  onLabTipChange();
  editModal.show();

  setTimeout(() => generateCode(false), 90);
}

function openEdit(id){
  editModal = editModal || new bootstrap.Modal(document.getElementById('editModal'));
  waitOn('Kayıt açılıyor...', 'Detaylar getiriliyor');
  fetch(`${API_PATH}?action=get_one&id=${id}`, { cache:'no-store' })
    .then(r => r.json())
    .then(d => {
      if(!d.success) throw new Error(d.error || 'Kayıt okunamadı');
      const it = d.item;

      document.getElementById('modalTitle').textContent = `Düzenle (#${it.id})`;
      document.getElementById('id').value = it.id;

      document.getElementById('test_adi').value = it.test_adi || '';
      document.getElementById('test_kodu').value = it.test_kodu || '';
      document.getElementById('sut_kodu').value = it.sut_kodu || '';
      document.getElementById('siralama').value = it.siralama ?? 0;

      document.getElementById('brans2').value = it.brans || '';
      document.getElementById('test_tipi').value = it.test_tipi || '';
      document.getElementById('laboratuvar_tipi').value = it.laboratuvar_tipi || 'Ic';

      document.getElementById('numune_kabi').value = it.numune_kabi || '';
      document.getElementById('numune_turu').value = it.numune_turu || '';
      document.getElementById('stabilite_sartlari').value = it.stabilite_sartlari || '';

      document.getElementById('maliyet').value = it.maliyet ?? '0.00';
      document.getElementById('birim_fiyat').value = it.birim_fiyat ?? '0.00';
      document.getElementById('is_active').value = String(it.is_active ?? 1);

      document.getElementById('dislab_mapping_id').value = it.dislab_mapping_id ?? '';
      document.querySelector('[data-dislab-label-for="dislab_mapping_id"]').textContent =
        (it.dislab_mapping_id ? `${it.dislab_kodu || ''} · ${it.dislab_adi || ''}` : '-');

      // Edit modunda otomatik ezmesin
      document.getElementById('test_kodu').dataset.auto = '0';

      loadParents(it.id, it.parent_id ?? 0);
      onLabTipChange();
      editModal.show();
    })
    .catch(err => alert(err.message))
    .finally(waitOff);
}

function loadParents(excludeId=0, selectedId=0){
  fetch(`${API_PATH}?action=parents&exclude=${excludeId}`, { cache:'no-store' })
    .then(r => r.json())
    .then(d => {
      const sel = document.getElementById('parent_id');
      sel.innerHTML = `<option value="0">Yok</option>`;
      if(!d.success) return;

      (d.items||[]).forEach(p => {
        const txt = `${p.test_adi} ${p.test_kodu ? '('+p.test_kodu+')' : ''} · ${p.test_tipi}`;
        const opt = document.createElement('option');
        opt.value = p.id;
        opt.textContent = txt;
        if (parseInt(selectedId,10) === parseInt(p.id,10)) opt.selected = true;
        sel.appendChild(opt);
      });
    });
}

function onLabTipChange(){
  const lt = document.getElementById('laboratuvar_tipi').value;
  const warn = document.getElementById('dislabWarn');
  warn.style.display = (lt === 'Dis') ? 'block' : 'none';
}

function clearDislabMapping(){
  document.getElementById('dislab_mapping_id').value = '';
  document.querySelector('[data-dislab-label-for="dislab_mapping_id"]').textContent = '-';
}

function saveForm(ev){
  ev.preventDefault();

  const lt = document.getElementById('laboratuvar_tipi').value;
  const mapId = document.getElementById('dislab_mapping_id').value;
  if(lt === 'Dis' && (!mapId || parseInt(mapId,10) <= 0)){
    alert('Laboratuvar Tipi Dis ise Dış Lab Test Eşlemesi seçmelisin.');
    return;
  }

  const fd = new FormData(document.getElementById('editForm'));

  waitOn('Kaydediliyor...', 'Veriler yazılıyor');
  fetch(`${API_PATH}?action=save`, { method:'POST', body: fd, cache:'no-store' })
    .then(r => r.json())
    .then(d => {
      if(!d.success) throw new Error(d.error || 'Kaydetme hatası');
      editModal.hide();
      loadList();
    })
    .catch(err => alert(err.message))
    .finally(waitOff);
}

function deleteOne(id){
  if(!confirm('Bu kaydı silmek istiyor musun?')) return;
  waitOn('Siliniyor...', 'Kayıt kaldırılıyor');
  const fd = new FormData(); fd.append('id', id);
  fetch(`${API_PATH}?action=delete`, { method:'POST', body: fd, cache:'no-store' })
    .then(r => r.json())
    .then(d => {
      if(!d.success) throw new Error(d.error || 'Silme hatası');
      loadList();
    })
    .catch(err => alert(err.message))
    .finally(waitOff);
}

function bulkDelete(){
  const ids = Array.from(document.querySelectorAll('.rowChk:checked')).map(x => x.value);
  if(!ids.length){ alert('Seçim yok.'); return; }
  if(!confirm(`Seçilen ${ids.length} kaydı silmek istiyor musun?`)) return;

  waitOn('Toplu silme...', 'Seçilen kayıtlar kaldırılıyor');
  const fd = new FormData();
  ids.forEach(id => fd.append('ids[]', id));

  fetch(`${API_PATH}?action=bulk_delete`, { method:'POST', body: fd, cache:'no-store' })
    .then(r => r.json())
    .then(d => {
      if(!d.success) throw new Error(d.error || 'Toplu silme hatası');
      const chkAll = document.getElementById('chkAll');
      if (chkAll) chkAll.checked = false;
      loadList();
    })
    .catch(err => alert(err.message))
    .finally(waitOff);
}

/* ============ DIŞLAB KATALOG MODAL ============ */
function openDislabCatalog(targetInputId){
  dislabTargetInputId = targetInputId;
  dislabModal = dislabModal || new bootstrap.Modal(document.getElementById('dislabCatalogModal'));
  document.getElementById('dislabSearch').value = '';
  document.getElementById('dislabCatalogBody').innerHTML =
    '<tr><td colspan="5" class="text-muted text-center py-4">Arama yapınca sonuçlar gelecek.</td></tr>';
  dislabModal.show();
  setTimeout(() => document.getElementById('dislabSearch').focus(), 220);
}

function loadDislabCatalog(force=false){
  const q = document.getElementById('dislabSearch').value.trim();
  if(!force && q.length < 2){
    document.getElementById('dislabCatalogBody').innerHTML =
      '<tr><td colspan="5" class="text-muted text-center py-4">En az 2 karakter yaz.</td></tr>';
    return;
  }

  document.getElementById('dislabCatalogLoading').style.display = 'block';

  fetch(`${DISLAB_CATALOG_API}?action=search_catalog&q=${encodeURIComponent(q)}&limit=80`, { cache:'no-store' })
    .then(r => r.json())
    .then(d => {
      const body = document.getElementById('dislabCatalogBody');
      if(!d.success){
        body.innerHTML = `<tr><td colspan="5" class="text-danger text-center py-4">${escapeHtml(d.error||'Hata')}</td></tr>`;
        return;
      }
      const items = d.items || [];
      if(!items.length){
        body.innerHTML = `<tr><td colspan="5" class="text-muted text-center py-4">Sonuç yok.</td></tr>`;
        return;
      }

      body.innerHTML = items.map(it => {
        return `
          <tr>
            <td>
              <div class="fw-semibold">${escapeHtml(it.dislab_adi||'')}</div>
              <div class="small text-muted">ID: ${escapeHtml(it.id)} · ${parseInt(it.is_active,10)===1 ? 'AKTİF' : 'PASİF'}</div>
            </td>
            <td class="fw-bold">${escapeHtml(it.dislab_kodu||'')}</td>
            <td>
              <div class="small">${escapeHtml(it.ornek_tur_adi||'-')}</div>
              <div class="small text-muted">${escapeHtml(it.kap_adi||'-')}</div>
            </td>
            <td class="small">${escapeHtml(it.sut_kodu||'-')}</td>
            <td class="text-end">
              <button class="btn btn-sm btn-primary tt-btn"
                type="button"
                onclick="selectDislabTest(${it.id}, '${String(it.dislab_kodu||'').replace(/'/g,"\\'")}', '${String(it.dislab_adi||'').replace(/'/g,"\\'")}')">
                <i class="bi bi-check2"></i>
              </button>
            </td>
          </tr>
        `;
      }).join('');
    })
    .catch(err => {
      document.getElementById('dislabCatalogBody').innerHTML =
        `<tr><td colspan="5" class="text-danger text-center py-4">JSON okunamadı: ${escapeHtml(String(err))}</td></tr>`;
    })
    .finally(() => document.getElementById('dislabCatalogLoading').style.display = 'none');
}

function selectDislabTest(id, code, name){
  const input = document.getElementById(dislabTargetInputId);
  if(!input){ alert('Input bulunamadı.'); return; }
  input.value = id;

  const label = document.querySelector(`[data-dislab-label-for="${dislabTargetInputId}"]`);
  if(label) label.textContent = `${code} · ${name}`;

  dislabModal.hide();
}

document.addEventListener('DOMContentLoaded', () => {
  const s = document.getElementById('dislabSearch');
  if(s){
    s.addEventListener('input', () => {
      clearTimeout(dislabDebounce);
      dislabDebounce = setTimeout(() => loadDislabCatalog(false), 260);
    });
  }

  const br2 = document.getElementById('brans2');
  if(br2){
    br2.addEventListener('change', () => generateCode(true));
  }

  const tk = document.getElementById('test_kodu');
  if(tk){
    tk.addEventListener('input', () => markManualCode());
  }

  loadList();
});
</script>
