<?php
header('Content-Type: application/json; charset=utf-8');
require_once __DIR__ . '/db.php';

try {
    $pdo = getConnection();
    
    $data = json_decode(file_get_contents('php://input'), true);
    
    $productoId = isset($data['producto_id']) ? (int)$data['producto_id'] : 0;
    $lugarCompraId = isset($data['lugar_compra_id']) ? (int)$data['lugar_compra_id'] : 0;
    $costoCompra = isset($data['costo_compra']) ? (float)$data['costo_compra'] : 0.0;
    $cantidad = isset($data['cantidad']) ? (int)$data['cantidad'] : 0;
    $presentacionId = isset($data['presentacion_id']) ? (int)$data['presentacion_id'] : 1;
    $fechaCompra = isset($data['fecha_compra']) && !empty($data['fecha_compra']) ? $data['fecha_compra'] : date('Y-m-d');
    $fechaVencimiento = isset($data['fecha_vencimiento']) && !empty($data['fecha_vencimiento']) ? $data['fecha_vencimiento'] : null;
    $conFactura = isset($data['con_factura']) ? (int)$data['con_factura'] : 1;

    if (!$productoId) {
        throw new Exception("ID de producto requerido");
    }
    if (!$lugarCompraId) {
        throw new Exception("Lugar de compra requerido");
    }
    if ($costoCompra <= 0) {
        throw new Exception("El costo de compra debe ser mayor a 0");
    }
    if ($cantidad <= 0) {
        throw new Exception("La cantidad debe ser mayor a 0");
    }

    $pdo->beginTransaction();

    // 1. Obtener el factor de conversión para la presentación elegida
    $stmtFactor = $pdo->prepare("SELECT factor_conversion FROM producto_presentaciones 
                                 WHERE producto_id = :pId AND presentacion_id = :presId AND activo = 1 LIMIT 1");
    $stmtFactor->execute([':pId' => $productoId, ':presId' => $presentacionId]);
    $factorConversion = $stmtFactor->fetchColumn();
    if ($factorConversion === false) {
        $factorConversion = isset($data['factor_conversion']) ? (int)$data['factor_conversion'] : 1; // Fallback to frontend factor
    } else {
        $factorConversion = (int)$factorConversion;
    }

    $nuevaCantidadBase = $cantidad * $factorConversion;
    $costoUnitarioBase = $costoCompra / $factorConversion; // Costo por unidad base
    $totalCompra = $cantidad * $costoCompra;

    // 2. Insertar en la tabla central de compras
    $stmtInsCompra = $pdo->prepare("INSERT INTO compras 
                                    (fecha_compra, id_lugarCompra, total, tipo_pago, monto_efectivo, monto_credito, estado_pago) 
                                    VALUES (:fecha, :lugar, :total, 'contado', :monto_efectivo, 0.0, 'pagado')");
    $stmtInsCompra->execute([
        ':fecha' => $fechaCompra . ' ' . date('H:i:s'),
        ':lugar' => $lugarCompraId,
        ':total' => $totalCompra,
        ':monto_efectivo' => $totalCompra
    ]);
    $compraId = $pdo->lastInsertId();

    // 3. Insertar en compras_detalle
    $stmtInsDetalle = $pdo->prepare("INSERT INTO compras_detalle 
                                     (compra_id, producto_id, cantidad, costo_unitario, costo_total, facturado, fecha_vencimiento, presentacion_id, factor_conversion_compra, cantidad_unidades_base) 
                                     VALUES (:compraId, :productoId, :cantidad, :costo, :total, :facturado, :vence, :presId, :factor, :cantBase)");
    $stmtInsDetalle->execute([
        ':compraId' => $compraId,
        ':productoId' => $productoId,
        ':cantidad' => $cantidad,
        ':costo' => $costoCompra,
        ':total' => $totalCompra,
        ':facturado' => $conFactura,
        ':vence' => $fechaVencimiento,
        ':presId' => $presentacionId,
        ':factor' => $factorConversion,
        ':cantBase' => $nuevaCantidadBase
    ]);

    // 4. Insertar o actualizar la relación en producto_lugares_compra
    $stmtCheckLugar = $pdo->prepare("SELECT id FROM producto_lugares_compra 
                                     WHERE producto_id = :pId AND lugar_compra_id = :lugarId LIMIT 1");
    $stmtCheckLugar->execute([':pId' => $productoId, ':lugarId' => $lugarCompraId]);
    $existingLugar = $stmtCheckLugar->fetch();

    if ($existingLugar) {
        $stmtUpdLugar = $pdo->prepare("UPDATE producto_lugares_compra 
                                       SET costo_compra = :costo, 
                                           fecha_ultima_compra = :fecha, 
                                           fecha_vencimiento = :vence, 
                                           con_factura = :facturado,
                                           activo = 1,
                                           fecha_actualizacion = NOW() 
                                       WHERE id = :id");
        $stmtUpdLugar->execute([
            ':costo' => $costoUnitarioBase,
            ':fecha' => $fechaCompra,
            ':vence' => $fechaVencimiento,
            ':facturado' => $conFactura,
            ':id' => $existingLugar['id']
        ]);
    } else {
        $stmtInsLugar = $pdo->prepare("INSERT INTO producto_lugares_compra 
                                       (producto_id, lugar_compra_id, costo_compra, fecha_ultima_compra, fecha_vencimiento, con_factura, activo, fecha_creacion) 
                                       VALUES (:pId, :lugarId, :costo, :fecha, :vence, :facturado, 1, NOW())");
        $stmtInsLugar->execute([
            ':pId' => $productoId,
            ':lugarId' => $lugarCompraId,
            ':costo' => $costoUnitarioBase,
            ':fecha' => $fechaCompra,
            ':vence' => $fechaVencimiento,
            ':facturado' => $conFactura
        ]);
    }

    // 5. Recalcular y actualizar el Costo Promedio Ponderado (CPP) en productos_costo_promedio
    // Obtenemos todos los costos unitarios de los proveedores activos de este producto
    $stmtRestantes = $pdo->prepare("SELECT costo_compra FROM producto_lugares_compra 
                                   WHERE producto_id = :pId AND activo = 1");
    $stmtRestantes->execute([':pId' => $productoId]);
    $costosRestantes = $stmtRestantes->fetchAll(PDO::FETCH_COLUMN);

    if (count($costosRestantes) > 0) {
        $nuevoCostoPromedio = array_sum($costosRestantes) / count($costosRestantes);
    } else {
        $nuevoCostoPromedio = $costoUnitarioBase; // Fallback
    }

    $stmtCheckCpp = $pdo->prepare("SELECT * FROM productos_costo_promedio WHERE producto_id = :pId LIMIT 1");
    $stmtCheckCpp->execute([':pId' => $productoId]);
    $cppRow = $stmtCheckCpp->fetch();

    if ($cppRow) {
        $cantidadActual = (int)$cppRow['cantidad_total_unidades'];
        $nuevaCantidadTotal = $cantidadActual + $nuevaCantidadBase;
        $valorTotal = $nuevaCantidadTotal * $nuevoCostoPromedio;
        
        $stmtUpdCpp = $pdo->prepare("UPDATE productos_costo_promedio 
                                     SET costo_promedio_unidad_base = :costo, 
                                         cantidad_total_unidades = :cant, 
                                         valor_total_inventario = :valor,
                                         fecha_ultimo_calculo = NOW() 
                                     WHERE producto_id = :pId");
        $stmtUpdCpp->execute([
            ':costo' => $nuevoCostoPromedio,
            ':cant' => $nuevaCantidadTotal,
            ':valor' => $valorTotal,
            ':pId' => $productoId
        ]);
    } else {
        $nuevaCantidadTotal = $nuevaCantidadBase;
        $valorTotal = $nuevaCantidadTotal * $nuevoCostoPromedio;
        
        $stmtInsCpp = $pdo->prepare("INSERT INTO productos_costo_promedio 
                                     (producto_id, costo_promedio_unidad_base, cantidad_total_unidades, valor_total_inventario, fecha_ultimo_calculo) 
                                     VALUES (:pId, :costo, :cant, :valor, NOW())");
        $stmtInsCpp->execute([
            ':pId' => $productoId,
            ':costo' => $nuevoCostoPromedio,
            ':cant' => $nuevaCantidadTotal,
            ':valor' => $valorTotal
        ]);
    }

    // 6. Actualizar inventario en inventario_sucursal para la sucursal por defecto (sucursal_id = 1)
    $stmtCheckStock = $pdo->prepare("SELECT id FROM inventario_sucursal WHERE producto_id = :pId AND sucursal_id = 1 LIMIT 1");
    $stmtCheckStock->execute([':pId' => $productoId]);
    $existingStock = $stmtCheckStock->fetch();

    if ($existingStock) {
        $stockCol = $conFactura ? 'stock_facturado' : 'stock_no_facturado';
        $stmtUpdStock = $pdo->prepare("UPDATE inventario_sucursal 
                                       SET stock_total = stock_total + :cantBase,
                                           `$stockCol` = `$stockCol` + :cantBase_2,
                                           costo_promedio_local = :costoLocal,
                                           last_updated = NOW() 
                                       WHERE id = :id");
        $stmtUpdStock->execute([
            ':cantBase' => $nuevaCantidadBase,
            ':cantBase_2' => $nuevaCantidadBase,
            ':costoLocal' => $nuevoCostoPromedio,
            ':id' => $existingStock['id']
        ]);
    } else {
        $stockFacturado = $conFactura ? $nuevaCantidadBase : 0;
        $stockNoFacturado = $conFactura ? 0 : $nuevaCantidadBase;
        $stmtInsStock = $pdo->prepare("INSERT INTO inventario_sucursal 
                                       (producto_id, sucursal_id, stock_total, stock_facturado, stock_no_facturado, stock_minimo, costo_promedio_local, last_updated) 
                                       VALUES (:pId, 1, :cantBase, :fact, :noFact, 10, :costoLocal, NOW())");
        $stmtInsStock->execute([
            ':pId' => $productoId,
            ':cantBase' => $nuevaCantidadBase,
            ':fact' => $stockFacturado,
            ':noFact' => $stockNoFacturado,
            ':costoLocal' => $nuevoCostoPromedio
        ]);
    }

    $pdo->commit();

    echo json_encode([
        'success' => true,
        'message' => 'Compra manual registrada con éxito, stock de inventario incrementado y Costo Promedio recalculado.',
        'nuevo_costo_promedio' => $nuevoCostoPromedio
    ]);

} catch (Exception $e) {
    if (isset($pdo) && $pdo->inTransaction()) {
        $pdo->rollBack();
    }
    http_response_code(500);
    echo json_encode([
        'success' => false,
        'error' => 'Error al registrar la compra: ' . $e->getMessage()
    ]);
}
