<?php
/**
 * Weighted Average Cost (WAC) calculation
 * Included by other API files — not called directly
 */

/**
 * Recalculate WAC for a product using the perpetual average formula:
 * New WAC = [(Current Stock * Current WAC) + (New Qty * New Cost)] / (Current Stock + New Qty)
 * 
 * @param PDO $pdo
 * @param int $producto_id
 * @param float|null $nuevaCantidad Quantity added in this entry (optional)
 * @param float|null $nuevoCostoUnitario Cost per unit in this entry (optional)
 */
function recalcular_wac(PDO $pdo, int $producto_id, ?float $nuevaCantidad = null, ?float $nuevoCostoUnitario = null): void {
    // 1. Get current stock from inventario_sucursal
    $stmtInv = $pdo->prepare("SELECT stock_total FROM inventario_sucursal WHERE producto_id = ? AND sucursal_id = 1");
    $stmtInv->execute([$producto_id]);
    $inv = $stmtInv->fetch();
    $stockActual = $inv ? (int)$inv['stock_total'] : 0;

    // 2. Get current WAC from productos_costo_promedio
    $stmtCPP = $pdo->prepare("SELECT costo_promedio_unidad_base FROM productos_costo_promedio WHERE producto_id = ?");
    $stmtCPP->execute([$producto_id]);
    $cppRow = $stmtCPP->fetch();
    $wacActual = $cppRow ? (float)$cppRow['costo_promedio_unidad_base'] : 0.0;

    // 3. Apply formula if a new entry is provided
    if ($nuevaCantidad !== null && $nuevoCostoUnitario !== null) {
        $totalNuevoStock = $stockActual + $nuevaCantidad;
        if ($totalNuevoStock > 0) {
            $nuevoWac = (($stockActual * $wacActual) + ($nuevaCantidad * $nuevoCostoUnitario)) / $totalNuevoStock;
        } else {
            $nuevoWac = $nuevoCostoUnitario;
        }
    } else {
        // Fallback: Re-sync from active inventory purchases
        // We use costo_compra from producto_lugares_compra and stock distribution
        $sql = "SELECT costo_compra, (stock_facturado + stock_no_facturado) as total_stock
                FROM producto_lugares_compra 
                WHERE producto_id = ? AND activo = 1 AND (stock_facturado + stock_no_facturado) > 0";
        $stmt = $pdo->prepare($sql);
        $stmt->execute([$producto_id]);
        $rows = $stmt->fetchAll();

        $sumC = 0;
        $totalS = 0;
        foreach ($rows as $r) {
            $sumC += (float)$r['costo_compra'] * (int)$r['total_stock'];
            $totalS += (int)$r['total_stock'];
        }

        if ($totalS > 0) {
            $nuevoWac = $sumC / $totalS;
        } else {
            // Keep current WAC if no active lots with stock exist
            $nuevoWac = ($wacActual > 0) ? $wacActual : (float)$nuevoCostoUnitario;
        }
    }

    $wacU = max(0, (float)$nuevoWac);
    $totalStock = $stockActual + ($nuevaCantidad ?? 0);
    $valorTotal = $totalStock * $wacU;

    // 4. Update CPP table
    $stmtUpdate = $pdo->prepare(
        "INSERT INTO productos_costo_promedio (producto_id, costo_promedio_unidad_base, cantidad_total_unidades, valor_total_inventario) 
         VALUES (?, ?, ?, ?) 
         ON DUPLICATE KEY UPDATE 
            costo_promedio_unidad_base = VALUES(costo_promedio_unidad_base),
            cantidad_total_unidades = VALUES(cantidad_total_unidades),
            valor_total_inventario = VALUES(valor_total_inventario)"
    );
    $stmtUpdate->execute([$producto_id, $wacU, $totalStock, $valorTotal]);

    // 5. Update "General" location (only if we have meaningful cost)
    update_general_location($pdo, $producto_id, $wacU);
}

/**
 * Helper to update the virtual 'General' location which shows the system average
 */
function update_general_location(PDO $pdo, int $producto_id, float $wacU): void {
    require_once __DIR__ . '/../../includes/helpers.php';
    $generalId = get_general_id($pdo);

    // Count physical locations with stock or that are active
    $stmt = $pdo->prepare("SELECT COUNT(*) FROM producto_lugares_compra WHERE producto_id = ? AND lugar_compra_id != ? AND activo = 1");
    $stmt->execute([$producto_id, $generalId]);
    $count = $stmt->fetchColumn();

    // Only keep 'General' active if there are multiple physical locations OR if it's the only reference
    if ($count >= 1) { 
        $stmtCheck = $pdo->prepare("SELECT id FROM producto_lugares_compra WHERE producto_id = ? AND lugar_compra_id = ?");
        $stmtCheck->execute([$producto_id, $generalId]);
        if ($stmtCheck->fetch()) {
            $pdo->prepare("UPDATE producto_lugares_compra SET costo_compra = ?, activo = 1 WHERE producto_id = ? AND lugar_compra_id = ?")
                ->execute([$wacU, $producto_id, $generalId]);
        } else {
            $pdo->prepare("INSERT INTO producto_lugares_compra (producto_id, lugar_compra_id, costo_compra, activo) VALUES (?, ?, ?, 1)")
                ->execute([$producto_id, $generalId, $wacU]);
        }
    } else {
        // If 0 or 1 physical location, "General" is redundant or inactive
        $pdo->prepare("UPDATE producto_lugares_compra SET activo = 0 WHERE producto_id = ? AND lugar_compra_id = ?")
            ->execute([$producto_id, $generalId]);
    }
}
