<?php

/**
 * InventariosRepartidor.php - Gestión de inventarios por repartidor
 * Maneja la asignación, retiro, ajuste y seguimiento de productos asignados a repartidores
 */

// Incluir Auth para obtener usuario del token
require_once __DIR__ . '/../../modelos/Auth.php';

// Función para enviar respuesta JSON (si no está definida)
if (!function_exists('sendResponse')) {
    function sendResponse($success, $message = '', $data = null)
    {
        echo json_encode([
            "success" => $success,
            "message" => $message,
            "data" => $data
        ]);
        exit;
    }
}

// Función para obtener usuario del token
if (!function_exists('getUserFromToken')) {
    function getUserFromToken($conn)
    {
        $authHeader = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
        if (empty($authHeader)) {
            $headers = getallheaders();
            $authHeader = $headers['Authorization'] ?? '';
        }

        if (empty($authHeader)) {
            return null;
        }

        $token = str_replace('Bearer ', '', $authHeader);
        $auth = new Auth($conn);
        return $auth->obtenerUsuarioDeToken($token);
    }
}

// === OBTENER INVENTARIO DE UN REPARTIDOR ===
if ($tipo === 'getInventarioRepartidor') {
    $repartidorId = isset($datapost['repartidor_id']) ? (int)$datapost['repartidor_id'] : 0;

    if ($repartidorId <= 0) {
        sendResponse(false, "ID de repartidor requerido");
    }

    try {
        $query = "SELECT
                    ir.id,
                    ir.repartidor_id,
                    ir.producto_id,
                    ir.cantidad,
                    ir.fecha_asignacion,
                    ir.updated_at,
                    p.codigo,
                    p.nombre,
                    p.descripcion,
                    p.precio,
                    p.unidad_medida,
                    p.imagen_url,
                    p.orden,
                    c.nombre as categoria_nombre
                FROM inventarios_repartidor ir
                INNER JOIN productos p ON ir.producto_id = p.id
                LEFT JOIN categorias_productos c ON p.categoria_id = c.id
                WHERE ir.repartidor_id = :repartidor_id
                ORDER BY COALESCE(p.orden, 999999) ASC, p.nombre ASC";

        $stmt = $conn->prepare($query);
        $stmt->bindParam(':repartidor_id', $repartidorId);
        $stmt->execute();

        $inventario = $stmt->fetchAll(PDO::FETCH_ASSOC);

        sendResponse(true, "Inventario obtenido exitosamente", $inventario);
    } catch (Exception $e) {
        error_log("Error obteniendo inventario: " . $e->getMessage());
        sendResponse(false, "Error obteniendo inventario: " . $e->getMessage());
    }
}

// === OBTENER INVENTARIOS DE TODOS LOS REPARTIDORES ===
if ($tipo === 'getInventariosRepartidores') {
    try {
        $query = "SELECT
                    r.id as repartidor_id,
                    r.codigo as repartidor_codigo,
                    r.nombre as repartidor_nombre,
                    r.apellidos as repartidor_apellidos,
                    COUNT(DISTINCT ir.producto_id) as total_productos,
                    SUM(ir.cantidad) as cantidad_total,
                    SUM(ir.cantidad * p.precio) as valor_total
                FROM repartidores r
                LEFT JOIN inventarios_repartidor ir ON r.id = ir.repartidor_id AND ir.cantidad > 0
                LEFT JOIN productos p ON ir.producto_id = p.id
                GROUP BY r.id, r.codigo, r.nombre, r.apellidos
                ORDER BY r.nombre ASC";

        $stmt = $conn->prepare($query);
        $stmt->execute();

        $inventarios = $stmt->fetchAll(PDO::FETCH_ASSOC);

        sendResponse(true, "Inventarios obtenidos exitosamente", $inventarios);
    } catch (Exception $e) {
        error_log("Error obteniendo inventarios: " . $e->getMessage());
        sendResponse(false, "Error obteniendo inventarios: " . $e->getMessage());
    }
}

// === ASIGNAR PRODUCTOS A REPARTIDOR ===
if ($tipo === 'asignarProductosRepartidor') {
    $repartidorId = isset($datapost['repartidor_id']) ? (int)$datapost['repartidor_id'] : 0;
    $productos = isset($datapost['productos']) ? $datapost['productos'] : [];
    $notas = isset($datapost['notas']) ? $datapost['notas'] : '';

    if ($repartidorId <= 0) {
        sendResponse(false, "ID de repartidor requerido");
    }

    if (empty($productos)) {
        sendResponse(false, "Debe incluir al menos un producto");
    }

    // Obtener usuario del token
    $usuario = getUserFromToken($conn);
    $usuarioId = $usuario ? $usuario['sub'] : null;

    try {
        $conn->beginTransaction();

        foreach ($productos as $producto) {
            $productoId = (int)$producto['producto_id'];
            $cantidad = (float)$producto['cantidad'];

            if ($cantidad <= 0) continue;

            // Obtener stock actual del almacén (sin validar si es suficiente)
            $queryStock = "SELECT stock_actual FROM productos WHERE id = :producto_id";
            $stmtStock = $conn->prepare($queryStock);
            $stmtStock->bindParam(':producto_id', $productoId);
            $stmtStock->execute();
            $stockActual = $stmtStock->fetchColumn();

            if ($stockActual === false) {
                throw new Exception("Producto no encontrado con ID: $productoId");
            }

            // NOTA: Permitimos transferir aunque el stock sea insuficiente
            // Esto puede resultar en stock negativo en el almacén

            // Actualizar o insertar en inventario del repartidor
            $queryCheck = "SELECT cantidad FROM inventarios_repartidor
                          WHERE repartidor_id = :repartidor_id AND producto_id = :producto_id";
            $stmtCheck = $conn->prepare($queryCheck);
            $stmtCheck->bindParam(':repartidor_id', $repartidorId);
            $stmtCheck->bindParam(':producto_id', $productoId);
            $stmtCheck->execute();
            $cantidadActual = $stmtCheck->fetchColumn();

            if ($cantidadActual !== false) {
                // Actualizar cantidad existente
                $nuevaCantidad = $cantidadActual + $cantidad;
                $queryUpdate = "UPDATE inventarios_repartidor
                              SET cantidad = :cantidad, updated_at = NOW()
                              WHERE repartidor_id = :repartidor_id AND producto_id = :producto_id";
                $stmtUpdate = $conn->prepare($queryUpdate);
                $stmtUpdate->bindParam(':cantidad', $nuevaCantidad);
                $stmtUpdate->bindParam(':repartidor_id', $repartidorId);
                $stmtUpdate->bindParam(':producto_id', $productoId);
                $stmtUpdate->execute();
            } else {
                // Insertar nuevo registro
                $queryInsert = "INSERT INTO inventarios_repartidor
                              (repartidor_id, producto_id, cantidad, fecha_asignacion, created_at, updated_at)
                              VALUES (:repartidor_id, :producto_id, :cantidad, NOW(), NOW(), NOW())";
                $stmtInsert = $conn->prepare($queryInsert);
                $stmtInsert->bindParam(':repartidor_id', $repartidorId);
                $stmtInsert->bindParam(':producto_id', $productoId);
                $stmtInsert->bindParam(':cantidad', $cantidad);
                $stmtInsert->execute();
            }

            // Descontar del almacén
            $queryAlmacen = "UPDATE productos
                           SET stock_actual = stock_actual - :cantidad, updated_at = NOW()
                           WHERE id = :producto_id";
            $stmtAlmacen = $conn->prepare($queryAlmacen);
            $stmtAlmacen->bindParam(':cantidad', $cantidad);
            $stmtAlmacen->bindParam(':producto_id', $productoId);
            $stmtAlmacen->execute();

            // Obtener información del repartidor para el motivo
            $queryRepartidor = "SELECT nombre, apellidos FROM repartidores WHERE id = :repartidor_id";
            $stmtRepartidor = $conn->prepare($queryRepartidor);
            $stmtRepartidor->bindParam(':repartidor_id', $repartidorId);
            $stmtRepartidor->execute();
            $repartidor = $stmtRepartidor->fetch(PDO::FETCH_ASSOC);
            $nombreRepartidor = $repartidor['nombre'] . ' ' . $repartidor['apellidos'];

            // Registrar movimiento en tabla de repartidor
            $queryMovimiento = "INSERT INTO movimientos_inventario_repartidor
                              (repartidor_id, producto_id, tipo_movimiento, cantidad, notas, created_at)
                              VALUES (:repartidor_id, :producto_id, 'asignacion', :cantidad, :notas, NOW())";
            $stmtMovimiento = $conn->prepare($queryMovimiento);
            $stmtMovimiento->bindParam(':repartidor_id', $repartidorId);
            $stmtMovimiento->bindParam(':producto_id', $productoId);
            $stmtMovimiento->bindParam(':cantidad', $cantidad);
            $stmtMovimiento->bindParam(':notas', $notas);
            $stmtMovimiento->execute();

            // Registrar movimiento en tabla general de stock (movimientos_stock)
            // ID 9 = "Transferencia salida" (motivo de salida para traspaso a repartidor)
            $motivoId = 9;
            $motivoTexto = "Traspaso a repartidor: $nombreRepartidor";
            if (!empty($notas)) {
                $motivoTexto .= " - $notas";
            }

            $queryMovimientoStock = "INSERT INTO movimientos_stock
                                    (producto_id, tipo_movimiento, cantidad, stock_anterior, stock_nuevo, motivo, motivo_id, usuario_id, created_at)
                                    VALUES (:producto_id, 'salida', :cantidad, :stock_anterior, :stock_nuevo, :motivo, :motivo_id, :usuario_id, NOW())";
            $stmtMovimientoStock = $conn->prepare($queryMovimientoStock);
            $stmtMovimientoStock->bindParam(':producto_id', $productoId);
            $stmtMovimientoStock->bindParam(':cantidad', $cantidad);
            $stmtMovimientoStock->bindParam(':stock_anterior', $stockActual);
            $nuevoStockAlmacen = $stockActual - $cantidad;
            $stmtMovimientoStock->bindParam(':stock_nuevo', $nuevoStockAlmacen);
            $stmtMovimientoStock->bindParam(':motivo', $motivoTexto);
            $stmtMovimientoStock->bindParam(':motivo_id', $motivoId);
            $stmtMovimientoStock->bindParam(':usuario_id', $usuarioId);
            $stmtMovimientoStock->execute();
        }

        $conn->commit();
        sendResponse(true, "Productos asignados exitosamente");
    } catch (Exception $e) {
        if ($conn->inTransaction()) {
            $conn->rollBack();
        }
        error_log("Error asignando productos: " . $e->getMessage());
        sendResponse(false, "Error asignando productos: " . $e->getMessage());
    }
}

// === RETIRAR PRODUCTOS DE REPARTIDOR ===
if ($tipo === 'retirarProductosRepartidor') {
    $repartidorId = isset($datapost['repartidor_id']) ? (int)$datapost['repartidor_id'] : 0;
    $productos = isset($datapost['productos']) ? $datapost['productos'] : [];
    $notas = isset($datapost['notas']) ? $datapost['notas'] : '';

    if ($repartidorId <= 0) {
        sendResponse(false, "ID de repartidor requerido");
    }

    if (empty($productos)) {
        sendResponse(false, "Debe incluir al menos un producto");
    }

    // Obtener usuario del token
    $usuario = getUserFromToken($conn);
    $usuarioId = $usuario ? $usuario['sub'] : null;

    try {
        $conn->beginTransaction();

        foreach ($productos as $producto) {
            $productoId = (int)$producto['producto_id'];
            $cantidad = (float)$producto['cantidad'];

            if ($cantidad <= 0) continue;

            // Verificar cantidad disponible en inventario del repartidor
            $queryCheck = "SELECT cantidad FROM inventarios_repartidor
                          WHERE repartidor_id = :repartidor_id AND producto_id = :producto_id";
            $stmtCheck = $conn->prepare($queryCheck);
            $stmtCheck->bindParam(':repartidor_id', $repartidorId);
            $stmtCheck->bindParam(':producto_id', $productoId);
            $stmtCheck->execute();
            $cantidadActual = $stmtCheck->fetchColumn();

            if ($cantidadActual === false || $cantidadActual < $cantidad) {
                throw new Exception("Cantidad insuficiente en inventario del repartidor para producto ID: $productoId");
            }

            // Restar del inventario del repartidor
            $nuevaCantidad = $cantidadActual - $cantidad;
            $queryUpdate = "UPDATE inventarios_repartidor
                          SET cantidad = :cantidad, updated_at = NOW()
                          WHERE repartidor_id = :repartidor_id AND producto_id = :producto_id";
            $stmtUpdate = $conn->prepare($queryUpdate);
            $stmtUpdate->bindParam(':cantidad', $nuevaCantidad);
            $stmtUpdate->bindParam(':repartidor_id', $repartidorId);
            $stmtUpdate->bindParam(':producto_id', $productoId);
            $stmtUpdate->execute();

            // Obtener stock actual del almacén antes de devolver
            $queryStockAlmacen = "SELECT stock_actual FROM productos WHERE id = :producto_id";
            $stmtStockAlmacen = $conn->prepare($queryStockAlmacen);
            $stmtStockAlmacen->bindParam(':producto_id', $productoId);
            $stmtStockAlmacen->execute();
            $stockActualAlmacen = $stmtStockAlmacen->fetchColumn();

            // Devolver al almacén
            $queryAlmacen = "UPDATE productos
                           SET stock_actual = stock_actual + :cantidad, updated_at = NOW()
                           WHERE id = :producto_id";
            $stmtAlmacen = $conn->prepare($queryAlmacen);
            $stmtAlmacen->bindParam(':cantidad', $cantidad);
            $stmtAlmacen->bindParam(':producto_id', $productoId);
            $stmtAlmacen->execute();

            // Obtener información del repartidor para el motivo
            $queryRepartidor = "SELECT nombre, apellidos FROM repartidores WHERE id = :repartidor_id";
            $stmtRepartidor = $conn->prepare($queryRepartidor);
            $stmtRepartidor->bindParam(':repartidor_id', $repartidorId);
            $stmtRepartidor->execute();
            $repartidor = $stmtRepartidor->fetch(PDO::FETCH_ASSOC);
            $nombreRepartidor = $repartidor['nombre'] . ' ' . $repartidor['apellidos'];

            // Registrar movimiento en tabla de repartidor
            $queryMovimiento = "INSERT INTO movimientos_inventario_repartidor
                              (repartidor_id, producto_id, tipo_movimiento, cantidad, notas, created_at)
                              VALUES (:repartidor_id, :producto_id, 'retiro', :cantidad, :notas, NOW())";
            $stmtMovimiento = $conn->prepare($queryMovimiento);
            $stmtMovimiento->bindParam(':repartidor_id', $repartidorId);
            $stmtMovimiento->bindParam(':producto_id', $productoId);
            $stmtMovimiento->bindParam(':cantidad', $cantidad);
            $stmtMovimiento->bindParam(':notas', $notas);
            $stmtMovimiento->execute();

            // Registrar movimiento en tabla general de stock (movimientos_stock)
            // ID 8 = "Transferencia entrada" (motivo de entrada para devolución de repartidor)
            $motivoId = 8;
            $motivoTexto = "Devolución de repartidor: $nombreRepartidor";
            if (!empty($notas)) {
                $motivoTexto .= " - $notas";
            }

            $queryMovimientoStock = "INSERT INTO movimientos_stock
                                    (producto_id, tipo_movimiento, cantidad, stock_anterior, stock_nuevo, motivo, motivo_id, usuario_id, created_at)
                                    VALUES (:producto_id, 'entrada', :cantidad, :stock_anterior, :stock_nuevo, :motivo, :motivo_id, :usuario_id, NOW())";
            $stmtMovimientoStock = $conn->prepare($queryMovimientoStock);
            $stmtMovimientoStock->bindParam(':producto_id', $productoId);
            $stmtMovimientoStock->bindParam(':cantidad', $cantidad);
            $stmtMovimientoStock->bindParam(':stock_anterior', $stockActualAlmacen);
            $nuevoStockAlmacen = $stockActualAlmacen + $cantidad;
            $stmtMovimientoStock->bindParam(':stock_nuevo', $nuevoStockAlmacen);
            $stmtMovimientoStock->bindParam(':motivo', $motivoTexto);
            $stmtMovimientoStock->bindParam(':motivo_id', $motivoId);
            $stmtMovimientoStock->bindParam(':usuario_id', $usuarioId);
            $stmtMovimientoStock->execute();
        }

        $conn->commit();
        sendResponse(true, "Productos retirados exitosamente");
    } catch (Exception $e) {
        if ($conn->inTransaction()) {
            $conn->rollBack();
        }
        error_log("Error retirando productos: " . $e->getMessage());
        sendResponse(false, "Error retirando productos: " . $e->getMessage());
    }
}

// === AJUSTAR INVENTARIO DE REPARTIDOR ===
if ($tipo === 'ajustarInventarioRepartidor') {
    $repartidorId = isset($datapost['repartidor_id']) ? (int)$datapost['repartidor_id'] : 0;
    $productoId = isset($datapost['producto_id']) ? (int)$datapost['producto_id'] : 0;
    $cantidad = isset($datapost['cantidad']) ? (float)$datapost['cantidad'] : 0;
    $tipoAjuste = isset($datapost['tipo_ajuste']) ? $datapost['tipo_ajuste'] : '';
    $notas = isset($datapost['notas']) ? $datapost['notas'] : '';

    if ($repartidorId <= 0 || $productoId <= 0) {
        sendResponse(false, "ID de repartidor y producto requeridos");
    }

    // Permitir cantidad 0 solo para tipo 'vaciar'
    if ($cantidad <= 0 && $tipoAjuste !== 'vaciar') {
        sendResponse(false, "Cantidad debe ser mayor a 0");
    }

    if (!in_array($tipoAjuste, ['incremento', 'decremento', 'perdida', 'daño', 'vaciar'])) {
        sendResponse(false, "Tipo de ajuste inválido");
    }

    try {
        $conn->beginTransaction();

        // Obtener cantidad actual
        $queryCheck = "SELECT cantidad FROM inventarios_repartidor
                      WHERE repartidor_id = :repartidor_id AND producto_id = :producto_id";
        $stmtCheck = $conn->prepare($queryCheck);
        $stmtCheck->bindParam(':repartidor_id', $repartidorId);
        $stmtCheck->bindParam(':producto_id', $productoId);
        $stmtCheck->execute();
        $cantidadActual = $stmtCheck->fetchColumn();

        if ($cantidadActual === false) {
            throw new Exception("Producto no encontrado en inventario del repartidor");
        }

        // Calcular nueva cantidad
        $nuevaCantidad = $cantidadActual;
        if ($tipoAjuste === 'vaciar') {
            // Vaciar completamente el inventario
            $cantidad = $cantidadActual; // Guardar la cantidad que se va a vaciar para el registro
            $nuevaCantidad = 0;
        } else if ($tipoAjuste === 'incremento') {
            $nuevaCantidad += $cantidad;
        } else {
            // decremento, perdida, daño
            $nuevaCantidad -= $cantidad;
            if ($nuevaCantidad < 0) {
                throw new Exception("El ajuste resultaría en cantidad negativa");
            }
        }

        // Actualizar inventario del repartidor
        $queryUpdate = "UPDATE inventarios_repartidor
                      SET cantidad = :cantidad, updated_at = NOW()
                      WHERE repartidor_id = :repartidor_id AND producto_id = :producto_id";
        $stmtUpdate = $conn->prepare($queryUpdate);
        $stmtUpdate->bindParam(':cantidad', $nuevaCantidad);
        $stmtUpdate->bindParam(':repartidor_id', $repartidorId);
        $stmtUpdate->bindParam(':producto_id', $productoId);
        $stmtUpdate->execute();

        // Registrar movimiento
        $tipoMovimiento = 'ajuste_' . $tipoAjuste;
        if ($tipoAjuste === 'perdida' || $tipoAjuste === 'daño') {
            $tipoMovimiento = $tipoAjuste;
        }

        $queryMovimiento = "INSERT INTO movimientos_inventario_repartidor
                          (repartidor_id, producto_id, tipo_movimiento, cantidad, notas, created_at)
                          VALUES (:repartidor_id, :producto_id, :tipo_movimiento, :cantidad, :notas, NOW())";
        $stmtMovimiento = $conn->prepare($queryMovimiento);
        $stmtMovimiento->bindParam(':repartidor_id', $repartidorId);
        $stmtMovimiento->bindParam(':producto_id', $productoId);
        $stmtMovimiento->bindParam(':tipo_movimiento', $tipoMovimiento);
        $stmtMovimiento->bindParam(':cantidad', $cantidad);
        $stmtMovimiento->bindParam(':notas', $notas);
        $stmtMovimiento->execute();

        $conn->commit();
        sendResponse(true, "Inventario ajustado exitosamente");
    } catch (Exception $e) {
        if ($conn->inTransaction()) {
            $conn->rollBack();
        }
        error_log("Error ajustando inventario: " . $e->getMessage());
        sendResponse(false, "Error ajustando inventario: " . $e->getMessage());
    }
}

// === OBTENER HISTORIAL DE MOVIMIENTOS ===
if ($tipo === 'getHistorialMovimientosRepartidor') {
    $repartidorId = isset($datapost['repartidor_id']) ? (int)$datapost['repartidor_id'] : 0;
    $limit = isset($datapost['limit']) ? (int)$datapost['limit'] : 100;

    if ($repartidorId <= 0) {
        sendResponse(false, "ID de repartidor requerido");
    }

    try {
        $query = "SELECT
                    mir.id,
                    mir.repartidor_id,
                    mir.producto_id,
                    mir.tipo_movimiento as tipo,
                    mir.cantidad,
                    mir.notas,
                    mir.created_at as fecha,
                    p.nombre as producto_nombre,
                    p.codigo as producto_codigo,
                    p.unidad_medida
                FROM movimientos_inventario_repartidor mir
                INNER JOIN productos p ON mir.producto_id = p.id
                WHERE mir.repartidor_id = :repartidor_id
                ORDER BY mir.created_at DESC
                LIMIT :limit";

        $stmt = $conn->prepare($query);
        $stmt->bindParam(':repartidor_id', $repartidorId);
        $stmt->bindParam(':limit', $limit, PDO::PARAM_INT);
        $stmt->execute();

        $historial = $stmt->fetchAll(PDO::FETCH_ASSOC);

        sendResponse(true, "Historial obtenido exitosamente", $historial);
    } catch (Exception $e) {
        error_log("Error obteniendo historial: " . $e->getMessage());
        sendResponse(false, "Error obteniendo historial: " . $e->getMessage());
    }
}

// === OBTENER ESTADÍSTICAS ===
if ($tipo === 'getEstadisticasInventariosRepartidores') {
    try {
        // Total de repartidores
        $queryRepartidores = "SELECT COUNT(*) FROM repartidores";
        $stmtRepartidores = $conn->prepare($queryRepartidores);
        $stmtRepartidores->execute();
        $totalRepartidores = $stmtRepartidores->fetchColumn();

        // Total de productos en campo (sumando todos los inventarios)
        $queryProductosCampo = "SELECT SUM(cantidad) FROM inventarios_repartidor WHERE cantidad > 0";
        $stmtProductosCampo = $conn->prepare($queryProductosCampo);
        $stmtProductosCampo->execute();
        $totalProductosCampo = $stmtProductosCampo->fetchColumn() ?: 0;

        // Valor total de inventarios
        $queryValorTotal = "SELECT SUM(ir.cantidad * p.precio)
                           FROM inventarios_repartidor ir
                           INNER JOIN productos p ON ir.producto_id = p.id
                           WHERE ir.cantidad > 0";
        $stmtValorTotal = $conn->prepare($queryValorTotal);
        $stmtValorTotal->execute();
        $valorTotal = $stmtValorTotal->fetchColumn() ?: 0;

        $estadisticas = [
            'total_repartidores' => (int)$totalRepartidores,
            'total_productos_campo' => (float)$totalProductosCampo,
            'valor_total_inventarios' => (float)$valorTotal
        ];

        sendResponse(true, "Estadísticas obtenidas exitosamente", $estadisticas);
    } catch (Exception $e) {
        error_log("Error obteniendo estadísticas: " . $e->getMessage());
        sendResponse(false, "Error obteniendo estadísticas: " . $e->getMessage());
    }
}

// === TRANSFERIR PRODUCTOS ENTRE REPARTIDORES ===
if ($tipo === 'transferirProductosEntreRepartidores') {
    $repartidorOrigenId = isset($datapost['repartidor_origen_id']) ? (int)$datapost['repartidor_origen_id'] : 0;
    $repartidorDestinoId = isset($datapost['repartidor_destino_id']) ? (int)$datapost['repartidor_destino_id'] : 0;
    $productos = isset($datapost['productos']) ? $datapost['productos'] : [];
    $notas = isset($datapost['notas']) ? $datapost['notas'] : '';

    if ($repartidorOrigenId <= 0 || $repartidorDestinoId <= 0) {
        sendResponse(false, "IDs de repartidores origen y destino requeridos");
    }

    if ($repartidorOrigenId === $repartidorDestinoId) {
        sendResponse(false, "Los repartidores origen y destino no pueden ser el mismo");
    }

    if (empty($productos)) {
        sendResponse(false, "Debe incluir al menos un producto");
    }

    try {
        $conn->beginTransaction();

        foreach ($productos as $producto) {
            $productoId = (int)$producto['producto_id'];
            $cantidad = (float)$producto['cantidad'];

            if ($cantidad <= 0) continue;

            // Verificar cantidad disponible en origen
            $queryCheck = "SELECT cantidad FROM inventarios_repartidor
                          WHERE repartidor_id = :repartidor_id AND producto_id = :producto_id";
            $stmtCheck = $conn->prepare($queryCheck);
            $stmtCheck->bindParam(':repartidor_id', $repartidorOrigenId);
            $stmtCheck->bindParam(':producto_id', $productoId);
            $stmtCheck->execute();
            $cantidadOrigen = $stmtCheck->fetchColumn();

            if ($cantidadOrigen === false || $cantidadOrigen < $cantidad) {
                throw new Exception("Cantidad insuficiente en origen para producto ID: $productoId");
            }

            // Restar del origen
            $nuevaCantidadOrigen = $cantidadOrigen - $cantidad;
            $queryUpdateOrigen = "UPDATE inventarios_repartidor
                                 SET cantidad = :cantidad, updated_at = NOW()
                                 WHERE repartidor_id = :repartidor_id AND producto_id = :producto_id";
            $stmtUpdateOrigen = $conn->prepare($queryUpdateOrigen);
            $stmtUpdateOrigen->bindParam(':cantidad', $nuevaCantidadOrigen);
            $stmtUpdateOrigen->bindParam(':repartidor_id', $repartidorOrigenId);
            $stmtUpdateOrigen->bindParam(':producto_id', $productoId);
            $stmtUpdateOrigen->execute();

            // Sumar al destino
            $queryCheckDestino = "SELECT cantidad FROM inventarios_repartidor
                                 WHERE repartidor_id = :repartidor_id AND producto_id = :producto_id";
            $stmtCheckDestino = $conn->prepare($queryCheckDestino);
            $stmtCheckDestino->bindParam(':repartidor_id', $repartidorDestinoId);
            $stmtCheckDestino->bindParam(':producto_id', $productoId);
            $stmtCheckDestino->execute();
            $cantidadDestino = $stmtCheckDestino->fetchColumn();

            if ($cantidadDestino !== false) {
                // Actualizar existente
                $nuevaCantidadDestino = $cantidadDestino + $cantidad;
                $queryUpdateDestino = "UPDATE inventarios_repartidor
                                      SET cantidad = :cantidad, updated_at = NOW()
                                      WHERE repartidor_id = :repartidor_id AND producto_id = :producto_id";
                $stmtUpdateDestino = $conn->prepare($queryUpdateDestino);
                $stmtUpdateDestino->bindParam(':cantidad', $nuevaCantidadDestino);
                $stmtUpdateDestino->bindParam(':repartidor_id', $repartidorDestinoId);
                $stmtUpdateDestino->bindParam(':producto_id', $productoId);
                $stmtUpdateDestino->execute();
            } else {
                // Crear nuevo
                $queryInsertDestino = "INSERT INTO inventarios_repartidor
                                      (repartidor_id, producto_id, cantidad, fecha_asignacion, created_at, updated_at)
                                      VALUES (:repartidor_id, :producto_id, :cantidad, NOW(), NOW(), NOW())";
                $stmtInsertDestino = $conn->prepare($queryInsertDestino);
                $stmtInsertDestino->bindParam(':repartidor_id', $repartidorDestinoId);
                $stmtInsertDestino->bindParam(':producto_id', $productoId);
                $stmtInsertDestino->bindParam(':cantidad', $cantidad);
                $stmtInsertDestino->execute();
            }

            // Registrar movimientos
            $queryMovimientoSalida = "INSERT INTO movimientos_inventario_repartidor
                                     (repartidor_id, producto_id, tipo_movimiento, cantidad, notas, created_at)
                                     VALUES (:repartidor_id, :producto_id, 'transferencia_salida', :cantidad, :notas, NOW())";
            $stmtMovimientoSalida = $conn->prepare($queryMovimientoSalida);
            $stmtMovimientoSalida->bindParam(':repartidor_id', $repartidorOrigenId);
            $stmtMovimientoSalida->bindParam(':producto_id', $productoId);
            $stmtMovimientoSalida->bindParam(':cantidad', $cantidad);
            $stmtMovimientoSalida->bindParam(':notas', $notas);
            $stmtMovimientoSalida->execute();

            $queryMovimientoEntrada = "INSERT INTO movimientos_inventario_repartidor
                                      (repartidor_id, producto_id, tipo_movimiento, cantidad, notas, created_at)
                                      VALUES (:repartidor_id, :producto_id, 'transferencia_entrada', :cantidad, :notas, NOW())";
            $stmtMovimientoEntrada = $conn->prepare($queryMovimientoEntrada);
            $stmtMovimientoEntrada->bindParam(':repartidor_id', $repartidorDestinoId);
            $stmtMovimientoEntrada->bindParam(':producto_id', $productoId);
            $stmtMovimientoEntrada->bindParam(':cantidad', $cantidad);
            $stmtMovimientoEntrada->bindParam(':notas', $notas);
            $stmtMovimientoEntrada->execute();
        }

        $conn->commit();
        sendResponse(true, "Productos transferidos exitosamente");
    } catch (Exception $e) {
        if ($conn->inTransaction()) {
            $conn->rollBack();
        }
        error_log("Error transfiriendo productos: " . $e->getMessage());
        sendResponse(false, "Error transfiriendo productos: " . $e->getMessage());
    }
}
