<?php
require_once __DIR__ . '/../../vendor/autoload.php';

use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;

function obtenerConexion()
{
    $conexion = new SqlServerConnection();
    $conexion->conectar();
    return $conexion->conexion;
}

function obtenerStringRandom($longitud = 6): string
{
    $caracteres = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $longitudCaracteres = strlen($caracteres);

    $arr = [];

    for ($i = 0; $i < $longitud; $i++) {
        $arr[] = $caracteres[rand(0, $longitudCaracteres - 1)];
    }

    return implode("", $arr);
}

function obtenerIPActual(): string
{
    if (isset($_SERVER["HTTP_CLIENT_IP"])) {
        return $_SERVER["HTTP_CLIENT_IP"];
    }

    if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) {
        return $_SERVER["HTTP_X_FORWARDED_FOR"];
    }

    if (isset($_SERVER["HTTP_X_FORWARDED"])) {
        return $_SERVER["HTTP_X_FORWARDED"];
    }

    if (isset($_SERVER["HTTP_FORWARDED_FOR"])) {
        return $_SERVER["HTTP_FORWARDED_FOR"];
    }

    if (isset($_SERVER["HTTP_FORWARDED"])) {
        return $_SERVER["HTTP_FORWARDED"];
    }

    return $_SERVER["REMOTE_ADDR"];
}

function validarDatosExcel(string $urlArchivo, array $modeloDatos = null): object
{
    try {
        $spreadsheet = IOFactory::load($urlArchivo);
        $respuesta = (object)[];

        $hoja = $spreadsheet->getActiveSheet();

        $ultimaFila = $hoja->getHighestRow();
        $ultimaColumna = $hoja->getHighestColumn();

        $mapaDatos = (object)[];

        foreach ($modeloDatos as $key => $modelo) {
            for ($columna = 'A'; $columna <= $ultimaColumna; $columna++) {
                if ($hoja->getCell($columna . '1')->getValue() === $modelo->nombre) {
                    $mapaDatos->{$key} = $columna;
                    break;
                }
            }
        }

        foreach ($modeloDatos as $key => $modelo) {
            if ($modelo->obligatorio && !isset($mapaDatos->{$key})) {
                $respuesta->status = 500;
                $respuesta->message = "No se encontró la columna {$modelo->nombre}";
                return $respuesta;
            }
        }

        $datos = [];
        $datosFaltantes = [];

        for ($fila = 2; $fila <= $ultimaFila; $fila++) {
            $datosFila = (object)[];

            foreach ($modeloDatos as $key => $modelo) {
                $tipo = $modelo->tipo;
                $longitud = $modelo->longitud;
                $nulo = $modelo->nulo;
                $obligatorio = $modelo->obligatorio;
                $valor = $hoja->getCell($mapaDatos->{$key} . $fila)->getValue();

                if (!$nulo && empty($valor)) {
                    $datosFaltantes[] = (object)[
                        'fila' => $fila,
                        'columna' => $key,
                    ];
                }

                if ($obligatorio && empty($valor)) {
                    $respuesta->status = 500;
                    $respuesta->message = "El campo {$key} en la fila {$fila} está vacío";
                    return $respuesta;
                }

                switch ($tipo) {
                    case 'int':
                        $valor = intval($valor);
                        break;
                    case 'float':
                        $valor = floatval($valor);
                        break;
                    default:
                        $valor = strval($valor);
                        if (!empty($longitud)) {
                            $valor = substr($valor, 0, $longitud);
                        }
                        break;
                }

                $datosFila->{$key} = $valor;
            }

            $datos[] = $datosFila;
        }

        if (count(array_values($datosFaltantes)) > 0) {
            $respuesta->status = 404;
            $respuesta->message = 'Incompleto';
            $respuesta->data = $datosFaltantes;
            return $respuesta;
        }

        $respuesta->status = 200;
        $respuesta->message = "success";
        $respuesta->data = $datos;

        return $respuesta;
    } catch (PhpSpreadsheetException $e) {
        $respuesta->status = 500;
        $respuesta->message = $e->getMessage();
        return $respuesta;
    } catch (Exception $e) {
        $respuesta->status = 500;
        $respuesta->message = $e->getMessage();
        return $respuesta;
    }
}
