<?php
// Devuelve los horarios asignados para un mes y año dados (para pintar en el calendario)
require_once __DIR__ . '/../config/database.php';
header('Content-Type: application/json');

$year = isset($_GET['year']) ? intval($_GET['year']) : date('Y');
$month = isset($_GET['month']) ? intval($_GET['month']) : date('n');

try {
    $db = new Database();
    $conn = $db->connect();
    $stmt = $conn->prepare('
        SELECT h.id_horario, h.curp, p.NOMBRES, p.`APELLIDO PATERNO`, p.`APELLIDO MATERNO`, q.fecha_inicio, q.fecha_fin, d.id_detalle, d.semana, d.dia_semana, d.hora_entrada, d.hora_salida
        FROM HorariosAsignados h
        JOIN Plantilla p ON h.curp = p.CURP
        JOIN Quincenas q ON h.id_quincena = q.id_quincena
        JOIN DetalleHorariosSemana d ON h.id_horario = d.id_horario
        WHERE q.anio = ? AND q.mes = ?
    ');
    $stmt->execute([$year, $month]);
    $horarios = $stmt->fetchAll(PDO::FETCH_ASSOC);
    // Filtrar por colaboradores activos del usuario logueado
    session_start();
    $departamento = $_SESSION['pdv_usuario'] ?? '';
    $curpsActivos = [];
    if (!empty($departamento)) {
        require_once __DIR__ . '/../models/Empleados.php';
        $empleadosModel = new EmpleadosModel($conn);
        $empleadosActivos = $empleadosModel->getActivosByDepartamentoInterno($departamento);
        foreach ($empleadosActivos as $emp) {
            if (!empty($emp['curp'])) $curpsActivos[] = $emp['curp'];
        }
        // Filtrar horarios
        $horarios = array_filter($horarios, function($h) use ($curpsActivos) {
            return in_array($h['curp'], $curpsActivos);
        });
    }
    // Obtener descansos por id_horario
    $descansosPorHorario = [];
    $stmtDesc = $conn->prepare('SELECT id_descanso, id_horario, dia_semana, fecha_descanso FROM DiasDescanso WHERE id_horario IN (SELECT id_horario FROM HorariosAsignados WHERE id_quincena IN (SELECT id_quincena FROM Quincenas WHERE anio = ? AND mes = ?))');
    $stmtDesc->execute([$year, $month]);
    
    // Para cada descanso, calcular la semana basándose en la fecha
    foreach ($stmtDesc->fetchAll(PDO::FETCH_ASSOC) as $desc) {
        // Buscar el horario correspondiente para obtener fecha_inicio y fecha_fin
        $id_horario = $desc['id_horario'];
        $fecha_inicio = null;
        $fecha_fin = null;
        foreach ($horarios as $h) {
            if ($h['id_horario'] == $id_horario) {
                $fecha_inicio = $h['fecha_inicio'];
                $fecha_fin = $h['fecha_fin'];
                break;
            }
        }
        
        // CORREGIDO: Calcular semana basándose en el rango real de la quincena
        $semana = 1;
        if ($fecha_inicio && $fecha_fin && $desc['fecha_descanso']) {
            $fechaInicioQuincena = new DateTime($fecha_inicio);
            $fechaFinQuincena = new DateTime($fecha_fin);
            
            // Encontrar el lunes de la semana que CONTIENE la fecha_inicio
            $lunesInicio = clone $fechaInicioQuincena;
            while ($lunesInicio->format('N') != 1) {
                $lunesInicio->modify('-1 day');
            }
            
            $fechaDescanso = new DateTime($desc['fecha_descanso']);
            
            // Calcular diferencia de días desde el lunes de inicio
            $diff = $lunesInicio->diff($fechaDescanso);
            $diasDiferencia = (int)$diff->format('%r%a'); // Días con signo
            
            // Calcular semana (0-6 días = semana 1, 7-13 días = semana 2, 14+ días = semana 3)
            if ($diasDiferencia < 0) {
                $semana = 1; // Antes del lunes inicial, considerar semana 1
            } elseif ($diasDiferencia < 7) {
                $semana = 1;
            } elseif ($diasDiferencia < 14) {
                $semana = 2;
            } else {
                $semana = 3;
            }
        }
        
        $desc['semana'] = $semana;
        $descansosPorHorario[$desc['id_horario']][] = $desc;
    }
    // Agrupar por id_horario (un solo objeto por colaborador/quincena)
    $agrupados = [];
    $diasMap = [
        'Lunes' => 1, 'Martes' => 2, 'Miércoles' => 3, 'Jueves' => 4, 'Viernes' => 5, 'Sábado' => 6, 'Domingo' => 0
    ];
    // --- Deduplicar descansos por colaborador y fecha ---
    $descansosGlobalesPorCurp = [];
    foreach ($descansosPorHorario as $id_horario => $descansosArr) {
        foreach ($descansosArr as $desc) {
            $curp = null;
            // Buscar el curp correspondiente a este id_horario
            foreach ($horarios as $h) {
                if ($h['id_horario'] == $id_horario) {
                    $curp = $h['curp'];
                    break;
                }
            }
            if ($curp) {
                $fecha = $desc['fecha_descanso'];
                // Si no existe aún, agregar
                if (!isset($descansosGlobalesPorCurp[$curp][$fecha])) {
                    $descansosGlobalesPorCurp[$curp][$fecha] = $desc;
                }
            }
        }
    }
    foreach ($horarios as $h) {
        $id = $h['id_horario'];
        if (!isset($agrupados[$id])) {
            $agrupados[$id] = [
                'id_horario' => $h['id_horario'],
                'curp' => $h['curp'],
                'NOMBRES' => $h['NOMBRES'],
                'APELLIDO PATERNO' => $h['APELLIDO PATERNO'],
                'APELLIDO MATERNO' => $h['APELLIDO MATERNO'],
                'fecha_inicio' => $h['fecha_inicio'],
                'fecha_fin' => $h['fecha_fin'],
                'dias_trabajo' => [],
                // Descansos deduplicados por curp y fecha
                'descansos' => []
            ];
        }
        // Definir $semana ANTES de usarla
        $semana = (int)($h['semana'] ?? 1);
        
        // CORREGIDO: Calcular fechas basándose en el rango real de la quincena, no en el lunes más cercano
        // Esto evita desfases cuando la quincena no inicia en lunes
        $fechaInicioQuincena = new DateTime($h['fecha_inicio']);
        $fechaFinQuincena = new DateTime($h['fecha_fin']);
        
        // Encontrar el lunes de la semana que CONTIENE la fecha_inicio (puede ser antes o igual)
        $lunesInicio = clone $fechaInicioQuincena;
        while ($lunesInicio->format('N') != 1) {
            $lunesInicio->modify('-1 day');
        }
        
        // Encontrar el domingo de la semana que CONTIENE la fecha_fin (puede ser después o igual)
        $domingoFin = clone $fechaFinQuincena;
        while ($domingoFin->format('N') != 7) {
            $domingoFin->modify('+1 day');
        }
        
        // Generar todos los días del período completo (de lunes a domingo)
        $diaSemanaMap = [1=>'Lunes',2=>'Martes',3=>'Miércoles',4=>'Jueves',5=>'Viernes',6=>'Sábado',7=>'Domingo'];
        $diasEnPeriodo = [];
        $fechaActual = clone $lunesInicio;
        
        while ($fechaActual <= $domingoFin) {
            $diaNombre = $diaSemanaMap[(int)$fechaActual->format('N')];
            $diasEnPeriodo[] = [
                'fecha' => $fechaActual->format('Y-m-d'),
                'dia_semana' => $diaNombre
            ];
            $fechaActual->modify('+1 day');
        }
        
        // Agrupar por semana completa (lunes a domingo)
        $semanasFechas = [];
        $semanaActual = [];
        
        foreach ($diasEnPeriodo as $diaObj) {
            $semanaActual[] = $diaObj;
            // Si es domingo, cerrar la semana
            if ($diaObj['dia_semana'] === 'Domingo') {
                $semanasFechas[] = $semanaActual;
                $semanaActual = [];
            }
        }
        
        // Si quedaron días sin agrupar (última semana incompleta), agregarlos
        if (!empty($semanaActual)) {
            $semanasFechas[] = $semanaActual;
        }
        
        // Buscar la fecha que corresponde a la semana y día específica
        $fechaSemanaDia = null;
        if (isset($semanasFechas[$semana-1])) {
            foreach ($semanasFechas[$semana-1] as $diaObj) {
                if ($diaObj['dia_semana'] === $h['dia_semana']) {
                    $fechaSemanaDia = $diaObj['fecha'];
                    break;
                }
            }
        }
        
        // Si no se encontró en la semana indicada, buscar en todas las semanas como fallback
        if (!$fechaSemanaDia) {
            foreach ($semanasFechas as $semanaArr) {
                foreach ($semanaArr as $diaObj) {
                    if ($diaObj['dia_semana'] === $h['dia_semana']) {
                        $fechaSemanaDia = $diaObj['fecha'];
                        break 2;
                    }
                }
            }
        }
        
        if ($fechaSemanaDia) {
            $fechas = [$fechaSemanaDia];
        } else {
            $fechas = [];
        }
        // Agrupar por semana y día, evitando duplicados: si ya existe, priorizar el que tenga hora válida
        $dia = $h['dia_semana'];
        if (!isset($agrupados[$id]['_dias_trabajo_map'])) {
            $agrupados[$id]['_dias_trabajo_map'] = [];
        }
        if (!isset($agrupados[$id]['_dias_trabajo_map'][$semana])) {
            $agrupados[$id]['_dias_trabajo_map'][$semana] = [];
        }
        // Si ya existe un registro para este día/semana, priorizar el que tenga hora válida (no 00:00:00)
        $nuevoRegistro = [
            'id_detalle' => $h['id_detalle'],
            'semana' => $semana,
            'dia_semana' => $h['dia_semana'],
            'hora_entrada' => $h['hora_entrada'],
            'hora_salida' => $h['hora_salida'],
            'fechas' => $fechas
        ];
        $yaExiste = isset($agrupados[$id]['_dias_trabajo_map'][$semana][$dia]);
        if ($yaExiste) {
            $existente = $agrupados[$id]['_dias_trabajo_map'][$semana][$dia];
            $nuevoValido = ($nuevoRegistro['hora_entrada'] !== '00:00:00' || $nuevoRegistro['hora_salida'] !== '00:00:00');
            $existenteValido = ($existente['hora_entrada'] !== '00:00:00' || $existente['hora_salida'] !== '00:00:00');
            // Si el nuevo es válido y el existente no, reemplazar
            if ($nuevoValido && !$existenteValido) {
                $agrupados[$id]['_dias_trabajo_map'][$semana][$dia] = $nuevoRegistro;
            }
            // Si ambos son válidos, mantener el primero (ya insertado)
            // Si ambos no son válidos, mantener el primero
        } else {
            $agrupados[$id]['_dias_trabajo_map'][$semana][$dia] = $nuevoRegistro;
        }
    }
    // Convertir _dias_trabajo_map a dias_trabajo limpio, evitando duplicados por fecha
    foreach ($agrupados as &$agr) {
        if (isset($agr['_dias_trabajo_map'])) {
            $fechasOcupadas = [];
            $diasTrabajoFinal = [];
            if (count($agr['_dias_trabajo_map']) === 1) {
                $semanaKeys = array_keys($agr['_dias_trabajo_map']);
                $semanaBaseKey = $semanaKeys[0];
                $semanaBase = $agr['_dias_trabajo_map'][$semanaBaseKey];
                for ($s = 1; $s <= 3; $s++) {
                    foreach ($semanaBase as $dia => $info) {
                        if (!empty($info['fechas'])) {
                            $fecha = $info['fechas'][0];
                            if (!isset($fechasOcupadas[$fecha])) {
                                $nuevo = $info;
                                $nuevo['semana'] = $s;
                                $diasTrabajoFinal[] = $nuevo;
                                $fechasOcupadas[$fecha] = true;
                            }
                        }
                    }
                }
            } else {
                foreach ($agr['_dias_trabajo_map'] as $semana => $diasArr) {
                    foreach ($diasArr as $info) {
                        if (!empty($info['fechas'])) {
                            $fecha = $info['fechas'][0];
                            if (!isset($fechasOcupadas[$fecha])) {
                                $diasTrabajoFinal[] = $info;
                                $fechasOcupadas[$fecha] = true;
                            }
                        }
                    }
                }
            }
            $agr['dias_trabajo'] = $diasTrabajoFinal;
            unset($agr['_dias_trabajo_map']);
        }
    }
    // --- Agrupar por id_horario (NO por CURP) para mantener quincenas separadas ---
    $horariosFinal = [];
    foreach ($agrupados as $horario) {
        $id_horario = $horario['id_horario'];
        
        // Cada id_horario es único por quincena, así que no agrupar más
        $horarioData = [
            'id_horario' => $horario['id_horario'],
            'curp' => $horario['curp'],
            'NOMBRES' => $horario['NOMBRES'],
            'APELLIDO PATERNO' => $horario['APELLIDO PATERNO'],
            'APELLIDO MATERNO' => $horario['APELLIDO MATERNO'],
            'fecha_inicio' => $horario['fecha_inicio'],
            'fecha_fin' => $horario['fecha_fin'],
            'dias_trabajo' => $horario['dias_trabajo'],
            'descansos' => []
        ];
        
        // Agregar descansos para este horario específico
        if (isset($descansosPorHorario[$id_horario])) {
            $horarioData['descansos'] = $descansosPorHorario[$id_horario];
        }
        
        $horariosFinal[] = $horarioData;
    }
    
    echo json_encode(['success' => true, 'horarios' => $horariosFinal]);
} catch (Exception $e) {
    echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
