<?php
date_default_timezone_set('America/Bogota');

// Habilitar la visualización de errores temporalmente
ini_set('display_errors', 1);
error_reporting(E_ALL);

// Definir la clave de la API como una constante
define('API_KEY', '6QW5T3HTWPMREMYZQ8TW8FH3JY45YGGZ');

// Función para establecer la conexión a la base de datos
function conectarBD($servidor, $usuario, $contrasena, $nombreBD)
{
    $conn = new mysqli($servidor, $usuario, $contrasena, $nombreBD);
    if ($conn->connect_error) {
        die("Conexión fallida: " . $conn->connect_error);
    }
    return $conn;
}

// Función para ejecutar una consulta SQL y devolver el resultado
function ejecutarConsulta($conn, $sql)
{
    $result = $conn->query($sql);
    if (!$result) {
        echo "Error en la consulta: " . $conn->error;
    }
    return $result;
}

// Función para realizar una petición cURL y devolver la respuesta
function realizarPeticionCurl($url)
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($ch);
    if (curl_errno($ch)) {
        echo 'Error en cURL: ' . curl_error($ch);
    }
    curl_close($ch);
    return json_decode($response, true);
}

// Función para obtener productos en lotes
function getProductsInBatches($apiUrl, $apiKey, $limit, $offset) {
    $url = "$apiUrl/products?display=full&limit=$limit&start=$offset&output_format=JSON&ws_key=$apiKey";
    return realizarPeticionCurl($url);
}

// Función para procesar en paralelo
function realizarPeticionesParalelas($urls) {
    $multiCurl = array();
    $mh = curl_multi_init();
    foreach ($urls as $i => $url) {
        $multiCurl[$i] = curl_init();
        curl_setopt($multiCurl[$i], CURLOPT_URL, $url);
        curl_setopt($multiCurl[$i], CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($multiCurl[$i], CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
        curl_setopt($multiCurl[$i], CURLOPT_USERPWD, API_KEY . ':');
        curl_multi_add_handle($mh, $multiCurl[$i]);
    }

    $running = null;
    do {
        curl_multi_exec($mh, $running);
    } while ($running);

    $responses = [];
    foreach ($multiCurl as $i => $ch) {
        $responses[] = curl_multi_getcontent($ch);
        curl_multi_remove_handle($mh, $ch);
    }

    curl_multi_close($mh);
    return $responses;
}

// Función para insertar productos en lotes
function insertarProductosEnLotes($productos, $conn) {
    $sql = "INSERT INTO boton_promo_productos (product_id, reference, price, available_for_order, visibility, meta_title, name, description, description_short, id_default_image) VALUES ";
    $values = [];
    foreach ($productos as $producto) {
        $productId = $producto['id'];
        $reference = $producto['reference'];
        $price = $producto['price'];
        $availableForOrder = $producto['available_for_order'];
        $visibility = $producto['visibility'];
        $metaTitle = $producto['meta_title'];
        $name = $producto['name'];
        $description = $conn->real_escape_string($producto['description']);
        $descriptionShort = $conn->real_escape_string($producto['description_short']);
        $id_default_image = $producto['id_default_image'];
        $values[] = "('$productId', '$reference', '$price', '$availableForOrder', '$visibility', '$metaTitle', '$name', '$description', '$descriptionShort', '$id_default_image')";
    }
    $sql .= implode(',', $values);
    $sql .= " ON DUPLICATE KEY UPDATE reference=VALUES(reference), price=VALUES(price), available_for_order=VALUES(available_for_order), visibility=VALUES(visibility), meta_title=VALUES(meta_title), name=VALUES(name), description=VALUES(description), description_short=VALUES(description_short), id_default_image=VALUES(id_default_image)";
    $conn->query($sql);
}

// Función para procesar asociaciones de un producto
function procesarAsociaciones($conn, $productId, $associations)
{
    // Categorías
    if (isset($associations['categories'])) {
        foreach ($associations['categories'] as $category) {
            $stmt = $conn->prepare("INSERT INTO boton_aux_categorias (product_id, categoria_id) VALUES (?, ?)");
            $stmt->bind_param("ii", $productId, $category['id']);
            $stmt->execute();
        }
    }

    // Imágenes
    if (isset($associations['images'])) {
        foreach ($associations['images'] as $image) {
            $stmt = $conn->prepare("INSERT INTO boton_aux_imagenes_principal (product_id, imagen_id) VALUES (?, ?)");
            $stmt->bind_param("ii", $productId, $image['id']);
            $stmt->execute();
        }
    }

    // Combinaciones
    if (isset($associations['combinations'])) {
        foreach ($associations['combinations'] as $combination) {
            $stmt = $conn->prepare("INSERT INTO boton_aux_combinaciones (product_id, combination_id) VALUES (?, ?)");
            $stmt->bind_param("ii", $productId, $combination['id']);
            $stmt->execute();
        }
    }

    // Opciones de producto
    if (isset($associations['product_option_values'])) {
        foreach ($associations['product_option_values'] as $option) {
            $stmt = $conn->prepare("INSERT INTO boton_aux_option_values (product_id, option_id) VALUES (?, ?)");
            $stmt->bind_param("ii", $productId, $option['id']);
            $stmt->execute();
        }
    }

    // Características del producto
    if (isset($associations['product_features'])) {
        foreach ($associations['product_features'] as $feature) {
            $stmt = $conn->prepare("INSERT INTO boton_aux_product_features (product_id, feature_id, feature_value_id) VALUES (?, ?, ?)");
            $stmt->bind_param("iii", $productId, $feature['id'], $feature['id_feature_value']);
            $stmt->execute();
        }
    }

    // Disponibilidad de stock
    if (isset($associations['stock_availables'])) {
        foreach ($associations['stock_availables'] as $stock) {
            $stmt = $conn->prepare("INSERT INTO boton_aux_stock_available (product_id, stock_id, id_product_attribute) VALUES (?, ?, ?)");
            $stmt->bind_param("iii", $productId, $stock['id'], $stock['id_product_attribute']);
            $stmt->execute();
        }
    }
}

// Conexión a la base de datos
$conn = conectarBD("localhost", "ndconsulta", "Nitro2021", "db_inventarios_compranet");

// Truncar tablas auxiliares
$tablasAux = [
    'boton_aux_categorias', 'boton_aux_combinaciones', 'boton_aux_id_productos',
    'boton_aux_option_values', 'boton_aux_imagenes_principal', 'boton_aux_product_features',
    'boton_aux_stock_available','boton_promo_productos'
];
foreach ($tablasAux as $tabla) {
    ejecutarConsulta($conn, "TRUNCATE TABLE $tabla;");
}

// Configuración de la API
$apiUrl = "https://esferos.com/site/api/";
$limit = 100; // Número de productos por lote
$offset = 0;
$totalProducts = realizarPeticionCurl("$apiUrl/products?output_format=JSON&ws_key=" . API_KEY . "&limit=1")['products'][0]['id'];
$pages = ceil($totalProducts / $limit);

// Procesar productos en lotes
while ($offset < $totalProducts) {
    $productList = getProductsInBatches($apiUrl, API_KEY, $limit, $offset);
    if (!empty($productList['products'])) {
        insertarProductosEnLotes($productList['products'], $conn);
    }
    $offset += $limit;
}

// Procesar detalles de productos en paralelo
$productIds = [];
$result = ejecutarConsulta($conn, "SELECT product_id FROM boton_aux_id_productos");
while ($row = $result->fetch_assoc()) {
    $productIds[] = $row['product_id'];
}
$productUrls = array_map(function($id) use ($apiUrl) {
    return "$apiUrl/products/$id?output_format=JSON&ws_key=" . API_KEY;
}, $productIds);
$productDetailsResponses = realizarPeticionesParalelas($productUrls);

// Procesar cada respuesta
foreach ($productDetailsResponses as $response) {
    $productDetails = json_decode($response, true);
    if (isset($productDetails['product'])) {
        $product = $productDetails['product'];
        // Insertar el producto en la base de datos
        insertarProductosEnLotes([$product], $conn);
        // Procesar asociaciones
        if (isset($product['associations'])) {
            procesarAsociaciones($conn, $product['id'], $product['associations']);
        }
    }
}

// Procesar descuentos específicos en paralelo
$specificPricesList = realizarPeticionCurl("$apiUrl/specific_prices/?output_format=JSON&ws_key=" . API_KEY);
if (isset($specificPricesList['specific_prices'])) {
    $specificPriceUrls = array_map(function($specificPrice) use ($apiUrl) {
        return "$apiUrl/specific_prices/{$specificPrice['id']}?output_format=JSON&ws_key=" . API_KEY;
    }, $specificPricesList['specific_prices']);
    $specificPriceResponses = realizarPeticionesParalelas($specificPriceUrls);

    foreach ($specificPriceResponses as $response) {
        $specificPriceDetails = json_decode($response, true);
        if (isset($specificPriceDetails['specific_price'])) {
            $specificPrice = $specificPriceDetails['specific_price'];
            // Insertar datos del precio específico en la base de datos
            $stmt = $conn->prepare("INSERT INTO boton_lista_descuentos (id_specific_price, id_product, id_product_attribute, price, from_quantity, reduction, reduction_type, from_date, to_date) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
            $stmt->bind_param("iiissssss", $specificPrice['id'], $specificPrice['id_product'], $specificPrice['id_product_attribute'], $specificPrice['price'], $specificPrice['from_quantity'], $specificPrice['reduction'], $specificPrice['reduction_type'], $specificPrice['from'], $specificPrice['to']);
            $stmt->execute();
        }
    }
}

// Insertar categorías, características, opciones y stock únicos en sus respectivas tablas
$uniqueTables = [
    'boton_lista_categorias' => 'categoria_id',
    'boton_lista_nombre_caracteristicas' => 'feature_id',
    'boton_lista_caracteristicas' => 'feature_value_id',
    'boton_lista_opciones' => 'option_id',
    'boton_lista_combinaciones' => ['product_id', 'combination_id'],
    'boton_lista_stock' => ['product_id', 'id_product_attribute', 'stock_id']
];
foreach ($uniqueTables as $table => $columns) {
    $columns = (array)$columns;
    $selectColumns = implode(',', $columns);
    $insertColumns = implode(',', array_map(function($col) { return "id_$col"; }, $columns));
    $query = "INSERT IGNORE INTO $table ($insertColumns) SELECT $selectColumns FROM boton_aux_$table GROUP BY $selectColumns ORDER BY $selectColumns";
    ejecutarConsulta($conn, $query);
}

// Actualizar nombres y valores en las tablas correspondientes
$updateQueries = [
    'boton_lista_categorias' => ['id_categoria', 'nombre_categoria', 'categories'],
    'boton_lista_nombre_caracteristicas' => ['id_caracteristica', 'nombre_caracteristica', 'product_features'],
    'boton_lista_caracteristicas' => ['id_valor_caracteristica', 'nombre_caracteristica', 'product_feature_values'],
    'boton_lista_opciones' => ['id_opcion', 'valor', 'product_option_values']
];
foreach ($updateQueries as $table => [$idColumn, $nameColumn, $endpoint]) {
    $rows = ejecutarConsulta($conn, "SELECT $idColumn FROM $table WHERE $nameColumn IS NULL");
    while ($row = $rows->fetch_assoc()) {
        $id = $row[$idColumn];
        $url = "$apiUrl/$endpoint/$id?output_format=JSON&ws_key=" . API_KEY;
        $details = realizarPeticionCurl($url);
        if (isset($details[$endpoint])) {
            $name = $conn->real_escape_string($details[$endpoint]['name']);
            $updateQuery = "UPDATE $table SET $nameColumn = ? WHERE $idColumn = ?";
            $stmt = $conn->prepare($updateQuery);
            $stmt->bind_param("si", $name, $id);
            $stmt->execute();
        }
    }
}

// Actualizar stock en la tabla boton_lista_stock
$stocks = ejecutarConsulta($conn, "SELECT stock_id FROM boton_lista_stock ORDER BY product_id");
while ($row = $stocks->fetch_assoc()) {
    $id_stockextractor = $row['stock_id'];
    $linkstock = "$apiUrl/stock_availables/$id_stockextractor?output_format=JSON&ws_key=" . API_KEY;
    $stockdetails = realizarPeticionCurl($linkstock);
    $valorstock = $stockdetails['stock_available']['quantity'] ?? 0;
    $updateQuery = "UPDATE boton_lista_stock SET stock = ? WHERE stock_id = ?";
    $stmt = $conn->prepare($updateQuery);
    $stmt->bind_param("si", $valorstock, $id_stockextractor);
    $stmt->execute();
}

// Llamar al procedimiento almacenado actualizar_pvp
ejecutarConsulta($conn, "CALL actualizar_boton_promo;");

// Cerrar la conexión a la base de datos
mysqli_close($conn);
echo "Proceso terminado.";
?>

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <title>Proceso terminado</title>
</head>
<body>
    <p>Proceso terminado. Mostrando barra de progreso...</p>
    <iframe src="https://sistema.compranet.com.co/conexiones/conexionwp/inventario_api.php?&id_proveedor=4" style="width:100%; height:500px; border:none;"></iframe>
</body>
</html>
