<?php


require_once "../vendor/autoload.php";
require_once "../include/bd_pdo.php";

$columnas = array(
    "SALÓN",
    "GRUPO",
    "CLAVE",
    "DOCENTE",
    "MATERIA",
    "LUNES",
    "MARTES",
    "MIÉRCOLES",
    "JUEVES",
    "VIERNES",
    "SÁBADO",
    "DURACIÓN",
);

$cl = ['salon', 'grupo', 'clave', 'maestro', 'materia',];

define('HORARIO', 5);
define('COLUMNA_MAXIMA', chr(count($columnas) + ord('A') - 1));
function columna_nombre(string $columna): array
{
    $nombre = "";
    $datos_nombre = explode(" ", str_replace(array("\n", chr(10), chr(13)), " ", trim(preg_replace('/_x([0-9a-fA-F]{4})_/', ' ', $columna))));
    $temp_nombre = explode(".", $datos_nombre[0]);
    if (count($temp_nombre) > 1) {
        $nombre .= $temp_nombre[1] . " ";
        $grado = $temp_nombre[0] . ".";
        array_shift($datos_nombre);
    } else
        $grado = strpos($datos_nombre[0], ".") !== false ? array_shift($datos_nombre) : null;

    $email = strpos($columna, "@") !== false ? array_pop($datos_nombre) : null;
    $nombre .= implode(" ", $datos_nombre);

    return array(
        "grado" => $grado,
        "nombre" => trim($nombre),
        "correo" => $email,
    );
}
###
function validar_columnas(object $sheet): void
{
    global $columnas;
    $diff = array_diff(array_map(fn ($col) => trim($col), get_columns($sheet)), $columnas);
    #array clean
    if (!empty($diff)) {
        $diff = array_filter($diff, fn ($col) => !empty($col));
        throw new Exception("Error en el formato del archivo: " . (empty($diff) ? "Columnas vacías" : "Columnas incorrectas: [" . implode(", ", $diff) . "]"));
    }
}
###
function get_columns(object $sheet)
{
    global $columnas;
    $columns = array();
    foreach ($sheet->getRowIterator(1, 1) as  $row)
        foreach ($row->getCellIterator() as $index => $cell) {
            $columns[$index] = mb_strtoupper($cell->getValue() ?? "");
            if ($index == COLUMNA_MAXIMA) break;
        }
    return $columns;
}
###
function foreach_sheet(object $workbook, callable $callback = null): void
{

    $sheets = $workbook->getSheetNames();
    // validate columns
    foreach ($sheets as $sheet) {
        $worksheet = $workbook->getSheetByName($sheet);
        validar_columnas($worksheet);
        foreach_register($worksheet, $callback, $sheet);
    }
}
###
function foreach_register(object $worksheet, callable $callback = null, string $sheet): void
{
    foreach ($worksheet->getRowIterator(2) as $key => $row) {
        $row_data = array();
        foreach ($row->getCellIterator() as $index => $cell) {
            $row_data[] = str_replace(' ', '', $cell->getValue() ?? "");
            if ($index == COLUMNA_MAXIMA) break;
        }

        if ($callback !== null) {
            $callback($row_data, $key, $sheet);
        }
    }
}

function horario(array &$row, int $fila, string $sheet): string
{
    global $cl, $db;
    date_default_timezone_set('UTC');
    $horario_tostring = "";
    for ($i = HORARIO; $i < count($row) - 1; $i++) {
        // echo $row[$i] . "  $i\n";
        if (!empty(trim($row[$i] ?? ""))) {
            $row[$i] = str_replace(array(" -", "- ", " - "), "-", $row[$i]);
            $separar_por_espacios = EXPLODE(" ", trim(preg_replace('!\s+!', ' ', $row[$i])));
            foreach ($separar_por_espacios as $horario) {
                $hora = // if string includes : then is string else is excel date
                    (strpos($horario, ":") === false)
                    ?   \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($horario)->format('H:i')
                    :   preg_replace('/[^0-9:]/', '', str_replace('.', ':', trim((strpos($horario, "-") !== false) ? explode("-", $horario)[0] : $horario)));

                if (
                    $hora > "22:00" || $hora < "07:00" || explode(":", $hora)[1]  % 15 !== 0
                ) {
                    throw new Exception("Error en el formato del archivo: Hora incorrecta [$hora] en la fila $fila, hoja $sheet.");
                }

                $duración = end($row);
                if ($duración <= 180 and $duración >= 30 and $duración % 15 == 0)
                    $bloques = $duración / 15;
                else if ($duración <= 3 and $duración >= 0.5)
                    $bloques = $duración * 60 / 15;
                else
                    throw new Exception("Error en el formato del archivo: Duración [$duración] incorrecta en la fila $fila, hoja $sheet.");
                
                $duraciónID = $db->where("duracion_bloques", $bloques)->get("duracion", 1, "duracion_id")[0]["duracion_id"];
                $horario_tostring .= ($i - 4) . ",$hora,$duraciónID;";
            }
        }
    }

    $row = array_combine($cl, array_intersect_key($row, array_keys($cl)));
    $horario_tostring = substr($horario_tostring, 0, -1);
    if (empty($horario_tostring))
        throw new Exception("Error en el formato del archivo: No se encontró horario en la fila $fila, hoja $sheet.");

    return $horario_tostring;
}

function validar_registro(array $row, int $fila): void
{
    $tiene_horario = false;
    for ($i = 0; $i < HORARIO - 1; $i++)
        if (empty(trim($row[$i])))
            throw new Exception("Error faltan datos en la fila $fila de la hoja");

    for ($i = HORARIO; $i < COLUMNA_MAXIMA; $i++)
        if ($tiene_horario = !empty($row[$i]))
            break;

    if (!$tiene_horario)
        throw new Exception("Error en el formato del archivo: No se encontró horario en la fila $fila.");
}


function renglón_vacío(array $row)
{
    foreach ($row as $columna)
        if (!empty($columna))
            return false;

    return true;
}
