<?php
/**
 * API: Guardar datos consolidados de FEL en la base de datos (Versión ProHigh)
 * POST JSON: { totalFacturas, observaciones, productos: [...] }
 */
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type');

$method = $_SERVER['REQUEST_METHOD'] ?? 'POST';

if ($method === 'OPTIONS') {
    http_response_code(200);
    exit;
}

if ($method !== 'POST') {
    http_response_code(405);
    echo json_encode(['success' => false, 'error' => 'Método no permitido']);
    exit;
}

require_once __DIR__ . '/../config/db.php';

try {
    $input = json_decode(file_get_contents('php://input') ?: ($GLOBALS['MOCK_INPUT'] ?? ''), true);

    if (!$input || !isset($input['productos']) || !is_array($input['productos'])) {
        throw new Exception('Datos inválidos: se requiere un array de productos');
    }

    $productos = $input['productos'];
    $totalFacturas = intval($input['totalFacturas'] ?? 0);
    $observaciones = trim($input['observaciones'] ?? '');
    $fechaImportacion = !empty($input['fecha_importacion']) ? trim($input['fecha_importacion']) : null;
    
    $registrarCompraERP = !empty($input['registrar_compra_erp']);
    $comprasConfig = $input['compras_config'] ?? [];
    
    $crearLibro = !empty($input['crear_libro']);
    $nombreLibro = trim($input['nombre_libro'] ?? '');
    $colorLibro = trim($input['color_libro'] ?? '#10b981');

    if (count($productos) === 0) {
        throw new Exception('No hay productos para guardar');
    }

    $pdo = getConnection();
    $pdo->beginTransaction();

    // === 1. Crear registro de importación ===
    $totalBonif = 0;
    $totalInvertido = 0;
    foreach ($productos as $p) {
        if (!empty($p['tieneBonificacion'])) $totalBonif++;
        $totalInvertido += floatval($p['totalPagado'] ?? 0);
    }

    $fechaSql = $fechaImportacion 
        ? (preg_match('/^\d{4}-\d{2}-\d{2}$/', $fechaImportacion) ? ($fechaImportacion . ' ' . date('H:i:s')) : $fechaImportacion)
        : date('Y-m-d H:i:s');

    $stmtImport = $pdo->prepare("
        INSERT INTO fel_importaciones (fecha_importacion, total_facturas, total_productos, total_bonificaciones, total_invertido, observaciones)
        VALUES (:fecha_importacion, :facturas, :productos, :bonif, :total, :obs)
    ");
    $stmtImport->execute([
        ':fecha_importacion' => $fechaSql,
        ':facturas'          => $totalFacturas,
        ':productos'         => count($productos),
        ':bonif'             => $totalBonif,
        ':total'             => round($totalInvertido, 2),
        ':obs'               => $observaciones ?: null
    ]);
    $importacionId = $pdo->lastInsertId();

    // === 1b. Crear libro si se solicita ===
    $libroId = null;
    $agregadoLibro = false;
    if ($crearLibro && !empty($nombreLibro)) {
        $stmtLib = $pdo->prepare("INSERT INTO libros (nombre, color, fecha_creado, fecha_actualizado) VALUES (:nombre, :color, NOW(), NOW())");
        $stmtLib->execute([
            ':nombre' => $nombreLibro,
            ':color'  => $colorLibro
        ]);
        $libroId = intval($pdo->lastInsertId());

        // Crear una única hoja vinculada a este libro y a esta importación
        $stmtHoja = $pdo->prepare("INSERT INTO libro_hojas (libro_id, importacion_id, nombre_hoja, fecha_agregado) VALUES (:libro_id, :imp_id, :nombre, NOW())");
        $stmtHoja->execute([
            ':libro_id' => $libroId,
            ':imp_id'   => $importacionId,
            ':nombre'   => $nombreLibro
        ]);
        $agregadoLibro = true;
    }

    // === 2. Caché de lugares de compra ===
    $lugarCache = [];
    $lugarNameCache = [];

    $stmtBuscarLugar = $pdo->prepare("SELECT id, nombre FROM lugarcompra WHERE UPPER(TRIM(nombre)) = UPPER(TRIM(:nombre)) LIMIT 1");
    $stmtCrearLugar = $pdo->prepare("INSERT INTO lugarcompra (nombre) VALUES (:nombre)");
    $stmtGetLugarName = $pdo->prepare("SELECT nombre FROM lugarcompra WHERE id = :id LIMIT 1");

    // Helper para obtener el nombre del proveedor por su ID
    $getLugarNombre = function($id) use ($pdo, $stmtGetLugarName, &$lugarNameCache) {
        if (isset($lugarNameCache[$id])) return $lugarNameCache[$id];
        $stmtGetLugarName->execute([':id' => $id]);
        $row = $stmtGetLugarName->fetch();
        $nombre = $row ? $row['nombre'] : 'Desconocido';
        $lugarNameCache[$id] = $nombre;
        return $nombre;
    };

    // === 3. Insertar cada producto con su mapeo inteligente ===
    $stmtDetalle = $pdo->prepare("
        INSERT INTO fel_importacion_detalle
            (importacion_id, lugar_compra_id, proveedor_nombre, numero_autorizacion, descripcion, cantidad_total,
             cantidad_bonificada, costo_real_unitario, precio_original, total_pagado,
             tiene_bonificacion, consolidado, es_exento, fecha_factura)
        VALUES
            (:imp_id, :lugar_id, :proveedor, :num_fac, :desc, :cant_total,
             :cant_bonif, :costo_real, :precio_orig, :total_pagado,
             :tiene_bonif, :consolidado, :es_exento, :fecha)
    ");

    $comprasAgrupadas = [];

    foreach ($productos as $p) {
        $finalLugarId = null;

        // Validar si viene mapeado a un ID existente del sistema o es nuevo
        if (isset($p['lugar_compra_id']) && $p['lugar_compra_id'] !== 'NEW' && intval($p['lugar_compra_id']) > 0) {
            $finalLugarId = intval($p['lugar_compra_id']);
        } else {
            // Es nuevo proveedor o personalizado por el usuario
            $nombrePersonalizado = trim($p['nuevo_lugar_nombre'] ?? $p['emisor'] ?? 'Desconocido');
            $provKey = mb_strtoupper($nombrePersonalizado);

            if (isset($lugarCache[$provKey])) {
                $finalLugarId = $lugarCache[$provKey];
            } else {
                $stmtBuscarLugar->execute([':nombre' => $nombrePersonalizado]);
                $row = $stmtBuscarLugar->fetch();

                if ($row) {
                    $finalLugarId = intval($row['id']);
                } else {
                    // Crear nuevo lugar de compra en catálogo
                    $stmtCrearLugar->execute([':nombre' => $nombrePersonalizado]);
                    $finalLugarId = intval($pdo->lastInsertId());
                }
                $lugarCache[$provKey] = $finalLugarId;
            }
        }

        // Obtener el nombre formal del proveedor para los detalles
        $nombreProveedorFinal = $getLugarNombre($finalLugarId);

        $cantTotal = floatval($p['cantidadTotal'] ?? 0);
        $totalPagado = floatval($p['totalPagado'] ?? 0);
        $costoReal = $cantTotal > 0 ? $totalPagado / $cantTotal : 0;

        $stmtDetalle->execute([
            ':imp_id'       => $importacionId,
            ':lugar_id'     => $finalLugarId,
            ':proveedor'    => $nombreProveedorFinal,
            ':num_fac'      => trim($p['numFactura'] ?? 'S/N'),
            ':desc'         => trim($p['descripcion'] ?? ''),
            ':cant_total'   => $cantTotal,
            ':cant_bonif'   => floatval($p['cantidadBonif'] ?? 0),
            ':costo_real'   => round($costoReal, 6),
            ':precio_orig'  => !empty($p['precioOriginal']) ? round(floatval($p['precioOriginal']), 6) : null,
            ':total_pagado' => round($totalPagado, 2),
            ':tiene_bonif'  => !empty($p['tieneBonificacion']) ? 1 : 0,
            ':consolidado'  => !empty($p['consolidado']) ? 1 : 0,
            ':es_exento'    => !empty($p['esExento']) ? 1 : 0,
            ':fecha'        => trim($p['fecha'] ?? '')
        ]);

        $newDetailId = $pdo->lastInsertId();

        // 3a. Buscar mapeo previo de múltiples variantes para esta descripción
        $stmtPrev = $pdo->prepare("
            SELECT dm.producto_id, dm.cantidad, fd.cantidad_total as total_orig
            FROM fel_importacion_detalle_mapeo dm
            JOIN fel_importacion_detalle fd ON dm.importacion_detalle_id = fd.id
            WHERE fd.descripcion = :desc
              AND fd.id = (
                  SELECT MAX(fd2.id) 
                  FROM fel_importacion_detalle fd2
                  JOIN fel_importacion_detalle_mapeo dm2 ON fd2.id = dm2.importacion_detalle_id
                  WHERE fd2.descripcion = :desc2
              )
        ");
        $stmtPrev->execute([':desc' => trim($p['descripcion']), ':desc2' => trim($p['descripcion'])]);
        $prevVariants = $stmtPrev->fetchAll(PDO::FETCH_ASSOC);

        if (count($prevVariants) > 0) {
            // Guardar el desglose de variantes en la nueva tabla
            $stmtNewMap = $pdo->prepare("
                INSERT INTO fel_importacion_detalle_mapeo (importacion_detalle_id, producto_id, cantidad)
                VALUES (:det_id, :prod_id, :cant)
            ");
            
            foreach ($prevVariants as $pv) {
                $ratio = floatval($pv['cantidad']) / floatval($pv['total_orig']);
                $mappedQty = round($cantTotal * $ratio, 2);
                $stmtNewMap->execute([
                    ':det_id'  => $newDetailId,
                    ':prod_id' => intval($pv['producto_id']),
                    ':cant'    => $mappedQty
                ]);

                // Recolectar para registrar en compras en SufarmaERP desglosado
                if ($registrarCompraERP) {
                    $emisor = $p['emisor'];
                    if (!isset($comprasAgrupadas[$finalLugarId])) {
                        $comprasAgrupadas[$finalLugarId] = [
                            'proveedor_id' => $finalLugarId,
                            'emisor_nombre' => $emisor,
                            'numero_factura' => trim($p['numFactura'] ?? 'S/N'),
                            'fecha_compra' => trim($p['fecha'] ?? ''),
                            'items' => []
                        ];
                    }

                    // Obtener factor_caja y factor_blister para esta variante
                    $stmtF = $pdo->prepare("
                        SELECT 
                            COALESCE((SELECT factor_conversion FROM producto_presentaciones WHERE producto_id = :pId AND presentacion_id = 3 AND activo = 1 LIMIT 1), 1) as f_caja,
                            COALESCE((SELECT factor_conversion FROM producto_presentaciones WHERE producto_id = :pId AND presentacion_id = 2 AND activo = 1 LIMIT 1), 1) as f_blister
                    ");
                    $stmtF->execute([':pId' => $pv['producto_id']]);
                    $fRow = $stmtF->fetch(PDO::FETCH_ASSOC);

                    $comprasAgrupadas[$finalLugarId]['items'][] = [
                        'producto_id' => intval($pv['producto_id']),
                        'cantidadTotal' => $mappedQty,
                        'totalPagado' => round($totalPagado * $ratio, 2),
                        'factor_caja' => intval($fRow['f_caja'] ?? 1),
                        'factor_blister' => intval($fRow['f_blister'] ?? 1),
                        'esExento' => !empty($p['esExento'])
                    ];
                }
            }
        } else {
            // Guardar mapeo único tradicional en la tabla nueva para consistencia
            if (!empty($p['producto_id'])) {
                $stmtNewMap = $pdo->prepare("
                    INSERT INTO fel_importacion_detalle_mapeo (importacion_detalle_id, producto_id, cantidad)
                    VALUES (:det_id, :prod_id, :cant)
                ");
                $stmtNewMap->execute([
                    ':det_id'  => $newDetailId,
                    ':prod_id' => intval($p['producto_id']),
                    ':cant'    => $cantTotal
                ]);

                // Recolectar para registrar en compras en SufarmaERP de forma tradicional
                if ($registrarCompraERP) {
                    $emisor = $p['emisor'];
                    if (!isset($comprasAgrupadas[$finalLugarId])) {
                        $comprasAgrupadas[$finalLugarId] = [
                            'proveedor_id' => $finalLugarId,
                            'emisor_nombre' => $emisor,
                            'numero_factura' => trim($p['numFactura'] ?? 'S/N'),
                            'fecha_compra' => trim($p['fecha'] ?? ''),
                            'items' => []
                        ];
                    }
                    $comprasAgrupadas[$finalLugarId]['items'][] = [
                        'producto_id' => intval($p['producto_id']),
                        'cantidadTotal' => $cantTotal,
                        'totalPagado' => $totalPagado,
                        'factor_caja' => intval($p['factor_caja'] ?? 1),
                        'factor_blister' => intval($p['factor_blister'] ?? 1),
                        'esExento' => !empty($p['esExento'])
                    ];
                }
            }
        }
    }

    // Registrar compras en SufarmaERP si fue solicitado y hay elementos mapeados
    if ($registrarCompraERP && !empty($comprasAgrupadas)) {
        require_once __DIR__ . '/../../SufarmaERP/api/inventario/costos/wac.php';
        
        $stmtC = $pdo->prepare("INSERT INTO compras (fecha_compra, id_lugarCompra, total, tipo_pago, monto_efectivo, monto_credito, fecha_limite_pago, estado_pago) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
        $stmtCP = $pdo->prepare("INSERT INTO cuentas_pagar (compra_id, proveedor_id, numero_factura, fecha_compra, fecha_vencimiento, total_factura, saldo_pendiente, estado, dias_credito) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
        $stmtD = $pdo->prepare("INSERT INTO compras_detalle (compra_id, producto_id, cantidad, costo_unitario, costo_total, facturado, numero_factura, fecha_vencimiento, presentacion_id, factor_conversion_compra, cantidad_unidades_base) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
        $stmtInv = $pdo->prepare("INSERT INTO inventario_sucursal (producto_id, sucursal_id, stock_total, stock_facturado, stock_no_facturado, costo_promedio_local, last_updated) VALUES (?, 1, ?, ?, ?, ?, NOW()) 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()");
        $stmtK = $pdo->prepare("INSERT INTO inventario_movimientos (producto_id, sucursal_id, tipo_movimiento, cantidad, saldo_despues, referencia_id, justificacion, usuario_id) VALUES (?, 1, 'ingreso_compra', ?, ?, ?, ?, 1)");
        $stmtCheck = $pdo->prepare("SELECT stock_total FROM inventario_sucursal WHERE producto_id = ? AND sucursal_id = 1");

        foreach ($comprasAgrupadas as $lugarId => $compra) {
            $emisor = $compra['emisor_nombre'];
            
            $tipo_pago = 'contado';
            $dias_credito = 30;
            $monto_efectivo = 0.00;
            if (isset($comprasConfig[$emisor])) {
                $conf = $comprasConfig[$emisor];
                $tipo_pago = $conf['tipo_pago'] ?? 'contado';
                $dias_credito = intval($conf['dias_credito'] ?? 30);
                $monto_efectivo = floatval($conf['monto_efectivo'] ?? 0.00);
            }

            $total_compra = 0.0;
            foreach ($compra['items'] as $item) {
                $total_compra += $item['totalPagado'];
            }

            $fecha_compra = $compra['fecha_compra'];
            if (preg_match('/^\d{2}-\d{2}-\d{4}$/', $fecha_compra)) {
                $parts = explode('-', $fecha_compra);
                $fecha_compra = "{$parts[2]}-{$parts[1]}-{$parts[0]}";
            }
            if (empty($fecha_compra)) {
                $fecha_compra = date('Y-m-d');
            }

            $monto_ef = 0.0;
            $monto_cr = 0.0;
            $estado_pago = 'pagado';
            $fecha_limite = null;

            if ($tipo_pago === 'contado') {
                $monto_ef = $total_compra;
            } elseif ($tipo_pago === 'credito') {
                $monto_cr = $total_compra;
                $estado_pago = 'pendiente';
                $fecha_limite = date('Y-m-d', strtotime($fecha_compra . " + $dias_credito days"));
            } elseif ($tipo_pago === 'mixto') {
                $monto_ef = $monto_efectivo;
                $monto_cr = $total_compra - $monto_ef;
                if ($monto_cr > 0) {
                    $estado_pago = 'pendiente';
                    $fecha_limite = date('Y-m-d', strtotime($fecha_compra . " + $dias_credito days"));
                }
            }

            $stmtC->execute([$fecha_compra, $lugarId, $total_compra, $tipo_pago, $monto_ef, $monto_cr, $fecha_limite, $estado_pago]);
            $compra_id = $pdo->lastInsertId();

            $saldo_pendiente = ($tipo_pago === 'contado') ? 0.0 : ($tipo_pago === 'mixto' ? $monto_cr : $total_compra);
            $estado_cuenta = ($saldo_pendiente <= 0) ? 'pagada' : 'pendiente';
            $stmtCP->execute([$compra_id, $lugarId, $compra['numero_factura'], $fecha_compra, $fecha_limite, $total_compra, $saldo_pendiente, $estado_cuenta, $dias_credito]);

            foreach ($compra['items'] as $item) {
                $pid = $item['producto_id'];
                $qty = $item['cantidadTotal'];
                $costoU = $qty > 0 ? ($item['totalPagado'] / $qty) : 0;
                $facturado = 1;
                $venc = null;
                $factor = $item['factor_caja'];
                $pres_id = 3; // Caja

                $costo_total = $item['totalPagado'];
                $base_qty = $qty * $factor;
                $base_costoU = ($factor > 0) ? ($costoU / $factor) : $costoU;

                $stmtD->execute([
                    $compra_id, $pid, $qty, $costoU, $costo_total, $facturado, $compra['numero_factura'], $venc, $pres_id, $factor, $base_qty
                ]);

                $sFact = $base_qty;
                $sNoFact = 0;
                $stmtInv->execute([$pid, $base_qty, $sFact, $sNoFact, $base_costoU]);

                $stmtCheck->execute([$pid]);
                $currStock = intval($stmtCheck->fetchColumn() ?: 0);

                $justificacion_kardex = "Factura {$compra['numero_factura']} (Facturado)";
                $stmtK->execute([$pid, $base_qty, $currStock, $compra_id, $justificacion_kardex]);

                recalcular_wac($pdo, $pid, $base_qty, $base_costoU);
            }
        }
    }

    $pdo->commit();

    echo json_encode([
        'success' => true,
        'importacion_id' => intval($importacionId),
        'libro_id' => $libroId,
        'agregado_libro' => $agregadoLibro,
        'message' => $agregadoLibro 
            ? "Se guardaron " . count($productos) . " productos correctamente en el libro '$nombreLibro'." 
            : "Se guardaron " . count($productos) . " productos correctamente en el historial global."
    ]);

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