<?php
declare(strict_types=1);

require_once __DIR__ . '/../../app/bootstrap.php';
require_login();

if (!(has_role('ADMIN') || has_role('DIRECTOR') || has_role('SECRETARIA'))) {
  http_response_code(403);
  die('Acceso no permitido');
}

$pdo = db();

function h($v): string {
  return htmlspecialchars((string)$v, ENT_QUOTES, 'UTF-8');
}

/* =========================
   Flash
========================= */
function flash_set(string $key, string $val): void {
  start_session();
  $_SESSION['flash'][$key] = $val;
}

function flash_get(string $key): ?string {
  start_session();
  if (!isset($_SESSION['flash'][$key])) return null;
  $v = (string)$_SESSION['flash'][$key];
  unset($_SESSION['flash'][$key]);
  return $v;
}

/* =========================
   Helpers
========================= */
function safe_rows(PDO $pdo, string $sql, array $params = [], int $mode = PDO::FETCH_ASSOC): array {
  try {
    $st = $pdo->prepare($sql);
    $st->execute($params);
    return $st->fetchAll($mode) ?: [];
  } catch (Throwable $e) {
    return [];
  }
}

function in_placeholders(array $ids): array {
  $ids = array_values(array_filter(array_map('intval', $ids), fn($x) => $x > 0));
  if (empty($ids)) return [[], ''];
  $ph = implode(',', array_fill(0, count($ids), '?'));
  return [$ids, $ph];
}

function obtenerMatriculaActivaDelAnio(PDO $pdo, int $estudianteId, int $anio): ?array {
  $st = $pdo->prepare("
    SELECT
      id,
      institucion,
      nivel,
      curso,
      COALESCE(seccion, 'A') AS seccion,
      turno,
      estado
    FROM matriculas
    WHERE estudiante_id = ?
      AND anio_lectivo = ?
      AND estado = 'ACTIVO'
    ORDER BY id DESC
    LIMIT 1
  ");
  $st->execute([$estudianteId, $anio]);
  $row = $st->fetch(PDO::FETCH_ASSOC);
  return $row ?: null;
}

function matriculaCoincideConFiltro(
  array $m,
  string $institucion,
  string $nivel,
  string $curso,
  string $seccion,
  string $turno
): bool {
  return
    (string)$m['institucion'] === $institucion &&
    (string)$m['nivel'] === $nivel &&
    (string)$m['curso'] === $curso &&
    (string)($m['seccion'] ?? 'A') === $seccion &&
    (string)$m['turno'] === $turno;
}

/* =========================
   Parámetros
========================= */
$institucion = trim((string)($_GET['institucion'] ?? 'ENC'));
$anio        = (int)($_GET['anio'] ?? (int)date('Y'));
$turno       = trim((string)($_GET['turno'] ?? 'Noche'));
$nivel       = trim((string)($_GET['nivel'] ?? ''));
$curso       = trim((string)($_GET['curso'] ?? ''));
$seccion     = trim((string)($_GET['seccion'] ?? 'A'));
$estado      = strtoupper(trim((string)($_GET['estado'] ?? 'ACTIVO')));
$q           = trim((string)($_GET['q'] ?? ''));

if ($institucion === '') $institucion = 'ENC';
if ($seccion === '') $seccion = 'A';
if (!in_array($estado, ['ACTIVO', 'INACTIVO', 'TODOS'], true)) {
  $estado = 'ACTIVO';
}

/* =========================
   Catálogos
========================= */
$instituciones = safe_rows(
  $pdo,
  "SELECT DISTINCT institucion FROM cursos WHERE activo = 1 ORDER BY institucion",
  [],
  PDO::FETCH_COLUMN
);

if (!empty($instituciones) && !in_array($institucion, array_map('strval', $instituciones), true)) {
  $institucion = (string)$instituciones[0];
}

$niveles = safe_rows(
  $pdo,
  "SELECT DISTINCT nivel
   FROM cursos
   WHERE activo = 1
     AND institucion = ?
   ORDER BY nivel",
  [$institucion],
  PDO::FETCH_COLUMN
);

if ($nivel === '' && !empty($niveles)) {
  $nivel = (string)$niveles[0];
}

$cursosTxt = [];
if ($nivel !== '') {
  $st = $pdo->prepare("
    SELECT nombre
    FROM cursos
    WHERE activo = 1
      AND institucion = ?
      AND nivel = ?
    ORDER BY orden, nombre
  ");
  $st->execute([$institucion, $nivel]);
  $cursosTxt = $st->fetchAll(PDO::FETCH_COLUMN) ?: [];
}

if ($curso === '' && !empty($cursosTxt)) {
  $curso = (string)$cursosTxt[0];
}

$secciones = safe_rows(
  $pdo,
  "SELECT nombre FROM secciones WHERE activo = 1 ORDER BY nombre",
  [],
  PDO::FETCH_COLUMN
);

if ($seccion === '' && !empty($secciones)) {
  $seccion = (string)$secciones[0];
}

/* =========================
   Sync inscripciones
========================= */
function sync_inscripciones(
  PDO $pdo,
  string $institucion,
  int $anio,
  string $nivel,
  string $cursoTxt,
  string $seccionTxt,
  string $turno
): void {
  $stM = $pdo->prepare("
    SELECT id
    FROM matriculas
    WHERE institucion = :institucion
      AND anio_lectivo = :anio
      AND estado = 'ACTIVO'
      AND nivel = :nivel
      AND curso = :curso
      AND COALESCE(seccion, 'A') = :seccion
      AND turno = :turno
  ");
  $stM->execute([
    ':institucion' => $institucion,
    ':anio'        => $anio,
    ':nivel'       => $nivel,
    ':curso'       => $cursoTxt,
    ':seccion'     => $seccionTxt,
    ':turno'       => $turno,
  ]);
  $matIds = array_map('intval', $stM->fetchAll(PDO::FETCH_COLUMN));
  if (empty($matIds)) {
    throw new RuntimeException('No hay matrículas activas para sincronizar.');
  }

  $stC = $pdo->prepare("
    SELECT c.id
    FROM clases c
    JOIN cursos cu ON cu.id = c.curso_id
    JOIN secciones s ON s.id = c.seccion_id
    WHERE c.institucion = :institucion
      AND c.anio_lectivo = :anio
      AND c.activo = 1
      AND c.nivel = :nivel
      AND cu.institucion = :institucion_curso
      AND cu.nombre = :curso
      AND s.nombre = :seccion
      AND c.turno = :turno
  ");
  $stC->execute([
    ':institucion'       => $institucion,
    ':institucion_curso' => $institucion,
    ':anio'              => $anio,
    ':nivel'             => $nivel,
    ':curso'             => $cursoTxt,
    ':seccion'           => $seccionTxt,
    ':turno'             => $turno,
  ]);
  $claseIds = array_map('intval', $stC->fetchAll(PDO::FETCH_COLUMN));
  if (empty($claseIds)) {
    throw new RuntimeException('No hay clases generadas para esta institución/curso/sección/turno/año.');
  }

  $pdo->beginTransaction();
  try {
    $ins = $pdo->prepare("
      INSERT IGNORE INTO inscripciones_clase (clase_id, matricula_id)
      VALUES (?, ?)
    ");
    foreach ($matIds as $mid) {
      foreach ($claseIds as $cid) {
        $ins->execute([$cid, $mid]);
      }
    }
    $pdo->commit();
  } catch (Throwable $e) {
    if ($pdo->inTransaction()) $pdo->rollBack();
    throw $e;
  }
}

/* =========================
   POST
========================= */
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  csrf_check();

  $action = (string)($_POST['action'] ?? '');

  $institucionP = trim((string)($_POST['institucion'] ?? $institucion));
  $anioP        = (int)($_POST['anio'] ?? $anio);
  $turnoP       = trim((string)($_POST['turno'] ?? $turno));
  $nivelP       = trim((string)($_POST['nivel'] ?? $nivel));
  $cursoP       = trim((string)($_POST['curso'] ?? $curso));
  $seccionP     = trim((string)($_POST['seccion'] ?? $seccion));
  $qP           = trim((string)($_POST['q'] ?? $q));
  $estadoP      = strtoupper(trim((string)($_POST['estado'] ?? $estado)));

  if ($institucionP === '') $institucionP = 'ENC';
  if ($seccionP === '') $seccionP = 'A';
  if (!in_array($estadoP, ['ACTIVO', 'INACTIVO', 'TODOS'], true)) {
    $estadoP = 'ACTIVO';
  }

  try {
    if ($action === 'cambiar_estado') {
      $matId = (int)($_POST['matricula_id'] ?? 0);
      $newSt = strtoupper((string)($_POST['nuevo_estado'] ?? 'ACTIVO'));

      if ($matId <= 0) throw new RuntimeException('Matrícula inválida.');

      $newSt = ($newSt === 'ACTIVO') ? 'ACTIVO' : 'INACTIVO';
      $pdo->prepare("UPDATE matriculas SET estado = ? WHERE id = ?")->execute([$newSt, $matId]);

      flash_set('msg', '✅ Estado actualizado.');
    }

    if ($action === 'sync_inscripciones') {
      sync_inscripciones($pdo, $institucionP, $anioP, $nivelP, $cursoP, $seccionP, $turnoP);
      flash_set('msg', '✅ Sincronización de inscripciones completada.');
    }

    if ($action === 'matricular_uno') {
      $estId = (int)($_POST['estudiante_id'] ?? 0);
      if ($estId <= 0) throw new RuntimeException('Estudiante inválido.');

      $pdo->beginTransaction();
      try {
        $matActiva = obtenerMatriculaActivaDelAnio($pdo, $estId, $anioP);

        if ($matActiva && !matriculaCoincideConFiltro($matActiva, $institucionP, $nivelP, $cursoP, $seccionP, $turnoP)) {
          throw new RuntimeException(
            'El estudiante ya está matriculado en otro curso: ' .
            $matActiva['nivel'] . ' / ' . $matActiva['curso'] . ' / ' . $matActiva['seccion'] . ' / ' . $matActiva['turno']
          );
        }

        if ($matActiva) {
          $pdo->prepare("
            UPDATE matriculas
            SET institucion = :institucion,
                nivel = :nivel,
                curso = :curso,
                seccion = :seccion,
                turno = :turno,
                estado = 'ACTIVO'
            WHERE id = :id
          ")->execute([
            ':institucion' => $institucionP,
            ':nivel'       => $nivelP,
            ':curso'       => $cursoP,
            ':seccion'     => $seccionP,
            ':turno'       => $turnoP,
            ':id'          => (int)$matActiva['id'],
          ]);
        } else {
          $pdo->prepare("
            INSERT INTO matriculas (institucion, estudiante_id, anio_lectivo, nivel, curso, seccion, turno, estado)
            VALUES (:institucion, :eid, :anio, :nivel, :curso, :seccion, :turno, 'ACTIVO')
          ")->execute([
            ':institucion' => $institucionP,
            ':eid'         => $estId,
            ':anio'        => $anioP,
            ':nivel'       => $nivelP,
            ':curso'       => $cursoP,
            ':seccion'     => $seccionP,
            ':turno'       => $turnoP,
          ]);
        }

        $pdo->commit();

        if (!empty($_POST['auto_sync'])) {
          sync_inscripciones($pdo, $institucionP, $anioP, $nivelP, $cursoP, $seccionP, $turnoP);
          flash_set('msg', '✅ Estudiante matriculado y sincronizado.');
        } else {
          flash_set('msg', '✅ Estudiante matriculado.');
        }
      } catch (Throwable $e) {
        if ($pdo->inTransaction()) $pdo->rollBack();
        throw $e;
      }
    }

    if ($action === 'matricular_seleccionados') {
      $ids = $_POST['estudiantes'] ?? [];
      if (!is_array($ids) || empty($ids)) {
        throw new RuntimeException('No seleccionaste estudiantes.');
      }

      [$ids, $ph] = in_placeholders($ids);
      if ($ph === '') {
        throw new RuntimeException('Selección inválida.');
      }

      $pdo->beginTransaction();
      try {
        $stInsert = $pdo->prepare("
          INSERT INTO matriculas (
            institucion, estudiante_id, anio_lectivo, nivel, curso, seccion, turno, estado
          ) VALUES (?, ?, ?, ?, ?, ?, ?, 'ACTIVO')
        ");

        $stUpdate = $pdo->prepare("
          UPDATE matriculas
          SET institucion = ?,
              nivel = ?,
              curso = ?,
              seccion = ?,
              turno = ?,
              estado = 'ACTIVO'
          WHERE id = ?
        ");

        $insertados = 0;
        $actualizados = 0;
        $bloqueados = [];

        foreach ($ids as $eid) {
          $eid = (int)$eid;
          if ($eid <= 0) continue;

          $matActiva = obtenerMatriculaActivaDelAnio($pdo, $eid, $anioP);

          if ($matActiva && !matriculaCoincideConFiltro($matActiva, $institucionP, $nivelP, $cursoP, $seccionP, $turnoP)) {
            $bloqueados[] = $eid;
            continue;
          }

          if ($matActiva) {
            $stUpdate->execute([
              $institucionP,
              $nivelP,
              $cursoP,
              $seccionP,
              $turnoP,
              (int)$matActiva['id']
            ]);
            $actualizados++;
          } else {
            $stInsert->execute([
              $institucionP,
              $eid,
              $anioP,
              $nivelP,
              $cursoP,
              $seccionP,
              $turnoP
            ]);
            $insertados++;
          }
        }

        $pdo->commit();

        $msgFinal = "✅ Matriculación completada ({$insertados} nuevos, {$actualizados} actualizados).";
        if (!empty($bloqueados)) {
          $msgFinal .= ' ' . count($bloqueados) . ' bloqueados por estar en otro curso.';
        }

        if (!empty($_POST['auto_sync'])) {
          sync_inscripciones($pdo, $institucionP, $anioP, $nivelP, $cursoP, $seccionP, $turnoP);
          $msgFinal .= ' Sincronización completada.';
        }

        flash_set('msg', $msgFinal);
      } catch (Throwable $e) {
        if ($pdo->inTransaction()) $pdo->rollBack();
        throw $e;
      }
    }

  } catch (Throwable $e) {
    flash_set('err', '❌ ' . $e->getMessage());
  }

  header('Location: /Comercio/public/admin/matricular.php?' . http_build_query([
    'institucion' => $institucionP,
    'anio'        => $anioP,
    'turno'       => $turnoP,
    'nivel'       => $nivelP,
    'curso'       => $cursoP,
    'seccion'     => $seccionP,
    'estado'      => $estadoP,
    'q'           => $qP,
  ]));
  exit;
}

/* =========================
   Matrículas activas del año
========================= */
$matriculasActivasAnio = safe_rows($pdo, "
  SELECT
    m.id,
    m.estudiante_id,
    m.institucion,
    m.anio_lectivo,
    m.nivel,
    m.curso,
    COALESCE(m.seccion, 'A') AS seccion,
    m.turno,
    m.estado
  FROM matriculas m
  WHERE m.anio_lectivo = :anio
    AND m.estado = 'ACTIVO'
", [
  ':anio' => $anio,
]);

$mapMatriculaActivaAnio = [];
foreach ($matriculasActivasAnio as $m) {
  $mapMatriculaActivaAnio[(int)$m['estudiante_id']] = $m;
}

/* =========================
   Consultas de pantalla
========================= */
$where = "
  m.institucion = :institucion
  AND m.anio_lectivo = :anio
  AND m.nivel = :nivel
  AND m.curso = :curso
  AND COALESCE(m.seccion, 'A') = :seccion
  AND m.turno = :turno
";

$params = [
  ':institucion' => $institucion,
  ':anio'        => $anio,
  ':nivel'       => $nivel,
  ':curso'       => $curso,
  ':seccion'     => $seccion,
  ':turno'       => $turno,
];

if ($estado !== 'TODOS') {
  $where .= " AND m.estado = :estado";
  $params[':estado'] = $estado;
}

$matriculados = safe_rows($pdo, "
  SELECT
    m.id,
    m.estado,
    m.creado_en,
    e.id AS estudiante_id,
    e.ci,
    e.apellidos,
    e.nombres
  FROM matriculas m
  JOIN estudiantes e ON e.id = m.estudiante_id
  WHERE {$where}
  ORDER BY e.nombres
", $params);

/* =========================
   Nómina completa
========================= */
$nominaCompleta = safe_rows($pdo, "
  SELECT
    e.id,
    e.ci,
    e.apellidos,
    e.nombres,
    e.activo
  FROM estudiantes e
  WHERE e.activo = 1
  ORDER BY e.nombres
");

foreach ($nominaCompleta as &$e) {
  $eid = (int)$e['id'];
  $m = $mapMatriculaActivaAnio[$eid] ?? null;

  $e['matricula_id'] = $m['id'] ?? null;
  $e['matricula_estado'] = $m['estado'] ?? null;
  $e['matricula_institucion'] = $m['institucion'] ?? null;
  $e['matricula_nivel'] = $m['nivel'] ?? null;
  $e['matricula_curso'] = $m['curso'] ?? null;
  $e['matricula_seccion'] = $m['seccion'] ?? null;
  $e['matricula_turno'] = $m['turno'] ?? null;

  $e['esta_en_filtro_actual'] = $m
    ? (
        (string)$m['institucion'] === $institucion &&
        (string)$m['nivel'] === $nivel &&
        (string)$m['curso'] === $curso &&
        (string)($m['seccion'] ?? 'A') === $seccion &&
        (string)$m['turno'] === $turno
      )
    : false;

  $e['esta_en_otro_curso'] = $m && !$e['esta_en_filtro_actual'];
}
unset($e);

$noMatric = array_values(array_filter($nominaCompleta, function ($e) {
  return empty($e['matricula_id']);
}));

$noMatricTotal = count($noMatric);
$totalNomina = count($nominaCompleta);

$title = 'Matricular';
include __DIR__ . '/../../app/views/header.php';

$err = flash_get('err');
$msg = flash_get('msg');
?>

<style>
  :root{
    --brand-blue:#0d6efd;
    --brand-blue-2:#0b5ed7;
    --ok:#198754;
    --warn:#f59f00;
    --danger:#dc3545;
  }

  .btn-brand{
    color:#fff !important;
    border:1px solid rgba(13,110,253,.55) !important;
    background:linear-gradient(90deg,var(--brand-blue),var(--brand-blue-2)) !important;
    font-weight:900;
    box-shadow:0 12px 26px rgba(13,110,253,.22);
  }
  .btn-brand:hover{
    transform:translateY(-1px);
    box-shadow:0 16px 34px rgba(13,110,253,.28);
  }

  .card-pro{
    border-radius:18px;
    border:1px solid rgba(0,0,0,.06);
    background:#fff;
    box-shadow:0 8px 22px rgba(0,0,0,.04);
  }

  .soft-table{
    border-radius:16px;
    overflow:hidden;
    border:1px solid rgba(0,0,0,.06);
  }

  .soft-table thead th{
    background:#f8f9fa;
    font-size:.84rem;
    color:#6c757d;
    font-weight:900;
    letter-spacing:.2px;
    white-space:nowrap;
  }

  .chip{
    display:inline-flex;
    align-items:center;
    gap:6px;
    padding:6px 10px;
    border-radius:999px;
    font-size:.85rem;
    border:1px solid rgba(0,0,0,.08);
    background:#fff;
  }

  .mini{
    font-size:.86rem;
    color:#6c757d;
  }

  .sticky-actions{
    position:sticky;
    top:12px;
    z-index:2;
    background:#fff;
  }

  .search-live{
    position:sticky;
    top:70px;
    z-index:2;
    background:#fff;
    padding-top:8px;
    padding-bottom:8px;
  }

  .badge-pill{
    display:inline-flex;
    align-items:center;
    justify-content:center;
    border-radius:999px;
    padding:5px 10px;
    font-size:.78rem;
    font-weight:800;
  }

  .badge-ok{
    background:rgba(25,135,84,.14);
    color:var(--ok);
  }

  .badge-warn{
    background:rgba(245,159,0,.16);
    color:#8a5a00;
  }

  .badge-muted{
    background:rgba(108,117,125,.14);
    color:#495057;
  }

  .row-hidden{
    display:none !important;
  }

  .row-disponible{
    cursor:pointer;
  }

  .row-disponible.table-active td{
    background:#eef5ff !important;
  }

  .row-disponible.row-checked td{
    background:#f6fbff;
  }

  .selected-counter{
    font-weight:800;
    color:#0d6efd;
  }
</style>

<div class="d-flex justify-content-between align-items-start flex-wrap gap-2 mb-3">
  <div>
    <h1 class="h5 mb-1">Matricular</h1>
    <div class="text-muted small">
      Elegí institución, nivel, curso, sección y turno. Todo lo que matriculás se guarda en ese filtro actual.
    </div>
  </div>
  <div class="d-flex gap-2">
    <a class="btn btn-outline-secondary btn-sm" href="/Comercio/public/dashboard.php">
      <i class="bi bi-arrow-left"></i> Volver
    </a>
  </div>
</div>

<?php if ($err): ?>
  <div class="alert alert-danger"><?= h($err) ?></div>
<?php endif; ?>

<?php if ($msg): ?>
  <div class="alert alert-info"><?= h($msg) ?></div>
<?php endif; ?>

<div class="card-pro p-3 mb-3">
  <form method="get" class="row g-2 align-items-end">
    <div class="col-6 col-md-2">
      <label class="form-label">Institución</label>
      <select class="form-select" name="institucion" onchange="this.form.submit()">
        <?php foreach ($instituciones as $inst): ?>
          <option value="<?= h((string)$inst) ?>" <?= $institucion === (string)$inst ? 'selected' : '' ?>>
            <?= h((string)$inst) ?>
          </option>
        <?php endforeach; ?>
      </select>
    </div>

    <div class="col-6 col-md-2">
      <label class="form-label">Año</label>
      <input class="form-control" type="number" name="anio" value="<?= (int)$anio ?>">
    </div>

    <div class="col-6 col-md-2">
      <label class="form-label">Turno</label>
      <select class="form-select" name="turno">
        <?php foreach (['Noche', 'Mañana', 'Tarde'] as $t): ?>
          <option value="<?= h($t) ?>" <?= $turno === $t ? 'selected' : '' ?>><?= h($t) ?></option>
        <?php endforeach; ?>
      </select>
    </div>

    <div class="col-12 col-md-2">
      <label class="form-label">Nivel</label>
      <select class="form-select" name="nivel" onchange="this.form.submit()">
        <?php foreach ($niveles as $n): ?>
          <option value="<?= h((string)$n) ?>" <?= $nivel === (string)$n ? 'selected' : '' ?>><?= h((string)$n) ?></option>
        <?php endforeach; ?>
      </select>
    </div>

    <div class="col-12 col-md-2">
      <label class="form-label">Curso</label>
      <select class="form-select" name="curso" onchange="this.form.submit()">
        <?php foreach ($cursosTxt as $c): ?>
          <option value="<?= h((string)$c) ?>" <?= $curso === (string)$c ? 'selected' : '' ?>><?= h((string)$c) ?></option>
        <?php endforeach; ?>
      </select>
    </div>

    <div class="col-6 col-md-1">
      <label class="form-label">Sección</label>
      <select class="form-select" name="seccion">
        <?php foreach ($secciones as $s): ?>
          <option value="<?= h((string)$s) ?>" <?= $seccion === (string)$s ? 'selected' : '' ?>><?= h((string)$s) ?></option>
        <?php endforeach; ?>
      </select>
    </div>

    <div class="col-6 col-md-1">
      <label class="form-label">Estado</label>
      <select class="form-select" name="estado">
        <?php foreach (['ACTIVO', 'INACTIVO', 'TODOS'] as $es): ?>
          <option value="<?= h($es) ?>" <?= $estado === $es ? 'selected' : '' ?>><?= h($es) ?></option>
        <?php endforeach; ?>
      </select>
    </div>

    <div class="col-12 d-flex gap-2">
      <button class="btn btn-primary w-100" type="submit">
        <i class="bi bi-funnel me-1"></i>Aplicar filtro académico
      </button>
      <a class="btn btn-outline-secondary" href="/Comercio/public/admin/matricular.php">Limpiar</a>
    </div>
  </form>

  <div class="d-flex flex-wrap gap-2 mt-3 align-items-center">
    <span class="chip"><i class="bi bi-building"></i> Institución: <b><?= h($institucion) ?></b></span>
    <span class="chip"><i class="bi bi-mortarboard"></i> Matriculados del filtro: <b><?= (int)count($matriculados) ?></b></span>
    <span class="chip"><i class="bi bi-person-plus"></i> Disponibles en este filtro: <b id="chipDisponibles"><?= (int)$noMatricTotal ?></b></span>
    <span class="chip"><i class="bi bi-people"></i> Nómina completa: <b id="chipNomina"><?= (int)$totalNomina ?></b></span>

    <form method="post" class="ms-auto d-flex gap-2 flex-wrap">
      <input type="hidden" name="csrf" value="<?= h(csrf_token()) ?>">
      <input type="hidden" name="action" value="sync_inscripciones">
      <input type="hidden" name="institucion" value="<?= h($institucion) ?>">
      <input type="hidden" name="anio" value="<?= (int)$anio ?>">
      <input type="hidden" name="turno" value="<?= h($turno) ?>">
      <input type="hidden" name="nivel" value="<?= h($nivel) ?>">
      <input type="hidden" name="curso" value="<?= h($curso) ?>">
      <input type="hidden" name="seccion" value="<?= h($seccion) ?>">
      <input type="hidden" name="estado" value="<?= h($estado) ?>">
      <input type="hidden" name="q" value="">
      <button class="btn btn-outline-primary" type="submit">
        <i class="bi bi-arrow-repeat me-1"></i>Sincronizar inscripciones
      </button>
    </form>
  </div>
</div>

<div class="card-pro p-3 mb-3 search-live">
  <div class="row g-2 align-items-end">
    <div class="col-12 col-lg-8">
      <label class="form-label fw-semibold">Búsqueda en vivo</label>
      <input
        type="text"
        id="liveSearch"
        class="form-control"
        value="<?= h($q) ?>"
        placeholder="Escribí CI, nombre o apellido y Enter selecciona"
        autocomplete="off"
      >
      <div class="mini mt-1">
        Si la búsqueda deja <b>1 resultado</b>, presioná <b>Enter</b> para marcarlo y seguir con otra búsqueda.
      </div>
    </div>

    <div class="col-12 col-lg-4 d-flex gap-2">
      <button type="button" class="btn btn-outline-secondary w-100" id="btnLimpiarBusqueda">
        <i class="bi bi-x-circle me-1"></i>Limpiar búsqueda
      </button>
    </div>
  </div>
</div>

<div class="row g-3">
  <div class="col-12 col-xl-6">
    <div class="card-pro p-3 mb-3">
      <div class="d-flex justify-content-between align-items-center mb-2 sticky-actions">
        <div class="fw-bold">Disponibles</div>
        <div class="mini">
          Seleccionados: <span id="seleccionadosInfo" class="selected-counter">0</span>
        </div>
      </div>

      <?php if (empty($noMatric)): ?>
        <div class="text-muted">No hay estudiantes disponibles con este filtro.</div>
      <?php else: ?>
        <form method="post" id="frmDisponibles">
          <input type="hidden" name="csrf" value="<?= h(csrf_token()) ?>">
          <input type="hidden" name="action" value="matricular_seleccionados">
          <input type="hidden" name="institucion" value="<?= h($institucion) ?>">
          <input type="hidden" name="anio" value="<?= (int)$anio ?>">
          <input type="hidden" name="turno" value="<?= h($turno) ?>">
          <input type="hidden" name="nivel" value="<?= h($nivel) ?>">
          <input type="hidden" name="curso" value="<?= h($curso) ?>">
          <input type="hidden" name="seccion" value="<?= h($seccion) ?>">
          <input type="hidden" name="estado" value="<?= h($estado) ?>">
          <input type="hidden" name="q" value="">

          <div class="d-flex justify-content-between align-items-center mb-2">
            <div class="mini">
              <label class="me-2">
                <input type="checkbox" id="chkAllAvail" class="form-check-input me-1">
                Seleccionar visibles
              </label>
            </div>
            <div class="d-flex gap-2">
              <label class="mini d-flex align-items-center gap-2">
                <input type="checkbox" class="form-check-input" name="auto_sync" value="1" checked>
                Sincronizar al finalizar
              </label>
              <button class="btn btn-sm btn-brand" type="submit">
                <i class="bi bi-person-check me-1"></i>Matricular seleccionados
              </button>
            </div>
          </div>

          <div class="soft-table table-responsive" style="max-height:52vh;">
            <table class="table table-sm align-middle mb-0">
              <thead class="sticky-top">
                <tr>
                  <th style="width:42px;"></th>
                  <th>Alumno</th>
                  <th>CI</th>
                  <th>Estado</th>
                  <th style="width:150px;"></th>
                </tr>
              </thead>
              <tbody id="tbodyDisponibles">
                <?php foreach ($noMatric as $e): ?>
                  <?php
                    $searchIndex = mb_strtolower(trim(
                      ($e['ci'] ?? '') . ' ' .
                      ($e['apellidos'] ?? '') . ' ' .
                      ($e['nombres'] ?? '') . ' ' .
                      ((string)($e['matricula_estado'] ?? 'disponible'))
                    ));
                  ?>
                  <tr
                    class="row-buscable row-disponible"
                    data-search="<?= h($searchIndex) ?>"
                    data-id="<?= (int)$e['id'] ?>"
                    tabindex="0"
                  >
                    <td class="text-center">
                      <input
                        class="form-check-input chkAvail"
                        type="checkbox"
                        name="estudiantes[]"
                        value="<?= (int)$e['id'] ?>"
                      >
                    </td>
                    <td class="fw-semibold"><?= h((string)($e['nombres'] ?? '')) ?></td>
                    <td><?= h($e['ci'] ?? '-') ?></td>
                    <td><span class="badge-pill badge-warn">Disponible</span></td>
                    <td class="text-end">
                      <button
                        type="submit"
                        class="btn btn-sm btn-outline-primary btn-add-one"
                        name="estudiante_id"
                        value="<?= (int)$e['id'] ?>"
                        data-action="matricular_uno"
                      >
                        <i class="bi bi-plus-circle me-1"></i>Agregar
                      </button>
                    </td>
                  </tr>
                <?php endforeach; ?>
              </tbody>
            </table>
          </div>
        </form>
      <?php endif; ?>
    </div>

    <div class="card-pro p-3">
      <div class="d-flex justify-content-between align-items-center mb-2 sticky-actions">
        <div class="fw-bold">Nómina completa</div>
        <div class="mini">
          Muestra toda la nómina, evaluada con la institución/curso/sección/turno actual.
        </div>
      </div>

      <?php if (empty($nominaCompleta)): ?>
        <div class="text-muted">No hay estudiantes en la nómina.</div>
      <?php else: ?>
        <div class="soft-table table-responsive" style="max-height:60vh;">
          <table class="table table-sm align-middle mb-0">
            <thead class="sticky-top">
              <tr>
                <th>Alumno</th>
                <th>CI</th>
                <th>Estado actual</th>
                <th style="width:220px;"></th>
              </tr>
            </thead>
            <tbody id="tbodyNomina">
              <?php foreach ($nominaCompleta as $e): ?>
                <?php
                  if (!empty($e['esta_en_filtro_actual'])) {
                    $label = 'Matriculado aquí';
                    $badgeClass = 'badge-ok';
                  } elseif (!empty($e['esta_en_otro_curso'])) {
                    $label = 'Matriculado en otro curso';
                    $badgeClass = 'badge-muted';
                  } else {
                    $label = 'No matriculado';
                    $badgeClass = 'badge-warn';
                  }

                  $searchIndex = mb_strtolower(trim(
                    ($e['ci'] ?? '') . ' ' .
                    ($e['apellidos'] ?? '') . ' ' .
                    ($e['nombres'] ?? '') . ' ' .
                    $label
                  ));
                ?>
                <tr class="row-buscable row-nomina" data-search="<?= h($searchIndex) ?>">
                  <td class="fw-semibold"><?= h((string)($e['nombres'] ?? '')) ?></td>
                  <td><?= h($e['ci'] ?? '-') ?></td>
                  <td><span class="badge-pill <?= h($badgeClass) ?>"><?= h($label) ?></span></td>
                  <td class="text-end">
                    <?php if (!empty($e['esta_en_filtro_actual'])): ?>
                      <span class="mini">Ya está en este curso</span>
                    <?php elseif (!empty($e['esta_en_otro_curso'])): ?>
                      <span class="mini">
                        Está en <?= h(($e['matricula_nivel'] ?? '') . ' / ' . ($e['matricula_curso'] ?? '') . ' / ' . ($e['matricula_seccion'] ?? 'A') . ' / ' . ($e['matricula_turno'] ?? '')) ?>
                      </span>
                    <?php else: ?>
                      <form method="post" class="d-inline">
                        <input type="hidden" name="csrf" value="<?= h(csrf_token()) ?>">
                        <input type="hidden" name="action" value="matricular_uno">
                        <input type="hidden" name="institucion" value="<?= h($institucion) ?>">
                        <input type="hidden" name="anio" value="<?= (int)$anio ?>">
                        <input type="hidden" name="turno" value="<?= h($turno) ?>">
                        <input type="hidden" name="nivel" value="<?= h($nivel) ?>">
                        <input type="hidden" name="curso" value="<?= h($curso) ?>">
                        <input type="hidden" name="seccion" value="<?= h($seccion) ?>">
                        <input type="hidden" name="estado" value="<?= h($estado) ?>">
                        <input type="hidden" name="q" value="">
                        <input type="hidden" name="estudiante_id" value="<?= (int)$e['id'] ?>">
                        <input type="hidden" name="auto_sync" value="1">
                        <button class="btn btn-sm btn-outline-primary" type="submit">
                          <i class="bi bi-plus-circle me-1"></i>Matricular
                        </button>
                      </form>
                    <?php endif; ?>
                  </td>
                </tr>
              <?php endforeach; ?>
            </tbody>
          </table>
        </div>
      <?php endif; ?>
    </div>
  </div>

  <div class="col-12 col-xl-6">
    <div class="card-pro p-3">
      <div class="fw-bold mb-2">Matriculados</div>

      <?php if (empty($matriculados)): ?>
        <div class="text-muted">Todavía no hay matrículas con este filtro.</div>
      <?php else: ?>
        <div class="soft-table table-responsive" style="max-height:75vh;">
          <table class="table table-sm align-middle mb-0">
            <thead class="sticky-top">
              <tr>
                <th>Alumno</th>
                <th>CI</th>
                <th>Estado</th>
                <th style="width:160px;"></th>
              </tr>
            </thead>
            <tbody id="tbodyMatriculados">
              <?php foreach ($matriculados as $m): ?>
                <?php
                  $estadoLabel = strtoupper((string)($m['estado'] ?? ''));
                  $searchIndex = mb_strtolower(trim(
                    ($m['ci'] ?? '') . ' ' .
                    ($m['apellidos'] ?? '') . ' ' .
                    ($m['nombres'] ?? '') . ' ' .
                    $estadoLabel
                  ));
                ?>
                <tr class="row-buscable row-matriculado" data-search="<?= h($searchIndex) ?>">
                  <td class="fw-semibold"><?= h((string)($m['nombres'] ?? '')) ?></td>
                  <td><?= h($m['ci'] ?? '-') ?></td>
                  <td>
                    <?php if ($estadoLabel === 'ACTIVO'): ?>
                      <span class="badge text-bg-success">ACTIVO</span>
                    <?php else: ?>
                      <span class="badge text-bg-secondary"><?= h($m['estado']) ?></span>
                    <?php endif; ?>
                  </td>
                  <td class="text-end">
                    <form method="post" class="d-inline">
                      <input type="hidden" name="csrf" value="<?= h(csrf_token()) ?>">
                      <input type="hidden" name="action" value="cambiar_estado">
                      <input type="hidden" name="institucion" value="<?= h($institucion) ?>">
                      <input type="hidden" name="anio" value="<?= (int)$anio ?>">
                      <input type="hidden" name="turno" value="<?= h($turno) ?>">
                      <input type="hidden" name="nivel" value="<?= h($nivel) ?>">
                      <input type="hidden" name="curso" value="<?= h($curso) ?>">
                      <input type="hidden" name="seccion" value="<?= h($seccion) ?>">
                      <input type="hidden" name="estado" value="<?= h($estado) ?>">
                      <input type="hidden" name="q" value="">
                      <input type="hidden" name="matricula_id" value="<?= (int)$m['id'] ?>">

                      <?php if ($estadoLabel === 'ACTIVO'): ?>
                        <input type="hidden" name="nuevo_estado" value="INACTIVO">
                        <button class="btn btn-sm btn-outline-danger" type="submit">Anular</button>
                      <?php else: ?>
                        <input type="hidden" name="nuevo_estado" value="ACTIVO">
                        <button class="btn btn-sm btn-outline-success" type="submit">Activar</button>
                      <?php endif; ?>
                    </form>
                  </td>
                </tr>
              <?php endforeach; ?>
            </tbody>
          </table>
        </div>
      <?php endif; ?>
    </div>
  </div>
</div>

<script>
(function () {
  const liveSearch = document.getElementById('liveSearch');
  const btnLimpiarBusqueda = document.getElementById('btnLimpiarBusqueda');
  const chkAllAvail = document.getElementById('chkAllAvail');
  const frmDisponibles = document.getElementById('frmDisponibles');
  let filaActivaIndex = -1;

  function normalize(str) {
    return (str || '')
      .toString()
      .toLowerCase()
      .normalize('NFD')
      .replace(/[\u0300-\u036f]/g, '')
      .trim();
  }

  function getFilasDisponibles() {
    return Array.from(document.querySelectorAll('#tbodyDisponibles .row-disponible'));
  }

  function getFilasDisponiblesVisibles() {
    return getFilasDisponibles().filter(tr => !tr.classList.contains('row-hidden'));
  }

  function limpiarFilaActiva() {
    getFilasDisponibles().forEach(tr => tr.classList.remove('table-active'));
    filaActivaIndex = -1;
  }

  function enfocarFila(index) {
    const filas = getFilasDisponiblesVisibles();
    limpiarFilaActiva();

    if (index >= 0 && index < filas.length) {
      filas[index].classList.add('table-active');
      filaActivaIndex = index;
      filas[index].scrollIntoView({ block: 'nearest' });
    }
  }

  function actualizarEstiloFila(fila) {
    const chk = fila ? fila.querySelector('.chkAvail') : null;
    if (!fila || !chk) return;
    fila.classList.toggle('row-checked', chk.checked);
  }

  function toggleCheckboxDeFila(fila, forzarEstado = null) {
    if (!fila) return;
    const chk = fila.querySelector('.chkAvail');
    if (!chk) return;

    chk.checked = (forzarEstado === null) ? !chk.checked : !!forzarEstado;
    actualizarEstiloFila(fila);
    actualizarContadorSeleccionados();
  }

  function actualizarContadorSeleccionados() {
    if (!frmDisponibles) return;
    const seleccionados = frmDisponibles.querySelectorAll('.chkAvail:checked').length;
    const box = document.getElementById('seleccionadosInfo');
    if (box) box.textContent = String(seleccionados);
  }

  function aplicarBusquedaEnVivo() {
    const q = normalize(liveSearch ? liveSearch.value : '');

    const filas = Array.from(document.querySelectorAll('.row-buscable'));
    let visiblesDisponibles = 0;
    let visiblesNomina = 0;

    filas.forEach((tr) => {
      const text = normalize(tr.getAttribute('data-search') || '');
      const visible = q === '' || text.includes(q);

      tr.classList.toggle('row-hidden', !visible);

      if (visible && tr.classList.contains('row-disponible')) visiblesDisponibles++;
      if (visible && tr.classList.contains('row-nomina')) visiblesNomina++;
    });

    const chipDisp = document.getElementById('chipDisponibles');
    const chipNom = document.getElementById('chipNomina');
    if (chipDisp) chipDisp.textContent = String(visiblesDisponibles);
    if (chipNom) chipNom.textContent = String(visiblesNomina);

    if (chkAllAvail) chkAllAvail.checked = false;
    limpiarFilaActiva();

    const visibles = getFilasDisponiblesVisibles();
    if (q !== '' && visibles.length > 0) {
      enfocarFila(0);
    }
  }

  function seleccionarResultadoUnicoYContinuar() {
    const visibles = getFilasDisponiblesVisibles();
    if (visibles.length !== 1) return false;

    toggleCheckboxDeFila(visibles[0], true);

    if (liveSearch) {
      liveSearch.value = '';
      aplicarBusquedaEnVivo();
      liveSearch.focus();
    }
    return true;
  }

  if (liveSearch) {
    liveSearch.addEventListener('input', aplicarBusquedaEnVivo);

    liveSearch.addEventListener('keydown', function (e) {
      if (e.key === 'Enter') {
        e.preventDefault();
        if (!seleccionarResultadoUnicoYContinuar()) {
          const visibles = getFilasDisponiblesVisibles();
          if (visibles.length > 0) enfocarFila(0);
        }
      }

      if (e.key === 'ArrowDown') {
        const visibles = getFilasDisponiblesVisibles();
        if (!visibles.length) return;
        e.preventDefault();
        enfocarFila(0);
      }
    });
  }

  if (btnLimpiarBusqueda) {
    btnLimpiarBusqueda.addEventListener('click', function () {
      if (liveSearch) {
        liveSearch.value = '';
        aplicarBusquedaEnVivo();
        liveSearch.focus();
      }
    });
  }

  document.addEventListener('keydown', function (e) {
    const filas = getFilasDisponiblesVisibles();
    if (!filas.length) return;

    const tag = (document.activeElement?.tagName || '').toLowerCase();
    const isTyping = tag === 'input' || tag === 'textarea' || tag === 'select';

    if (document.activeElement === liveSearch) return;
    if (isTyping && document.activeElement !== liveSearch) return;

    if (e.key === 'ArrowDown') {
      e.preventDefault();
      if (filaActivaIndex < 0) {
        enfocarFila(0);
      } else {
        enfocarFila(Math.min(filaActivaIndex + 1, filas.length - 1));
      }
    }

    if (e.key === 'ArrowUp') {
      e.preventDefault();
      if (filaActivaIndex < 0) {
        enfocarFila(0);
      } else {
        enfocarFila(Math.max(filaActivaIndex - 1, 0));
      }
    }

    if (e.key === 'Enter' && filaActivaIndex >= 0) {
      e.preventDefault();
      const fila = filas[filaActivaIndex];
      toggleCheckboxDeFila(fila);
      if (liveSearch) liveSearch.focus();
    }

    if (e.key === 'Escape' && liveSearch) {
      liveSearch.focus();
    }
  });

  if (chkAllAvail && frmDisponibles) {
    chkAllAvail.addEventListener('change', function () {
      const visibles = Array.from(frmDisponibles.querySelectorAll('.row-disponible:not(.row-hidden)'));
      visibles.forEach(fila => toggleCheckboxDeFila(fila, chkAllAvail.checked));
      actualizarContadorSeleccionados();
    });
  }

  if (frmDisponibles) {
    frmDisponibles.querySelectorAll('.chkAvail').forEach(chk => {
      chk.addEventListener('change', function () {
        const fila = this.closest('.row-disponible');
        actualizarEstiloFila(fila);
        actualizarContadorSeleccionados();
      });
    });

    frmDisponibles.querySelectorAll('.row-disponible').forEach(fila => {
      fila.addEventListener('click', function (e) {
        const target = e.target;

        if (target.closest('.btn-add-one')) return;
        if (target.classList.contains('chkAvail')) return;

        toggleCheckboxDeFila(fila);
      });

      fila.addEventListener('dblclick', function () {
        toggleCheckboxDeFila(fila, true);
        if (liveSearch) {
          liveSearch.value = '';
          aplicarBusquedaEnVivo();
          liveSearch.focus();
        }
      });
    });

    frmDisponibles.querySelectorAll('.btn-add-one').forEach(btn => {
      btn.addEventListener('click', function () {
        const actionInput = frmDisponibles.querySelector('input[name="action"]');
        if (actionInput) actionInput.value = this.dataset.action || 'matricular_uno';

        frmDisponibles.querySelectorAll('.chkAvail').forEach(ch => {
          if (parseInt(ch.value, 10) !== parseInt(this.value, 10)) {
            ch.checked = false;
            const fila = ch.closest('.row-disponible');
            if (fila) actualizarEstiloFila(fila);
          }
        });

        let estInput = frmDisponibles.querySelector('input[name="estudiante_id"]');
        if (!estInput) {
          estInput = document.createElement('input');
          estInput.type = 'hidden';
          estInput.name = 'estudiante_id';
          frmDisponibles.appendChild(estInput);
        }
        estInput.value = this.value;
        actualizarContadorSeleccionados();
      });
    });

    frmDisponibles.addEventListener('submit', function (e) {
      const submitter = e.submitter;
      const actionInput = frmDisponibles.querySelector('input[name="action"]');

      if (submitter && submitter.classList.contains('btn-add-one')) {
        if (actionInput) actionInput.value = 'matricular_uno';
        return;
      }

      if (actionInput) actionInput.value = 'matricular_seleccionados';
    });
  }

  getFilasDisponibles().forEach(actualizarEstiloFila);
  actualizarContadorSeleccionados();
  aplicarBusquedaEnVivo();
})();
</script>

<?php include __DIR__ . '/../../app/views/footer.php'; ?>