<?php

// Método para reservar el stock directamente en este endpoint
function reserveStock($conn, $productId, $quantity, $liveId) {
    try {
        // ============================================
        // 🚀 UPSERT ATÓMICO - Evita deadlocks
        // ============================================
        $stmt = $conn->prepare("
            INSERT INTO stock_reserved (id_product, live_id, reserved_quantity, updated_at) 
            VALUES (:product_id, :live_id, :quantity, NOW())
            ON DUPLICATE KEY UPDATE 
                reserved_quantity = reserved_quantity + VALUES(reserved_quantity),
                updated_at = NOW()
        ");
        $stmt->bindParam(':product_id', $productId);
        $stmt->bindParam(':live_id', $liveId);
        $stmt->bindParam(':quantity', $quantity);
        $stmt->execute();
        
        return ['success' => true, 'message' => 'Stock reservado correctamente'];
    } catch (Exception $e) {
        error_app('Error al reservar stock: ' . $e->getMessage());
        return ['success' => false, 'message' => 'Error al reservar stock'];
    }
}

function updateCheckoutUrlInDatabase($cartId, $checkoutUrl) {
    try {
        // Instanciar la base de datos y conectar
        $db = new db();
        $conn = $db->connect();
        $conn->exec("SET NAMES 'utf8mb4'");
        if (!$conn) {
            throw new Exception("Failed to connect to database");
        }
        
        // Primero verificar que el cart existe
        $checkStmt = $conn->prepare("SELECT id_user, status FROM cart WHERE id_cart = :id_cart");
        $checkStmt->bindParam(':id_cart', $cartId, PDO::PARAM_INT);
        $checkStmt->execute();
        $cartInfo = $checkStmt->fetch(PDO::FETCH_ASSOC);
        
        if (!$cartInfo) {
            error_app("ERROR: El carrito con ID $cartId no existe en la base de datos");
            return false;
        }
        
 
        // Preparar la sentencia SQL para actualizar la URL de checkout
        $sql = "UPDATE cart SET url_checkout = :url_checkout WHERE id_cart = :id_cart";
        $stmt = $conn->prepare($sql);
        $stmt->bindParam(':url_checkout', $checkoutUrl, PDO::PARAM_STR);
        $stmt->bindParam(':id_cart', $cartId, PDO::PARAM_INT);
        
        // Ejecutar la sentencia
        if ($stmt->execute()) {
            $affectedRows = $stmt->rowCount();
            return true;
        } else {
            error_app("Failed to update checkout URL in the database for cartId: $cartId");
            return false;
        }
    } catch (Exception $e) {
        error_app("Error en updateCheckoutUrlInDatabase: " . $e->getMessage());
        return false;
    }
}



function generateAddToCartAndCheckoutUrl($items, $psid, $accessToken, $cartId, $conn, $cartNote = '') {
    $baseUrl = STORE_URL . '/checkout/';
    
    try {
        // Primero verificar si el carrito ya tiene una URL asignada
        $stmt = $conn->prepare("SELECT url_checkout FROM cart WHERE id_cart = :cart_id");
        $stmt->bindParam(':cart_id', $cartId);
        $stmt->execute();
        $existingCart = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if ($existingCart && !empty($existingCart['url_checkout'])) {
            return $existingCart['url_checkout'];
        }
        
        // Generar hash único pasando la conexión
        $checkoutHash = generateUniqueCheckoutHash($conn);
        $checkoutUrl = $baseUrl . $checkoutHash;
        
        // Actualizar la URL de checkout en la base de datos
        $stmt = $conn->prepare("UPDATE cart SET url_checkout = :url_checkout WHERE id_cart = :id_cart");
        $stmt->bindParam(':url_checkout', $checkoutUrl);
        $stmt->bindParam(':id_cart', $cartId);
        $updated = $stmt->execute();
        
        if (!$updated) {
            error_app("No se pudo actualizar la URL de checkout para el carrito: " . $cartId);
            // Fallback al método antiguo si falla
            return generateOldCheckoutUrl($items, $psid, $accessToken, $cartId, $conn, $cartNote);
        }
        
        // Verificar que se actualizó correctamente
        $stmt = $conn->prepare("SELECT url_checkout FROM cart WHERE id_cart = :cart_id");
        $stmt->bindParam(':cart_id', $cartId);
        $stmt->execute();
        $verifyCart = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if ($verifyCart['url_checkout'] !== $checkoutUrl) {
            error_app("Error: La URL no se guardó correctamente. Esperado: $checkoutUrl, Actual: " . $verifyCart['url_checkout']);
        }
        
        return $checkoutUrl;
        
    } catch (Exception $e) {
        error_app("Error en generateAddToCartAndCheckoutUrl: " . $e->getMessage());
        return generateOldCheckoutUrl($items, $psid, $accessToken, $cartId, $conn, $cartNote);
    }
}

// Función mejorada para generar hash único con verificación en BD
function generateUniqueCheckoutHash($conn = null) {
    $maxAttempts = 10;
    $attempt = 0;
    
    // Si no se pasa conexión, crear una nueva
    if (!$conn) {
        $db = new db();
        $conn = $db->connect();
    }
    
    while ($attempt < $maxAttempts) {
        // Generar hash más largo y único
        // Usar 6 bytes aleatorios (12 caracteres hex) + microsegundos
        $microseconds = substr(microtime(), 2, 6);
        $random = bin2hex(random_bytes(6));
        $hash = strtoupper(substr($random . $microseconds, 0, 10));
        
        // Verificar si ya existe en la base de datos
        $stmt = $conn->prepare("SELECT COUNT(*) as count FROM cart WHERE url_checkout LIKE :pattern");
        $pattern = '%' . $hash . '%';
        $stmt->bindParam(':pattern', $pattern);
        $stmt->execute();
        $result = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if ($result['count'] == 0) {
            // Hash único encontrado
            return $hash;
        }
        
        $attempt++;
        error_app("Hash duplicado generado: $hash, intentando de nuevo (intento $attempt)");
    }
    
    // Si después de 10 intentos no se encuentra un hash único
    $fallbackHash = strtoupper(substr(md5(uniqid(mt_rand(), true)), 0, 10));
    error_app("Usando hash de respaldo después de $maxAttempts intentos: $fallbackHash");
    
    return $fallbackHash;
}

// Función de fallback para mantener compatibilidad
function generateOldCheckoutUrl($items, $psid, $accessToken, $orderId, $conn, $cartNote = '') {
    $baseUrl = STORE_URL . '/checkout/';
    
    $productIds = [];
    $quantities = [];
    $observations = [];
    
    foreach ($items as $item) {
        $productIds[] = $item['id_product'];
        $quantities[] = $item['quantity'];
        $observations[] = isset($item['obs']) ? $item['obs'] : '';
    }
    
    $productIdsString = implode(',', $productIds);
    $quantitiesString = implode(',', $quantities);
    $observationsString = implode('|', $observations);
    
    $url = $baseUrl . '?add-to-cart=' . $productIdsString . '&quantities=' . $quantitiesString;
    $url .= '&psid=' . urlencode($psid) . '&accessToken=' . urlencode($accessToken);
    $url .= '&order_id=' . urlencode($orderId);
    
    if (!empty($observationsString)) {
        $url .= '&product_obs=' . urlencode($observationsString);
    }
    
    if (!empty($cartNote)) {
        $url .= '&cart_note=' . urlencode($cartNote);
    }
    
    return $url;
}


function generateUnifiedCheckoutUrl($items, $userId, $accessToken, $orderIds, $conn) {
    $baseUrl = STORE_URL . '/checkout/';
     $productIds = [];
    $quantities = [];
    $observations = [];

    foreach ($items as $item) {
        $productIds[] = $item['id_product'];
        $quantities[] = $item['quantity'];
        $observations[] = isset($item['obs']) && $item['obs'] !== null ? $item['obs'] : '';
    }

    $productIdsString = implode(',', $productIds);
    $quantitiesString = implode(',', $quantities);
    $observationsString = implode('|', $observations);

    $url = $baseUrl . '?add-to-cart=' . $productIdsString . '&quantities=' . $quantitiesString;

    // Incluir observaciones si al menos una tiene valor
    if (array_filter($observations, function($obs) { return !empty($obs); })) {
        $url .= '&product_obs=' . urlencode($observationsString);
    }

    $url .= '&psid=' . urlencode($userId) . '&accessToken=' . urlencode($accessToken);

    // Incluir order IDs si existen
    if (!empty($orderIds)) {
        $orderIdsString = implode(',', $orderIds);
        $url .= '&order_id=' . urlencode($orderIdsString);

        // Obtener id_cart para cada orderId
        $placeholders = implode(',', array_fill(0, count($orderIds), '?'));
        $stmt = $conn->prepare("SELECT id_cart FROM pending_orders WHERE id IN ($placeholders)");
        $stmt->execute($orderIds);
        $cartIds = $stmt->fetchAll(PDO::FETCH_COLUMN);

    }

    return $url;
}