<?php
require_once("../functions.php");
$pag = basename($_SERVER['PHP_SELF']);
gen_plantilla(true, $pag, false, false, '', false, false);

//Comprobar is está sistema de incidencias activo
if(!SISTEMA_INCIDENCIAS){
    crear_notificacion("error", "No tienes acceso a esta página");
    exit;
}

//Comprobar cada registro desde el último cierre de mes en adelante
$fechas = consulta("SELECT fecha_fin FROM meses_cerrados ORDER BY id DESC LIMIT 1;", [], true);
if (!empty($fechas))
    $fech = $fechas[0]["fecha_fin"];
else
    $fech = date("Y-m-d", strtotime(date("Y-m-d") . " -30 days")); //coge los últimos 30 días

//coger registros mayores a esta fecha
$registros = consulta(
    "SELECT * FROM registros WHERE fecha>? AND fecha<? AND activo=1 ORDER BY id_empleado,fecha;",
    [$fech, date("Y-m-d")],
    true
); //Actualizado beta 24w21b
if (empty($registros)) {
    crear_notificacion('correcto', 'No hay nuevos registros desde el último cierre de mes');
    crear_log('advertencia', 'No hay nuevas incidencias', $pag, 'No hay registros desde el último cierre de mes [$fech, ' . date("Y-m-d") . ']');
    exit;
}

$dias = [1 => 'lun', 2 => 'mar', 3 => 'mie', 4 => 'jue', 5 => 'vie', 6 => 'sab', 7 => 'dom'];

function get_horas_cached($id, $dia) {
    static $cache = [];
    if (!isset($cache[$id][$dia])) $cache[$id][$dia] = get_horas_hace_empleado($id, $dia);
    return $cache[$id][$dia];
}

$idsEmp = [];
for ($ii = 0, $nr = count($registros); $ii < $nr; $ii++) $idsEmp[$registros[$ii]['id_empleado']] = true;
$idsEmp = array_keys($idsEmp);
$empPlaceholders = implode(',', array_fill(0, count($idsEmp), '?'));
$empRows = consulta(
    "SELECT t.*, g.id AS id_grupo, g.tipo_grupo, g.tipo_flexible, g.lunes, g.martes, g.miercoles, g.jueves, g.viernes, g.sabado, g.domingo
     FROM empleados t
     LEFT JOIN grupos g ON t.id_grupo=g.id
     WHERE t.id IN ($empPlaceholders);",
    $idsEmp,
    true
);
$empMap = [];
for ($e = 0, $ne = count($empRows); $e < $ne; $e++) $empMap[$empRows[$e]['id']] = $empRows[$e];

$bajas = consulta(
    "SELECT id_empleado, fecha, fecha_incorporacion FROM bajas_empleado;",
    [],
    true
);
$bajasMap = [];
for ($b = 0, $nb = count($bajas); $b < $nb; $b++) $bajasMap[$bajas[$b]['id_empleado']][] = [$bajas[$b]['fecha'], $bajas[$b]['fecha_incorporacion']];

$incExist = consulta(
    "SELECT id_empleado, fecha FROM incidencias WHERE fecha>? AND fecha<?;",
    [$fech, date("Y-m-d")],
    true
);
$incSet = [];
for ($ix = 0, $nix = count($incExist); $ix < $nix; $ix++) $incSet[$incExist[$ix]['id_empleado'].'|'.$incExist[$ix]['fecha']] = 1;

//RECOGER HORARIOS TEÓRICOS, PRIMERO LOS PERSONALIZADOS Y DESPUÉS GRUPALES

$singrupo = false;
for ($i = 0, $nreg = count($registros); $i < $nreg; $i++) {

    //Comprobar grupo del empleado y hacer comprobaciones
    $empRow = $empMap[$registros[$i]["id_empleado"]] ?? null;
    $grupo_empleado = [];
    if ($empRow) {
        $grupo_empleado[0] = [
            "tipo_grupo" => $empRow["tipo_grupo"],
            "tipo_flexible" => $empRow["tipo_flexible"],
            "lunes" => $empRow["lunes"],
            "martes" => $empRow["martes"],
            "miercoles" => $empRow["miercoles"],
            "jueves" => $empRow["jueves"],
            "viernes" => $empRow["viernes"],
            "sabado" => $empRow["sabado"],
            "domingo" => $empRow["domingo"]
        ];
    }

    // Si no hay grupo, saltar (ya se notificó en log si correspondía, pero aquí aseguramos no romper)
    if (empty($grupo_empleado)) continue; 

    if ($grupo_empleado[0]["tipo_grupo"] == 0) { //HORARIO FIJO - COMPROBACIÓN NORMAL
        $comprobacion_normal = true;
        $comprobacion_flexible = false;
    } elseif ($grupo_empleado[0]["tipo_flexible"] == 1) { //HORARIO FLEXIBLE DIARIO - COMPROBAR SI ES DÍA LABORAL Y HACER COMPROBACIONES
        $comprobacion_normal = true;
        $fecha = DateTime::createFromFormat('Y-m-d', $registros[$i]["fecha"]);
        $dia_semana = $fecha->format("N");
        //COMPROBAR SI ESE DÍA ES LABORAL, SI ES ES LABORAL, COMPROBACIÓN NORMAL TRUE
        if ($grupo_empleado[0]["lunes"] == 1 && $dia_semana == 1) $comprobacion_normal = true;
        elseif ($grupo_empleado[0]["martes"] == 1 && $dia_semana == 2) $comprobacion_normal = true;
        elseif ($grupo_empleado[0]["miercoles"] == 1 && $dia_semana == 3) $comprobacion_normal = true;
        elseif ($grupo_empleado[0]["jueves"] == 1 && $dia_semana == 4) $comprobacion_normal = true;
        elseif ($grupo_empleado[0]["viernes"] == 1 && $dia_semana == 5) $comprobacion_normal = true;
        elseif ($grupo_empleado[0]["sabado"] == 1 && $dia_semana == 6) $comprobacion_normal = true;
        elseif ($grupo_empleado[0]["domingo"] == 1 && $dia_semana == 7) $comprobacion_normal = true;
        else $comprobacion_normal = false;
        $comprobacion_flexible = true;
    } else { //HORARIO SEMANAL - LO COMPRUEBA UN ARCHIVO APARTE CON TAREA CRON SEMANAL
        $comprobacion_normal = false;
        $comprobacion_flexible = false;
    }

    if ($comprobacion_normal) {
        //Comprobar si el empleado estaba de baja
        $estaBaja = false;
        if (!empty($bajasMap[$registros[$i]["id_empleado"]])) {
            $f = $registros[$i]["fecha"];
            foreach ($bajasMap[$registros[$i]["id_empleado"]] as $rango) {
                $ini = $rango[0];
                $fin = $rango[1];
                if ($f >= $ini && ($fin === null || $f < $fin)) { $estaBaja = true; break; }
            }
        }
        if ($estaBaja) continue;

        $mensaje = "";
        //Registro impar
        $cant = 1;
        $hora1 = $registros[$i]["hora1"];
        if (!isset($registros[$i]["hora2"])) $hora2 = null;
        else {
            $hora2 = $registros[$i]["hora2"];
            $cant++;
        }
        if (!isset($registros[$i]["hora3"])) $hora3 = null;
        else {
            $hora3 = $registros[$i]["hora3"];
            $cant++;
        }
        if (!isset($registros[$i]["hora4"])) $hora4 = null;
        else {
            $hora4 = $registros[$i]["hora4"];
            $cant++;
        }
        if (!isset($registros[$i]["hora5"])) $hora5 = null;
        else {
            $hora5 = $registros[$i]["hora5"];
            $cant++;
        }
        if (!isset($registros[$i]["hora6"])) $hora6 = null;
        else {
            $hora6 = $registros[$i]["hora6"];
            $cant++;
        }
        
        $dt = DateTime::createFromFormat('Y-m-d', $registros[$i]["fecha"]);
        $n = (int)$dt->format('N');
        //incidencia si es impar
        if ($cant % 2 != 0 && $registros[$i]["fecha"] != date("Y-m-d")) $mensaje .= "<span class='men-incidencia incidencia-impar' title='Registro impar'>Impar</span>";
        //comprobar primero si es fin de semana, si es y ha hecho horas suma acumuladas
        if (fecha_fin_de_semana($registros[$i]["fecha"])) { //FIN DE SEMANA, HACER INCIDENCIA
            $mensaje .= "<span class='men-incidencia incidencia-finde' title='Registro en fin de semana'>Fin de semana</span>";
        } else {
            //hora1, hora2,hora3,hora4...podría fichar hasta 6
            //Para más adelante comparar si es día de vacaciones para el trabajador
            //comprobar si el id de empleado está en el array de horas personalizadas y si no en las grupales
            $horarios_personalizados = [];
            if (!empty($empRow)) {
                $diaPers = $dias[$n];
                $tienePersonal = false;
                for ($k = 1; $k <= 6; $k += 2) {
                    $hIni = $empRow[$diaPers . "h$k"] ?? null;
                    $hFin = $empRow[$diaPers . "h" . ($k + 1)] ?? null;
                    if (!empty($hIni) && !empty($hFin) && $hIni !== '00:00:00' && $hFin !== '00:00:00') { $tienePersonal = true; break; }
                }
                if ($tienePersonal) $horarios_personalizados = [$empRow['id']];
            }

            if (!empty($horarios_personalizados)) { //TIENE HORARIO PERSONALIZADO
                if ($cant % 2 == 0) {
                    $total_rel = get_horas_cached($registros[$i]["id_empleado"], $dias[$n]);
                    $total = calculo_horas_totales($hora1, $hora2, $hora3, $hora4, $hora5, $hora6);
                    //comprobar si ha hecho las 8 horas (si es más o menos incidencia)
                    if ($total < $total_rel) $mensaje .= "<span class='men-incidencia incidencia-ocho-' title='Menos de " . $total_rel . " horas'>-" . $total_rel . "h</span>";
                    elseif ($total > $total_rel) $mensaje .= "<span class='men-incidencia incidencia-ocho-mas' title='Más de " . $total_rel . " horas'>+" . $total_rel . "h</span>";
                }
            } else { //MIRAR HORARIOS GRUPALES
                $horario_grupal = [];
                if (!empty($empRow) && !empty($empRow['id_grupo'])) $horario_grupal = [['id' => $empRow['id_grupo']]];
                if (empty($horario_grupal)) $singrupo = true;

                if (!$singrupo && $cant % 2 == 0) {
                    //horas relativas
                    $total_rel = get_horas_cached($registros[$i]["id_empleado"], $dias[$n]);
                    $total = calculo_horas_totales($hora1, $hora2, $hora3, $hora4, $hora5, $hora6);
                    //comprobar si ha hecho las 8 horas (si es más o menos incidencia)
                    if (intval($total[0] . $total[1]) < $total_rel) $mensaje .= "<span class='men-incidencia incidencia-ocho-' title='Menos de " . $total_rel . " horas'>-" . $total_rel . "h</span>"; //Modificado beta 24w22e
                    elseif (intval($total[0] . $total[1]) > $total_rel) $mensaje .= "<span class='men-incidencia incidencia-ocho-mas' title='Más de " . $total_rel . " horas'>+" . $total_rel . "h</span>"; //Modificado beta 24w22e
                }
            }
        }
        $keyInc = $registros[$i]["id_empleado"].'|'.$registros[$i]["fecha"];
        if (strlen($mensaje) > 0 && empty($incSet[$keyInc])) {
            crear_incidencia($registros[$i]["id_empleado"],$registros[$i]["id"], $hora1, $hora2, $hora3, $hora4, $hora5, $hora6, $registros[$i]["fecha"], $mensaje);
            $incSet[$keyInc] = 1;
        }
    }
}
if ($singrupo) crear_notificacion("incidencia1", "Tienes empleados sin grupo u horario");

//Comprobar desde cierre de mes si algún día que no sea fin de semana y que no esté en días inhábiles
//si no hay registro, entonces sería incidencia
//coger empleados
$empleados = consulta(
    "SELECT t.* FROM empleados AS t
    LEFT JOIN grupos AS g ON t.id_grupo=g.id;",
    [],
    true
); //Modificado beta 24w23e

$fecha = DateTime::createFromFormat('Y-m-d', $fech);
$fecha_act = DateTime::createFromFormat('Y-m-d', date("Y-m-d"));
$fecha_act->modify('-1 day');

//En el caso de que fecha falle
if (!$fecha || !$fecha_act) {
    crear_notificacion('error', 'Ha ocurrido un error interno');
    crear_log('error', 'Error fecha incidencias', $pag, 'Error fecha es falsa');
    exit;
}

$gruposAll = consulta("SELECT * FROM grupos;", [], true);
$gruposMap = [];
for ($g = 0, $ng = count($gruposAll); $g < $ng; $g++) $gruposMap[$gruposAll[$g]['id']] = $gruposAll[$g];

$inh = consulta(
    "SELECT id_empleado, id_grupo, fecha_entrada, fecha_termina FROM dias_inhabiles WHERE fecha_entrada<=? AND fecha_termina>=?;",
    [$fecha_act->format('Y-m-d'), $fech],
    true
);
$inhEmp = [];
$inhGrp = [];
for ($h = 0, $nh = count($inh); $h < $nh; $h++) {
    if (!empty($inh[$h]['id_empleado'])) $inhEmp[$inh[$h]['id_empleado']][] = [$inh[$h]['fecha_entrada'], $inh[$h]['fecha_termina']];
    if (!empty($inh[$h]['id_grupo'])) $inhGrp[$inh[$h]['id_grupo']][] = [$inh[$h]['fecha_entrada'], $inh[$h]['fecha_termina']];
}

$regExist = consulta(
    "SELECT id_empleado, fecha FROM registros WHERE fecha>? AND fecha<?;",
    [$fech, date("Y-m-d")],
    true
);
$regSet = [];
for ($rx = 0, $nrx = count($regExist); $rx < $nrx; $rx++) $regSet[$regExist[$rx]['id_empleado'].'|'.$regExist[$rx]['fecha']] = 1;

while ($fecha->format('Y-m-d') <= $fecha_act->format('Y-m-d')) {
    $dia_semana = $fecha->format("N");
    //Hay algunos que trabajan fines de semana
    if ($dia_semana == 6 || $dia_semana == 7) {
        $fecha->modify('+1 day');
        continue;
    }
    //comprobar si hay un registo de este trabajador, comprobar si hay o no registro de vacaciones
    for ($i = 0, $ne2 = count($empleados); $i < $ne2; $i++) {
        $key = $empleados[$i]["id"].'|'.$fecha->format('Y-m-d');
        $resultado = isset($regSet[$key]) ? [['id' => 1]] : [];
        if (empty($resultado)) { //no hay registro, hacer comprobaciones
            //Comprobar grupo del empleado y hacer comprobaciones
            $grupo_empleado = [];
            if (!empty($empleados[$i]["id_grupo"]) && isset($gruposMap[$empleados[$i]["id_grupo"]])) $grupo_empleado[0] = $gruposMap[$empleados[$i]["id_grupo"]];
            if (empty($grupo_empleado)) {
                crear_log(
                    'error',
                    'Error al comprobar grupo de empleado',
                    $pag,
                    'El empleado ' . $empleados[$i]["nombre"] . ' con id ' . $empleados[$i]["id"] . ' no tiene grupo asignado.'
                );
                continue; //Si no tiene grupo, saltar al siguiente empleado
            }

            if ($grupo_empleado[0]["tipo_grupo"] == 0) { //HORARIO FIJO - COMPROBACIÓN NORMAL
                $comprobacion_normal = true;
                $comprobacion_flexible = false;
            } elseif ($grupo_empleado[0]["tipo_flexible"] == 1) { //HORARIO FLEXIBLE DIARIO - COMPROBAR SI ES DÍA LABORAL Y HACER COMPROBACIONES
                $comprobacion_normal = true;
                //COMPROBAR SI ESE DÍA ES LABORAL, SI ES ES LABORAL, COMPROBACIÓN NORMAL TRUE
                if ($grupo_empleado[0]["lunes"] == 1 && $dia_semana == 1) $comprobacion_normal = true;
                elseif ($grupo_empleado[0]["martes"] == 1 && $dia_semana == 2) $comprobacion_normal = true;
                elseif ($grupo_empleado[0]["miercoles"] == 1 && $dia_semana == 3) $comprobacion_normal = true;
                elseif ($grupo_empleado[0]["jueves"] == 1 && $dia_semana == 4) $comprobacion_normal = true;
                elseif ($grupo_empleado[0]["viernes"] == 1 && $dia_semana == 5) $comprobacion_normal = true;
                elseif ($grupo_empleado[0]["sabado"] == 1 && $dia_semana == 6) $comprobacion_normal = true;
                elseif ($grupo_empleado[0]["domingo"] == 1 && $dia_semana == 7) $comprobacion_normal = true;
                else $comprobacion_normal = false;
                $comprobacion_flexible = true;
            } else { //HORARIO SEMANAL - LO COMPRUEBA UN ARCHIVO APARTE CON TAREA CRON SEMANAL
                $comprobacion_normal = false;
                $comprobacion_flexible = false;
            }

            if ($comprobacion_normal) {
                //1º CONSULTA - COMPROBAR TIENE DÍA INHÁBIL POR EMPLEADO Y GRUPO Y CENTRO
                $res_1 = [];
                if (!empty($inhEmp[$empleados[$i]["id"]])) {
                    foreach ($inhEmp[$empleados[$i]["id"]] as $r) {
                        if ($fecha->format('Y-m-d') >= $r[0] && $fecha->format('Y-m-d') <= $r[1]) { $res_1 = [1]; break; }
                    }
                }
                if (empty($res_1) && !empty($inhGrp[$empleados[$i]["id_grupo"]])) {
                    foreach ($inhGrp[$empleados[$i]["id_grupo"]] as $r) {
                        if ($fecha->format('Y-m-d') >= $r[0] && $fecha->format('Y-m-d') <= $r[1]) { $res_1 = [1]; break; }
                    }
                } //Modificado beta 24w23e
                if (empty($res_1)) { //2º CONSULTA - COMPROBAR SI TIENE POR CENTRO
                    $mensaje = "<span class='men-incidencia incidencia-no-trabajo' title='No hay registro de trabajo'>No trabajado</span>";
                    consulta(
                        "INSERT INTO `incidencias`
                    (`id_empleado`, `nombre_empleado`, `id_registro`, `rh1`, `rh2`, `rh3`, `rh4`, `rh5`, `rh6`, `fecha`,
                    `diferencia_horas`, `id_motivo`, `estado`, `descripcion`)
                    SELECT ?,?,0,0,0,0,0,0,0,?,-8,NULL,1,? FROM dual
                    WHERE NOT EXISTS (SELECT 1 FROM incidencias WHERE id_empleado=? AND fecha=? AND rh1=0);",
                        [
                            $empleados[$i]["id"],
                            !empty($empleados[$i]["nombre"]) ? $empleados[$i]["nombre"] : 'Desconocido',
                            $fecha->format('Y-m-d'),
                            $mensaje,
                            $empleados[$i]["id"],
                            $fecha->format('Y-m-d')
                        ],
                        false
                    );
                }
            }
        }
    }
    $fecha->modify('+1 day');
}

//Comprobar incidencias con empleados de baja

$empleados_baja = consulta(
    "SELECT * FROM bajas_empleado;",
    [],
    true
);

for ($i = 0, $nbaja = count($empleados_baja); $i < $nbaja; $i++) {
    //Comprobar si hay incidencias activas en esas fechas
    $incidencias = consulta(
        'SELECT * FROM incidencias WHERE id_empleado=? AND fecha>=? AND (? IS NULL OR fecha <= ?) AND estado=1;',
        [$empleados_baja[$i]['id_empleado'], $empleados_baja[$i]['fecha'], $empleados_baja[$i]['fecha_incorporacion'], $empleados_baja[$i]['fecha_incorporacion']],
        true
    );
    for ($o = 0, $no = count($incidencias); $o < $no; $o++) {
        //Si hay incidencias activas, cambiar estado a 0
        consulta(
            'UPDATE incidencias SET estado=0 WHERE id=?;',
            [$incidencias[$o]['id']],
            false
        );
    }
}

//Comprobar si tiene incidencias activas
if (!empty(consulta("SELECT id FROM incidencias WHERE estado=1 LIMIT 1;", [], true)))
    crear_notificacion("incidencia", "Tienes incidencias activas");
