<?php
declare(strict_types=1);

date_default_timezone_set('America/Asuncion');

require_once __DIR__ . '/../../app/bootstrap.php';

header('Content-Type: application/json; charset=utf-8');

function normalizarCedula(?string $valor): string
{
    return trim((string)$valor);
}

function contieneTexto(string $texto, string $busqueda): bool
{
    return mb_stripos($texto, $busqueda) !== false;
}

function rangoPeriodo(string $periodo): array
{
    $tz = new DateTimeZone('America/Asuncion');
    $ahora = new DateTime('now', $tz);

    switch ($periodo) {
        case 'ayer':
            $inicio = (clone $ahora)->modify('-1 day')->setTime(0, 0, 0);
            $fin    = (clone $ahora)->modify('-1 day')->setTime(23, 59, 59);
            break;

        case 'semana':
            $inicio = (clone $ahora)->modify('monday this week')->setTime(0, 0, 0);
            $fin    = (clone $inicio)->modify('+6 days')->setTime(23, 59, 59);
            break;

        case 'mes':
            $inicio = (clone $ahora)->modify('first day of this month')->setTime(0, 0, 0);
            $fin    = (clone $ahora)->modify('last day of this month')->setTime(23, 59, 59);
            break;

        case 'todos':
            $inicio = new DateTime('2000-01-01 00:00:00', $tz);
            $fin    = new DateTime('2100-12-31 23:59:59', $tz);
            break;

        case 'hoy':
        default:
            $inicio = (clone $ahora)->setTime(0, 0, 0);
            $fin    = (clone $ahora)->setTime(23, 59, 59);
            break;
    }

    return [$inicio, $fin];
}

function construirGrupoAcademico(string $nivel, string $curso): array
{
    $nivel = strtoupper(trim($nivel));
    $curso = trim($curso);

    $grado = '-';
    $cursoOut = '-';
    $grupo = '-';

    if ($nivel === 'EEB' && in_array($curso, ['7°', '8°', '9°'], true)) {
        $grado = $curso;
        $grupo = $curso;
    } elseif (in_array($nivel, ['BTC', 'BC'], true) && in_array($curso, ['1°', '2°', '3°'], true)) {
        $cursoOut = $curso;
        $grupo = $curso;
    } else {
        if (in_array($curso, ['7°', '8°', '9°'], true)) {
            $grado = $curso;
            $grupo = $curso;
        } elseif (in_array($curso, ['1°', '2°', '3°'], true)) {
            $cursoOut = $curso;
            $grupo = $curso;
        }
    }

    return [
        'grado' => $grado,
        'curso' => $cursoOut,
        'grupo_academico' => $grupo,
    ];
}

function contarDiasLectivos(DateTime $inicio, DateTime $fin): int
{
    $dias = 0;
    $cursor = clone $inicio;

    while ($cursor <= $fin) {
        $n = (int)$cursor->format('N'); // 1 lunes ... 7 domingo
        if ($n >= 1 && $n <= 5) {
            $dias++;
        }
        $cursor->modify('+1 day');
    }

    return $dias;
}

try {
    $pdo = db();

    $periodo = trim((string)($_GET['periodo'] ?? 'hoy'));
    $institucion = trim((string)($_GET['institucion'] ?? ''));
    $nivel = trim((string)($_GET['nivel'] ?? ''));
    $grado = trim((string)($_GET['grado'] ?? ''));
    $curso = trim((string)($_GET['curso'] ?? ''));
    $turno = trim((string)($_GET['turno'] ?? ''));
    $seccion = trim((string)($_GET['seccion'] ?? ''));
    $q = trim((string)($_GET['q'] ?? ''));
    $limit = (int)($_GET['limit'] ?? 300);

    if ($limit <= 0) $limit = 300;
    if ($limit > 1000) $limit = 1000;

    $anioActual = (int)date('Y');
    [$inicio, $fin] = rangoPeriodo($periodo);

    $where = [
        "m.anio_lectivo = :anio",
        "m.estado = 'ACTIVO'",
        "e.activo = 1",
    ];

    $params = [
        ':anio' => $anioActual,
    ];

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

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

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

    if ($seccion !== '') {
        $where[] = "COALESCE(m.seccion, 'A') = :seccion";
        $params[':seccion'] = $seccion;
    }

    $sqlMatriculados = "
        SELECT
            m.id AS matricula_id,
            m.estudiante_id,
            m.institucion,
            m.anio_lectivo,
            m.nivel,
            m.curso,
            m.seccion,
            m.turno,
            m.estado,
            e.ci,
            e.nombres,
            e.apellidos
        FROM matriculas m
        INNER JOIN estudiantes e ON e.id = m.estudiante_id
        WHERE " . implode(' AND ', $where) . "
        ORDER BY e.nombres
        LIMIT {$limit}
    ";

    $stMat = $pdo->prepare($sqlMatriculados);
    $stMat->execute($params);
    $matriculados = $stMat->fetchAll(PDO::FETCH_ASSOC) ?: [];

    $stMarcaciones = $pdo->prepare("
        SELECT
            id,
            fecha_hora,
            device_user_id,
            tipo_evento
        FROM marcaciones
        WHERE device_user_id = :ci
          AND fecha_hora BETWEEN :inicio AND :fin
        ORDER BY fecha_hora ASC
    ");

    $rows = [];
    $totalPresentes = 0;
    $totalAusentes = 0;

    $diasLectivos = 0;
    if (in_array($periodo, ['semana', 'mes'], true)) {
        $diasLectivos = contarDiasLectivos($inicio, $fin);
    }

    foreach ($matriculados as $m) {
        $ci = normalizarCedula($m['ci'] ?? '');
        $nombre = trim((string)($m['nombres'] ?? ''));
        $grupo = construirGrupoAcademico((string)($m['nivel'] ?? ''), (string)($m['curso'] ?? ''));

        if ($grado !== '' && $grupo['grado'] !== $grado) {
            continue;
        }

        if ($curso !== '' && $grupo['curso'] !== $curso) {
            continue;
        }

        $marcaciones = [];
        if ($ci !== '') {
            $stMarcaciones->execute([
                ':ci' => $ci,
                ':inicio' => $inicio->format('Y-m-d H:i:s'),
                ':fin' => $fin->format('Y-m-d H:i:s'),
            ]);
            $marcaciones = $stMarcaciones->fetchAll(PDO::FETCH_ASSOC) ?: [];
        }

        $estadoAsistencia = 'ausente';
        $primeraMarcacion = '-';
        $ultimaMarcacion = '-';
        $diasPresentes = 0;
        $diasAusentes = 0;

        if (!empty($marcaciones)) {
            $estadoAsistencia = 'presente';
            $primeraMarcacion = (string)($marcaciones[0]['fecha_hora'] ?? '-');
            $ultimaMarcacion = (string)($marcaciones[count($marcaciones) - 1]['fecha_hora'] ?? '-');
            $totalPresentes++;
        } else {
            $totalAusentes++;
        }

        if (in_array($periodo, ['semana', 'mes'], true)) {
            $diasUnicos = [];
            foreach ($marcaciones as $mk) {
                $d = substr((string)$mk['fecha_hora'], 0, 10);
                $diasUnicos[$d] = true;
            }
            $diasPresentes = count($diasUnicos);
            $diasAusentes = max(0, $diasLectivos - $diasPresentes);
        }

        $textoBusqueda = mb_strtolower(trim(
            ($ci ?? '') . ' ' .
            ($nombre ?? '') . ' ' .
            ((string)($m['institucion'] ?? '')) . ' ' .
            ((string)($m['nivel'] ?? '')) . ' ' .
            ((string)($grupo['grado'] ?? '')) . ' ' .
            ((string)($grupo['curso'] ?? '')) . ' ' .
            ((string)($m['turno'] ?? '')) . ' ' .
            ((string)($m['seccion'] ?? '')) . ' ' .
            $estadoAsistencia
        ));

        if ($q !== '' && !contieneTexto($textoBusqueda, mb_strtolower($q))) {
            continue;
        }

        $rows[] = [
            'matricula_id' => (int)$m['matricula_id'],
            'estudiante_id' => (int)$m['estudiante_id'],
            'cedula' => $ci,
            'nombre' => $nombre !== '' ? $nombre : '-',
            'institucion' => (string)($m['institucion'] ?? '-'),
            'nivel' => (string)($m['nivel'] ?? '-'),
            'grado' => $grupo['grado'],
            'curso' => $grupo['curso'],
            'grupo_academico' => $grupo['grupo_academico'],
            'seccion' => (string)($m['seccion'] ?? 'A'),
            'turno' => (string)($m['turno'] ?? '-'),
            'estado_asistencia' => $estadoAsistencia,
            'primera_marcacion' => $primeraMarcacion,
            'ultima_marcacion' => $ultimaMarcacion,
            'dias_presentes' => $diasPresentes,
            'dias_ausentes' => $diasAusentes,
        ];
    }

    usort($rows, function (array $a, array $b): int {
        $ga = (string)($a['grupo_academico'] ?? '');
        $gb = (string)($b['grupo_academico'] ?? '');
        if ($ga !== $gb) return strcmp($ga, $gb);

        $na = (string)($a['nombre'] ?? '');
        $nb = (string)($b['nombre'] ?? '');
        return strcmp($na, $nb);
    });

    echo json_encode([
        'ok' => true,
        'resumen' => [
            'total_matriculados' => count($rows),
            'total_presentes' => count(array_filter($rows, fn($r) => $r['estado_asistencia'] === 'presente')),
            'total_ausentes' => count(array_filter($rows, fn($r) => $r['estado_asistencia'] === 'ausente')),
            'dias_lectivos' => $diasLectivos,
        ],
        'rows' => $rows,
        'server_time' => date('Y-m-d H:i:s'),
        'periodo' => $periodo,
    ], JSON_UNESCAPED_UNICODE);

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