<?php

declare(strict_types=1);

// --------------------------------------------------
// 1. Autoload
// --------------------------------------------------
require __DIR__ . '/../../vendor/autoload.php';

use PhpOffice\PhpSpreadsheet\IOFactory;

// --------------------------------------------------
// 2. Lockfile (evita solapamientos)
// --------------------------------------------------
$lockFile = sys_get_temp_dir() . '/invepromos.lock';
$fp = fopen($lockFile, 'c');
if (!$fp || !flock($fp, LOCK_EX | LOCK_NB)) {
    exit; // ya hay otra instancia en ejecución
}

// --------------------------------------------------
// 3. Conexión a MySQL
// --------------------------------------------------
$mysqli = new mysqli('localhost', 'ndconsulta', 'Nitro2021', 'db_inventarios_compranet');
if ($mysqli->connect_error) {
    die("Conexión fallida: " . $mysqli->connect_error);
}
$mysqli->set_charset('utf8');

// --------------------------------------------------
// 4. Asegurar columnas extra
// --------------------------------------------------
function ensureColumnExists(mysqli $db, string $table, string $column, string $definition): void
{
    $res = $db->query("SHOW COLUMNS FROM `$table` LIKE '$column'");
    if ($res === false) {
        throw new RuntimeException("SHOW COLUMNS falló: " . $db->error);
    }
    if ($res->num_rows === 0) {
        if (!$db->query("ALTER TABLE `$table` ADD `$column` $definition")) {
            throw new RuntimeException("ALTER TABLE ADD COLUMN falló: " . $db->error);
        }
    }
}

ensureColumnExists($mysqli, 'temporalpreciospromos', 'import_date',      'DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP');
ensureColumnExists($mysqli, 'promos_productos',   'activo',           'TINYINT(1) NOT NULL DEFAULT 1');
ensureColumnExists($mysqli, 'promos_variaciones', 'activo',           'TINYINT(1) NOT NULL DEFAULT 1');

// --------------------------------------------------
// 5. Utilidades cURL / JSON
// --------------------------------------------------
function downloadFile(string $url, string $dest): void
{
    $ch = curl_init($url);
    $fp = fopen($dest, 'wb');
    curl_setopt_array($ch, [
        CURLOPT_FILE           => $fp,
        CURLOPT_TIMEOUT        => 120,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_FAILONERROR    => true,
    ]);
    if (!curl_exec($ch)) {
        throw new RuntimeException("cURL error: " . curl_error($ch));
    }
    curl_close($ch);
    fclose($fp);
    if (!file_exists($dest) || filesize($dest) === 0) {
        throw new RuntimeException("Error al descargar o fichero vacío: $dest");
    }
}

function getCurlResponse(string $url): array
{
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 30,
        CURLOPT_FOLLOWLOCATION => true,
    ]);
    $resp = curl_exec($ch);
    if ($resp === false) {
        throw new RuntimeException("cURL error: " . curl_error($ch));
    }
    curl_close($ch);
    $data = json_decode($resp, true);
    if (json_last_error() !== JSON_ERROR_NONE) {
        throw new RuntimeException("JSON inválido: " . json_last_error_msg());
    }
    return $data;
}

function customUrlEncode(string $s): string
{
    return str_replace(' ', '%20', $s);
}

// --------------------------------------------------
// 6. Upserts productos / variaciones
// --------------------------------------------------
function saveProductInfo(array $p, mysqli $db): void
{
    static $stmt;
    if (!$stmt) {
        $stmt = $db->prepare(
            <<<'SQL'
INSERT INTO promos_productos
  (id, referencia, resumen, idCategoria, descripcionProducto,
   precio1, precio2, precio3, precio4, precio5,
   descripcionPrecio1, descripcionPrecio2, descripcionPrecio3,
   descripcionPrecio4, descripcionPrecio5, activo)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1)
ON DUPLICATE KEY UPDATE
  referencia=VALUES(referencia), resumen=VALUES(resumen),
  idCategoria=VALUES(idCategoria), descripcionProducto=VALUES(descripcionProducto),
  precio1=VALUES(precio1), precio2=VALUES(precio2),
  precio3=VALUES(precio3), precio4=VALUES(precio4),
  precio5=VALUES(precio5),
  descripcionPrecio1=VALUES(descripcionPrecio1),
  descripcionPrecio2=VALUES(descripcionPrecio2),
  descripcionPrecio3=VALUES(descripcionPrecio3),
  descripcionPrecio4=VALUES(descripcionPrecio4),
  descripcionPrecio5=VALUES(descripcionPrecio5),
  activo=1
SQL
        );
    }
    $stmt->bind_param(
        "issisiiiiisssss",
        $p['id'],
        $p['referencia'],
        $p['resumen'],
        $p['idCategoria'],
        $p['descripcionProducto'],
        $p['precio1'],
        $p['precio2'],
        $p['precio3'],
        $p['precio4'],
        $p['precio5'],
        $p['descripcionPrecio1'],
        $p['descripcionPrecio2'],
        $p['descripcionPrecio3'],
        $p['descripcionPrecio4'],
        $p['descripcionPrecio5']
    );
    $stmt->execute();
}

function saveStockInfo(array $vs, int $productId, mysqli $db): void
{
    static $stmt;
    if (!$stmt) {
        $stmt = $db->prepare(
            <<<'SQL'
INSERT INTO promos_variaciones
  (id, id_producto, referencia, color, bodegaLocal,
   bodegaZonaFranca, totalDisponible, llegadaBodegaLocal,
   cantidadTransito, estadoOrden, activo)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1)
ON DUPLICATE KEY UPDATE
  referencia=VALUES(referencia), color=VALUES(color),
  bodegaLocal=VALUES(bodegaLocal), bodegaZonaFranca=VALUES(bodegaZonaFranca),
  totalDisponible=VALUES(totalDisponible),
  llegadaBodegaLocal=VALUES(llegadaBodegaLocal),
  cantidadTransito=VALUES(cantidadTransito),
  estadoOrden=VALUES(estadoOrden),
  activo=1
SQL
        );
    }
    foreach ($vs as $v) {
        $clean = ltrim($v['color'], '.');
        $stmt->bind_param(
            "iissiiiiss",
            $v['id'],
            $productId,
            $v['referencia'],
            $clean,
            $v['bodegaLocal'],
            $v['bodegaZonaFranca'],
            $v['totalDisponible'],
            $v['llegadaBodegaLocal'],
            $v['cantidadTransito'],
            $v['estadoOrden']
        );
        $stmt->execute();
    }
}

// --------------------------------------------------
// 7. Función: importar precios con barra de progreso
// --------------------------------------------------
function importarPrecios(mysqli $db): void
{
    // URL que genera dinámicamente un .xls
    $url = 'http://catalogospromocionales.com/distribuidores/referenciasexcel';
    $xls = __DIR__ . '/referencias.xls';

    // 1) descargar
    downloadFile($url, $xls);

    // 2) cargar con PhpSpreadsheet
    $spreadsheet = IOFactory::load($xls);
    $sheet       = $spreadsheet->getActiveSheet();
    $rows        = $sheet->toArray(null, true, true, true);
    $spreadsheet->disconnectWorksheets();
    unset($spreadsheet);

    // 3) quitar encabezado
    array_shift($rows);
    $total = count($rows);
    if ($total === 0) {
        throw new RuntimeException("El Excel no contiene datos.");
    }

    // 4) limpiar la tabla temporal
    $db->query('TRUNCATE TABLE temporalpreciospromos');

    // 5) preparar INSERT con 16 placeholders + NOW()
    $sql = <<<'SQL'
INSERT INTO temporalpreciospromos
  (Referencia, NombreProducto, Caracteristicas,
   DescPrecio1, Precio1, DescPrecio2, Precio2,
   DescPrecio3, Precio3, DescPrecio4, Precio4,
   DescPrecio5, Precio5, textoprecio, descuento, maximo, import_date)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())
SQL;
    $stmt = $db->prepare($sql);
    if (!$stmt) {
        throw new RuntimeException("Prepare falló: " . $db->error);
    }

    // 6) iterar y bind+execute
    $i = 0;
    foreach ($rows as $r) {
        $i++;
        $pct = intval($i * 100 / $total);
        echo "<script>callprogress($pct)</script>";
        flush();

        // columnas A–M
        $Referencia      = $r['A'];
        $NombreProducto  = $r['B'];
        $Caracteristicas = $r['C'];
        $D1 = $r['D'];
        $P1 = $r['E'];
        $D2 = $r['F'];
        $P2 = $r['G'];
        $D3 = $r['H'];
        $P3 = $r['I'];
        $D4 = $r['J'];
        $P4 = $r['K'];
        $D5 = $r['L'];
        $P5 = $r['M'];

        // normalizar textos y precios
        $Desc1 = $D1 === null ? 'Precio de Lista:' : substr((string)$D1, 0, 255);
        $Desc2 = $D2 === null ? ''                  : substr((string)$D2, 0, 255);
        $Desc3 = $D3 === null ? ''                  : substr((string)$D3, 0, 255);
        $Desc4 = $D4 === null ? ''                  : substr((string)$D4, 0, 255);
        $Desc5 = $D5 === null ? ''                  : substr((string)$D5, 0, 255);

        $Pr1 = ($P1 !== null && $P1 !== '-1.00') ? str_replace('.00', '', (string)$P1) : '0.00';
        $Pr2 = ($P2 !== null && $P2 !== '-1.00') ? str_replace('.00', '', (string)$P2) : '0.00';
        $Pr3 = ($P3 !== null && $P3 !== '-1.00') ? str_replace('.00', '', (string)$P3) : '0.00';
        $Pr4 = ($P4 !== null && $P4 !== '-1.00') ? str_replace('.00', '', (string)$P4) : '0.00';
        $Pr5 = ($P5 !== null && $P5 !== '-1.00') ? str_replace('.00', '', (string)$P5) : '0.00';

        $desc = strtolower(trim((string)$D1)) === 'oferta' ? 0.15 : 0.0;
        $max  = max($Pr1, $Pr2, $Pr3, $Pr4, $Pr5);

        $sep = "\r\n";
        $textoprecio = "$Desc1 $Pr1$sep"
            . "$Desc2 $Pr2$sep"
            . "$Desc3 $Pr3$sep"
            . "$Desc4 $Pr4$sep"
            . "$Desc5 $Pr5";

        $stmt->bind_param(
            'ssssssssssssssdd',
            $Referencia,
            $NombreProducto,
            $Caracteristicas,
            $Desc1,
            $Pr1,
            $Desc2,
            $Pr2,
            $Desc3,
            $Pr3,
            $Desc4,
            $Pr4,
            $Desc5,
            $Pr5,
            $textoprecio,
            $desc,
            $max
        );
        $stmt->execute();
    }
    $stmt->close();

    // 7) aplicar precios finales
    $db->query('CALL actualizar_promos()');
    echo "<script>callprogress(100)</script>";
}

// --------------------------------------------------
// 8. Sincronizar productos y stock
// --------------------------------------------------
function sincronizarProductosYStock(mysqli $db): void
{
    // marcar todo como inactivo
    $db->query('UPDATE promos_productos   SET activo=0');
    $db->query('UPDATE promos_variaciones SET activo=0');

    $base = 'https://api.cataprom.com/rest';
    $cats = getCurlResponse("$base/categorias");
    echo "<script>callprogress(105)</script>";
    flush();

    foreach ($cats['resultado'] as $cat) {
        $prods = getCurlResponse("$base/categorias/{$cat['id']}/productos");
        foreach ($prods['resultado'] as $p) {
            saveProductInfo($p, $db);
        }
    }
    echo "<script>callprogress(110)</script>";
    flush();

    $res = $db->query('SELECT id, referencia FROM promos_productos WHERE activo=1');
    while ($f = $res->fetch_assoc()) {
        $stk = getCurlResponse("$base/stock/" . customUrlEncode($f['referencia']));
        if (!$stk['hayError']) {
            saveStockInfo($stk['resultado'], (int)$f['id'], $db);
        }
    }

    // eliminar inactivos
    $db->query('DELETE FROM promos_productos   WHERE activo=0');
    $db->query('DELETE FROM promos_variaciones WHERE activo=0');

    echo "<script>callprogress(120)</script>";
    flush();
}

// --------------------------------------------------
// 9. HTML + ejecución
// --------------------------------------------------
?>
<!DOCTYPE html>
<html lang="es">

<head>
    <meta charset="UTF-8">
    <title>Importación Promos</title>
    <style>
        #contenedor {
            width: 100%;
            background: #eee;
        }

        #barra {
            width: 0;
            background: green;
            color: #fff;
            text-align: center;
        }
    </style>
</head>

<body>
    <div id="contenedor">
        <div id="barra">0%</div>
    </div>
    <script>
        function callprogress(p) {
            var b = document.getElementById('barra');
            b.style.width = Math.min(p, 120) + '%';
            b.textContent = Math.min(p, 120) + '%';
        }
    </script>
    <?php
    try {
        importarPrecios($mysqli);
        sincronizarProductosYStock($mysqli);
        echo "<p>Proceso completado.</p>";
    } catch (Throwable $e) {
        echo "<p style='color:red;'>ERROR: " . htmlspecialchars($e->getMessage()) . "</p>";
    }
    $mysqli->close();
    ?>
</body>

</html>