<?php
/**
 * POST /api/inventario/productos/registrar_inicial.php
 */
require_once '../../config/database.php';
require_once '../../includes/helpers.php';
require_once '../costos/wac.php';

require_post();
$data = json_input();

// Valida campos requeridos
require_fields($data, ['sucursal_id', 'producto_id', 'presentacion_id', 'factor_conversion', 'cantidad', 'costo_unitario', 'tipo_stock']);

$pdo = getConnection();

try {
    $pdo->beginTransaction();

    $sucursal_id = (int)$data['sucursal_id'];
    $producto_id = (int)$data['producto_id'];
    $presentacion_id = (int)$data['presentacion_id'];
    $factor_conversion = (int)$data['factor_conversion'];
    $cantidad = (float)$data['cantidad'];
    $costo_unitario = (float)$data['costo_unitario'];
    $tipo_stock = trim($data['tipo_stock']); // 'facturado' o 'no_facturado'

    if ($sucursal_id <= 0 || $producto_id <= 0 || $presentacion_id <= 0 || $cantidad <= 0 || $factor_conversion <= 0) {
        throw new Exception("Datos de entrada no válidos.");
    }

    if ($tipo_stock !== 'facturado' && $tipo_stock !== 'no_facturado') {
        throw new Exception("Tipo de stock inválido. Debe ser 'facturado' o 'no_facturado'.");
    }

    // 1. Obtener o crear proveedor de "Inventario Inicial"
    $stmtP = $pdo->prepare("SELECT id FROM lugarcompra WHERE nombre = 'Inventario Inicial' LIMIT 1");
    $stmtP->execute();
    $lugar = $stmtP->fetch();
    if ($lugar) {
        $proveedor_id = (int)$lugar['id'];
    } else {
        $stmtP = $pdo->prepare("INSERT INTO lugarcompra (nombre, contacto_nombre, telefono, activo) VALUES ('Inventario Inicial', 'Sistema', '0000-0000', 1)");
        $stmtP->execute();
        $proveedor_id = (int)$pdo->lastInsertId();
    }

    // 2. Calcular cantidades y costos en unidades base
    $base_qty = (int)($cantidad * $factor_conversion);
    $costo_base = ($factor_conversion > 0) ? ($costo_unitario / $factor_conversion) : $costo_unitario;
    $total_compra = (float)($cantidad * $costo_unitario);

    // 3. Registrar "Compra" virtual para Kardex y trazabilidad
    $stmtC = $pdo->prepare("INSERT INTO compras (fecha_compra, id_lugarCompra, total, tipo_pago, monto_efectivo, monto_credito, estado_pago) VALUES (NOW(), ?, ?, 'contado', ?, 0.00, 'pagado')");
    $stmtC->execute([$proveedor_id, $total_compra, $total_compra]);
    $compra_id = $pdo->lastInsertId();

    $fecha_vencimiento = isset($data['fecha_vencimiento']) && !empty($data['fecha_vencimiento']) ? trim($data['fecha_vencimiento']) : null;

    // Detalle de compra
    $facturado = ($tipo_stock === 'facturado') ? 1 : 0;
    $stmtD = $pdo->prepare("INSERT INTO compras_detalle (compra_id, producto_id, cantidad, costo_unitario, costo_total, facturado, numero_factura, presentacion_id, factor_conversion_compra, cantidad_unidades_base, fecha_vencimiento) VALUES (?, ?, ?, ?, ?, ?, 'INV-INICIAL', ?, ?, ?, ?)");
    $stmtD->execute([$compra_id, $producto_id, $cantidad, $costo_unitario, $total_compra, $facturado, $presentacion_id, $factor_conversion, $base_qty, $fecha_vencimiento]);

    // 4. Actualizar inventario por sucursal
    $sFact = $facturado ? $base_qty : 0;
    $sNoFact = $facturado ? 0 : $base_qty;

    $stmtInv = $pdo->prepare("
        INSERT INTO inventario_sucursal (producto_id, sucursal_id, stock_total, stock_facturado, stock_no_facturado, costo_promedio_local) 
        VALUES (?, ?, ?, ?, ?, ?) 
        ON DUPLICATE KEY UPDATE 
            stock_total = stock_total + VALUES(stock_total), 
            stock_facturado = stock_facturado + VALUES(stock_facturado), 
            stock_no_facturado = stock_no_facturado + VALUES(stock_no_facturado), 
            costo_promedio_local = VALUES(costo_promedio_local),
            last_updated = NOW()
    ");
    $stmtInv->execute([$producto_id, $sucursal_id, $base_qty, $sFact, $sNoFact, $costo_base]);

    // Obtener el nuevo stock para Kardex
    $stmtCheck = $pdo->prepare("SELECT stock_total FROM inventario_sucursal WHERE producto_id = ? AND sucursal_id = ?");
    $stmtCheck->execute([$producto_id, $sucursal_id]);
    $updatedStock = (int)$stmtCheck->fetchColumn();

    // 5. Registrar en producto_lugares_compra
    $stmtCheckPLC = $pdo->prepare("SELECT id FROM producto_lugares_compra WHERE producto_id = ? AND lugar_compra_id = ? LIMIT 1");
    $stmtCheckPLC->execute([$producto_id, $proveedor_id]);
    $plcRow = $stmtCheckPLC->fetch();
    if ($plcRow) {
        $stmtUpdatePLC = $pdo->prepare("UPDATE producto_lugares_compra SET costo_compra = ?, fecha_ultima_compra = NOW(), fecha_vencimiento = ?, con_factura = ?, activo = 1, fecha_actualizacion = NOW() WHERE id = ?");
        $stmtUpdatePLC->execute([$costo_base, $fecha_vencimiento, $facturado, $plcRow['id']]);
    } else {
        $stmtInsertPLC = $pdo->prepare("INSERT INTO producto_lugares_compra (producto_id, lugar_compra_id, costo_compra, fecha_ultima_compra, fecha_vencimiento, con_factura, activo) VALUES (?, ?, ?, NOW(), ?, ?, 1)");
        $stmtInsertPLC->execute([$producto_id, $proveedor_id, $costo_base, $fecha_vencimiento, $facturado]);
    }

    // 6. Obtener ID de usuario asignado o fallback
    if (session_status() === PHP_SESSION_NONE) {
        session_start();
    }
    $usuario_id = isset($data['usuario_id']) && (int)$data['usuario_id'] > 0 
        ? (int)$data['usuario_id'] 
        : (int)($_SESSION['user_id'] ?? $_SESSION['usuario_id'] ?? 1);

    // 7. Registrar movimiento en Kardex
    $justificacion_kardex = 'Inventario Inicial - Conteo Físico (' . ($facturado ? 'Facturado' : 'Sin Factura') . ')';
    $stmtK = $pdo->prepare("INSERT INTO inventario_movimientos (producto_id, sucursal_id, tipo_movimiento, cantidad, saldo_despues, referencia_id, justificacion, usuario_id) VALUES (?, ?, 'ingreso_compra', ?, ?, ?, ?, ?)");
    $stmtK->execute([$producto_id, $sucursal_id, $base_qty, $updatedStock, $compra_id, $justificacion_kardex, $usuario_id]);

    // 8. Recalcular WAC (Weighted Average Cost)
    recalcular_wac($pdo, $producto_id, $base_qty, $costo_base);

    // 9. Registrar auditoría silenciosa
    if (function_exists('logAudit')) {
        logAudit('Inventario', 'Registro Inventario Inicial', 'inventario_sucursal', $producto_id, "Se cargaron $base_qty unidades base en Sucursal ID $sucursal_id.");
    }

    $pdo->commit();

    json_success([
        'compra_id' => $compra_id,
        'base_qty' => $base_qty,
        'stock_actual' => $updatedStock
    ], 'Inventario inicial registrado y costo promedio actualizado con éxito');

} catch (Exception $e) {
    if ($pdo->inTransaction()) {
        $pdo->rollBack();
    }
    json_error("Error al registrar inventario inicial: " . $e->getMessage(), 400);
}
