<?php
// === Fragmento para integrar en api.php bajo action = 'create_sale' ===
// Recomendado: ejecutar TODO dentro de transacción para atomicidad.

// $items = array of { product_id, qty, unit_price, hose_id (optional) }
// $payment_method provided, etc.
// $pdo : PDO instance available from init.php

$strictRequireTank = false; // true = bloquear la venta si falta tanque; false = permitir venta y regresar warning

try {
    // Iniciar transacción (si no estás ya en una)
    if (!$pdo->inTransaction()) $pdo->beginTransaction();

    // 1) Insertar la venta (ejemplo)
    $stmtSale = $pdo->prepare("INSERT INTO sales (sale_code, user_id, total, payment_method, created_at) VALUES (?, ?, ?, ?, NOW())");
    // Genera sale_code y calcula total
    $sale_code = 'S' . date('YmdHis') . rand(100,999);
    $user_id = $_SESSION['user_id'] ?? null;
    $total = array_reduce($items, function($s, $it){ return $s + ($it['qty'] * $it['unit_price']); }, 0.0);
    $stmtSale->execute([$sale_code, $user_id, $total, $payment_method]);
    $saleId = $pdo->lastInsertId();

    // 2) Insertar sale_items
    $stmtInsertItem = $pdo->prepare("INSERT INTO sale_items (sale_id, product_id, hose_id, qty, unit_price, total) VALUES (?, ?, ?, ?, ?, ?)");
    foreach ($items as $it) {
        $qty = (float)$it['qty'];
        $unit_price = (float)$it['unit_price'];
        $lineTotal = $qty * $unit_price;
        $hose_id = isset($it['hose_id']) ? ($it['hose_id'] === '' ? null : (int)$it['hose_id']) : null;
        $stmtInsertItem->execute([$saleId, (int)$it['product_id'], $hose_id, $qty, $unit_price, $lineTotal]);
    }

    // 3) Actualizar inventario de tanques por cada item
    // Preparar statements
    // - Si mapéas por hose -> tank en el futuro, reemplaza la consulta de búsqueda de tanque por SELECT tank_id FROM hoses WHERE id = ? LIMIT 1;
    // - Actualmente, buscamos un tanque por producto_id (primer tanque encontrado). Si hay varios, se puede cambiar la estrategia.
    $selectTankByProductForUpdate = $pdo->prepare("SELECT id, vendido, inventario_inicial FROM tanques WHERE producto_id = ? LIMIT 1 FOR UPDATE");
    $updateTank = $pdo->prepare("UPDATE tanques SET vendido = ?, disponible = ?, updated_at = NOW() WHERE id = ?");

    $tankWarnings = [];
    foreach ($items as $it) {
        $productId = (int)$it['product_id'];
        $qty = (float)$it['qty'];

        // Si tienes hose_id y planeas mapear hoses->tanques, intenta buscar por hose primero:
        if (!empty($it['hose_id'])) {
            // Intento de mapear hose->tank si existe la columna tank_id en hoses
            $hoseRow = null;
            $stmtH = $pdo->prepare("SELECT * FROM hoses WHERE id = ? LIMIT 1");
            $stmtH->execute([(int)$it['hose_id']]);
            $hoseRow = $stmtH->fetch(PDO::FETCH_ASSOC);
            if ($hoseRow) {
                if (isset($hoseRow['tank_id']) && $hoseRow['tank_id']) {
                    // buscar tanque por id
                    $stmtT = $pdo->prepare("SELECT id, vendido, inventario_inicial FROM tanques WHERE id = ? FOR UPDATE");
                    $stmtT->execute([(int)$hoseRow['tank_id']]);
                    $tank = $stmtT->fetch(PDO::FETCH_ASSOC);
                    if ($tank) {
                        $newVend = (float)$tank['vendido'] + $qty;
                        $newDisp = (float)$tank['inventario_inicial'] - $newVend;
                        $updateTank->execute([$newVend, $newDisp, $tank['id']]);
                        continue; // siguiente item
                    }
                    // si tank_id no resolvió, caemos a búsqueda por producto
                }
                // si hoses tiene product_id y coincide, intentamos buscar tanques por producto (fallback)
                if (isset($hoseRow['product_id']) && (int)$hoseRow['product_id'] === $productId) {
                    // fallback: buscar tanque por producto
                    $selectTankByProductForUpdate->execute([$productId]);
                    $tank = $selectTankByProductForUpdate->fetch(PDO::FETCH_ASSOC);
                    if ($tank) {
                        $newVend = (float)$tank['vendido'] + $qty;
                        $newDisp = (float)$tank['inventario_inicial'] - $newVend;
                        $updateTank->execute([$newVend, $newDisp, $tank['id']]);
                        continue;
                    }
                }
            }
        }

        // Búsqueda normal por producto_id
        $selectTankByProductForUpdate->execute([$productId]);
        $tank = $selectTankByProductForUpdate->fetch(PDO::FETCH_ASSOC);
        if ($tank) {
            $newVend = (float)$tank['vendido'] + $qty;
            $newDisp = (float)$tank['inventario_inicial'] - $newVend;
            $updateTank->execute([$newVend, $newDisp, $tank['id']]);
        } else {
            // No se encontró tanque para este producto
            $msg = "No se encontró tanque para producto_id={$productId}";
            if ($strictRequireTank) {
                throw new Exception($msg);
            } else {
                $tankWarnings[] = $msg;
                // continuar sin fallar la venta
            }
        }
    }

    // 4) Confirmar (commit) la transacción
    if ($pdo->inTransaction()) $pdo->commit();

    // Responder OK incluyendo warnings si los hay
    $response = ['ok' => 1, 'sale_id' => $saleId, 'sale_code' => $sale_code, 'total' => $total];
    if (!empty($tankWarnings)) $response['tank_warnings'] = $tankWarnings;
    echo json_encode($response);
} catch (Exception $e) {
    if ($pdo->inTransaction()) $pdo->rollBack();
    // Manejo de error: responder con detalle (pero no exponer info sensible)
    echo json_encode(['ok' => 0, 'msg' => 'Error registrando venta: ' . $e->getMessage()]);
}