<?php
// Prevenir acceso directo
if (!defined('BASEPATH')) exit('No direct script access allowed');

switch ($tipo) {
    case 'getConfiguracionRangos':
        try {
            $query = "SELECT
                id,
                nombre,
                descripcion,
                precio_tipo,
                cantidad_minima,
                cantidad_maxima,
                porcentaje_descuento,
                activo,
                fecha_creacion,
                fecha_actualizacion
            FROM configuracion_rangos
            WHERE activo = 1
            ORDER BY precio_tipo ASC, cantidad_minima ASC";

            $result = $conn->query($query);
            $configuraciones = [];

            while ($row = $result->fetch_assoc()) {
                $configuraciones[] = [
                    'id' => intval($row['id']),
                    'nombre' => $row['nombre'],
                    'descripcion' => $row['descripcion'],
                    'precio_tipo' => $row['precio_tipo'],
                    'cantidad_minima' => floatval($row['cantidad_minima']),
                    'cantidad_maxima' => $row['cantidad_maxima'] ? floatval($row['cantidad_maxima']) : null,
                    'porcentaje_descuento' => floatval($row['porcentaje_descuento']),
                    'activo' => intval($row['activo']),
                    'fecha_creacion' => $row['fecha_creacion'],
                    'fecha_actualizacion' => $row['fecha_actualizacion']
                ];
            }

            sendResponse(true, "Configuración de rangos obtenida exitosamente", $configuraciones);

        } catch (Exception $e) {
            sendResponse(false, "Error al obtener configuración de rangos: " . $e->getMessage());
        }
        break;

    case 'actualizarConfiguracionRango':
        try {
            $id = intval($datapost['id'] ?? 0);
            $nombre = trim($datapost['nombre'] ?? '');
            $descripcion = trim($datapost['descripcion'] ?? '');
            $precio_tipo = trim($datapost['precio_tipo'] ?? '');
            $cantidad_minima = floatval($datapost['cantidad_minima'] ?? 1);
            $cantidad_maxima = isset($datapost['cantidad_maxima']) && $datapost['cantidad_maxima'] !== '' ? floatval($datapost['cantidad_maxima']) : null;
            $porcentaje_descuento = floatval($datapost['porcentaje_descuento'] ?? 0);

            if ($id <= 0) {
                sendResponse(false, "ID de configuración requerido");
            }

            if (empty($nombre)) {
                sendResponse(false, "El nombre es requerido");
            }

            if (!in_array($precio_tipo, ['precio1', 'precio2', 'precio3', 'precio4'])) {
                sendResponse(false, "Tipo de precio inválido");
            }

            if ($cantidad_minima <= 0) {
                sendResponse(false, "La cantidad mínima debe ser mayor a 0");
            }

            if ($cantidad_maxima !== null && $cantidad_maxima <= $cantidad_minima) {
                sendResponse(false, "La cantidad máxima debe ser mayor a la mínima");
            }

            $query = "UPDATE configuracion_rangos SET
                        nombre = ?,
                        descripcion = ?,
                        precio_tipo = ?,
                        cantidad_minima = ?,
                        cantidad_maxima = ?,
                        porcentaje_descuento = ?
                      WHERE id = ?";

            $stmt = $conn->prepare($query);
            $stmt->bind_param("sssdidi", $nombre, $descripcion, $precio_tipo, $cantidad_minima, $cantidad_maxima, $porcentaje_descuento, $id);

            if ($stmt->execute()) {
                sendResponse(true, "Configuración actualizada exitosamente");
            } else {
                sendResponse(false, "Error al actualizar la configuración");
            }

        } catch (Exception $e) {
            sendResponse(false, "Error al actualizar configuración: " . $e->getMessage());
        }
        break;

    case 'getPrecioPorCantidad':
        try {
            // Helper function para obtener precio con fallback
            function getPrecioConFallback($producto, $precio_preferido) {
                $precio = floatval($producto[$precio_preferido] ?? 0);

                // Si el precio preferido es 0, buscar el primer precio disponible como fallback
                if ($precio == 0) {
                    $precios_fallback = ['precio_lista', 'precio1', 'precio2', 'precio3', 'precio4', 'precio5', 'precio6'];
                    foreach ($precios_fallback as $tipo_precio) {
                        $precio_alternativo = floatval($producto[$tipo_precio] ?? 0);
                        if ($precio_alternativo > 0) {
                            return $precio_alternativo;
                        }
                    }
                }

                return $precio;
            }

            $producto_id = intval($datapost['producto_id'] ?? 0);
            $cantidad = floatval($datapost['cantidad'] ?? 1);
            $cliente_id = isset($datapost['cliente_id']) && $datapost['cliente_id'] !== '' ? intval($datapost['cliente_id']) : null;

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

            if ($cantidad <= 0) {
                sendResponse(false, "La cantidad debe ser mayor a 0");
            }

            // Obtener precio_venta del cliente si existe (por defecto precio_lista)
            $precio_preferido_cliente = 'precio_lista';
            if ($cliente_id) {
                $query_cliente = "SELECT precio_venta FROM clientes WHERE id = ? AND activo = 1";
                $stmt_cliente = $conn->prepare($query_cliente);
                $stmt_cliente->bind_param("i", $cliente_id);
                $stmt_cliente->execute();
                $result_cliente = $stmt_cliente->get_result();
                if ($cliente_data = $result_cliente->fetch_assoc()) {
                    $precio_preferido_cliente = $cliente_data['precio_venta'] ?: 'precio_lista';
                }
            }

            // Obtener información del producto
            $query_producto = "SELECT precio_compra, precio_lista, precio1, precio2, precio3, precio4, precio5, precio6, nombre
                             FROM productos WHERE id = ? AND activo = 1";
            $stmt_producto = $conn->prepare($query_producto);
            $stmt_producto->bind_param("i", $producto_id);
            $stmt_producto->execute();
            $result_producto = $stmt_producto->get_result();
            $producto = $result_producto->fetch_assoc();

            if (!$producto) {
                sendResponse(false, "Producto no encontrado");
            }

            // Buscar descuento por volumen para este producto y cantidad
            $query_descuento = "SELECT descuento_porcentaje, cantidad_minima
                               FROM descuentos_volumen
                               WHERE producto_id = ?
                               AND cantidad_minima <= ?
                               AND activo = 1
                               ORDER BY cantidad_minima DESC
                               LIMIT 1";

            $stmt_descuento = $conn->prepare($query_descuento);
            $stmt_descuento->bind_param("id", $producto_id, $cantidad);
            $stmt_descuento->execute();
            $result_descuento = $stmt_descuento->get_result();

            // Obtener el precio base según preferencia del cliente
            $precio_tipo = $precio_preferido_cliente;
            $precio_base = getPrecioConFallback($producto, $precio_preferido_cliente);

            // Si el precio preferido es 0, usar precio_lista
            if ($precio_base == 0) {
                $precio_tipo = 'precio_lista';
                $precio_base = floatval($producto['precio_lista'] ?? 0);
            }

            $porcentaje_descuento = 0;
            $origen = 'precio_base';

            // Si hay descuento por volumen, aplicarlo sobre precio_lista
            if ($descuento = $result_descuento->fetch_assoc()) {
                $precio_lista = floatval($producto['precio_lista'] ?? 0);
                if ($precio_lista > 0) {
                    $porcentaje_descuento = floatval($descuento['descuento_porcentaje']);
                    $precio_base = $precio_lista;
                    $precio_tipo = 'precio_lista';
                    $origen = 'descuento_volumen';
                }
            }

            $precio_final = $precio_base * (1 - ($porcentaje_descuento / 100));

            $response = [
                'producto_id' => $producto_id,
                'producto_nombre' => $producto['nombre'],
                'cantidad' => $cantidad,
                'precio_tipo' => $precio_tipo,
                'precio_base' => round($precio_base, 2),
                'porcentaje_descuento' => round($porcentaje_descuento, 2),
                'precio_final' => round($precio_final, 2),
                'total' => round($precio_final * $cantidad, 2),
                'origen' => $origen,
                'precio_preferido_cliente' => $precio_preferido_cliente
            ];

            sendResponse(true, "Precio calculado exitosamente", $response);

        } catch (Exception $e) {
            sendResponse(false, "Error al calcular precio: " . $e->getMessage());
        }
        break;

    case 'aplicarRangosAProducto':
        try {
            $producto_id = intval($datapost['producto_id'] ?? 0);

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

            // Verificar que el producto existe
            $query_check = "SELECT precio1 FROM productos WHERE id = ? AND activo = 1";
            $stmt_check = $conn->prepare($query_check);
            $stmt_check->bind_param("i", $producto_id);
            $stmt_check->execute();
            $result_check = $stmt_check->get_result();

            if (!$result_check->fetch_assoc()) {
                sendResponse(false, "Producto no encontrado");
            }

            // Limpiar rangos existentes del producto
            $query_delete = "DELETE FROM precio_rangos WHERE producto_id = ?";
            $stmt_delete = $conn->prepare($query_delete);
            $stmt_delete->bind_param("i", $producto_id);
            $stmt_delete->execute();

            // Obtener producto actualizado
            $stmt_check->execute();
            $producto = $stmt_check->get_result()->fetch_assoc();
            $precio_base = floatval($producto['precio1']);

            // Aplicar configuración global al producto
            $query_config = "SELECT precio_tipo, cantidad_minima, cantidad_maxima, porcentaje_descuento
                           FROM configuracion_rangos WHERE activo = 1";
            $result_config = $conn->query($query_config);

            $rangos_aplicados = [];
            while ($config = $result_config->fetch_assoc()) {
                $precio_con_descuento = $precio_base * (1 - (floatval($config['porcentaje_descuento']) / 100));

                $query_insert = "INSERT INTO precio_rangos
                               (producto_id, precio_tipo, cantidad_minima, cantidad_maxima, precio)
                               VALUES (?, ?, ?, ?, ?)";

                $stmt_insert = $conn->prepare($query_insert);
                $stmt_insert->bind_param("isddd",
                    $producto_id,
                    $config['precio_tipo'],
                    $config['cantidad_minima'],
                    $config['cantidad_maxima'],
                    $precio_con_descuento
                );

                if ($stmt_insert->execute()) {
                    $rangos_aplicados[] = [
                        'precio_tipo' => $config['precio_tipo'],
                        'cantidad_minima' => floatval($config['cantidad_minima']),
                        'cantidad_maxima' => $config['cantidad_maxima'] ? floatval($config['cantidad_maxima']) : null,
                        'precio' => round($precio_con_descuento, 2)
                    ];
                }
            }

            sendResponse(true, "Rangos aplicados exitosamente al producto", $rangos_aplicados);

        } catch (Exception $e) {
            sendResponse(false, "Error al aplicar rangos: " . $e->getMessage());
        }
        break;

    case 'guardarRangosProducto':
        try {
            $producto_id = intval($datapost['producto_id'] ?? 0);
            $rangos = $datapost['rangos'] ?? [];

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

            if (empty($rangos) || !is_array($rangos)) {
                sendResponse(false, "Configuración de rangos requerida");
            }

            // Verificar que el producto existe
            $query_check = "SELECT id FROM productos WHERE id = ? AND activo = 1";
            $stmt_check = $conn->prepare($query_check);
            $stmt_check->bind_param("i", $producto_id);
            $stmt_check->execute();
            $result_check = $stmt_check->get_result();

            if (!$result_check->fetch_assoc()) {
                sendResponse(false, "Producto no encontrado");
            }

            // Limpiar rangos existentes del producto
            $query_delete = "DELETE FROM precio_rangos WHERE producto_id = ?";
            $stmt_delete = $conn->prepare($query_delete);
            $stmt_delete->bind_param("i", $producto_id);
            $stmt_delete->execute();

            // Validar rangos secuenciales antes de insertar
            $rangos_ordenados = $rangos;
            usort($rangos_ordenados, function($a, $b) {
                $order = ['precio1' => 1, 'precio2' => 2, 'precio3' => 3, 'precio4' => 4];
                return $order[$a['precio_tipo']] - $order[$b['precio_tipo']];
            });

            for ($i = 0; $i < count($rangos_ordenados) - 1; $i++) {
                $current = $rangos_ordenados[$i];
                $next = $rangos_ordenados[$i + 1];

                $current_max = isset($current['cantidad_maxima']) && $current['cantidad_maxima'] !== '' ? floatval($current['cantidad_maxima']) : null;
                $next_min = floatval($next['cantidad_minima'] ?? 1);

                if ($current_max !== null && $next_min <= $current_max) {
                    sendResponse(false, "Error en rangos secuenciales: El mínimo de " . $next['precio_tipo'] . " ({$next_min}) debe ser mayor al máximo de " . $current['precio_tipo'] . " ({$current_max})");
                }
            }

            // Insertar nuevos rangos
            $rangos_guardados = [];
            foreach ($rangos as $rango) {
                $precio_tipo = trim($rango['precio_tipo'] ?? '');
                $cantidad_minima = floatval($rango['cantidad_minima'] ?? 1);
                $cantidad_maxima = isset($rango['cantidad_maxima']) && $rango['cantidad_maxima'] !== '' ? floatval($rango['cantidad_maxima']) : null;
                $precio_final = floatval($rango['precio_final'] ?? 0);

                // Validaciones
                if (!in_array($precio_tipo, ['precio1', 'precio2', 'precio3', 'precio4'])) {
                    sendResponse(false, "Tipo de precio inválido: " . $precio_tipo);
                }

                if ($cantidad_minima <= 0) {
                    sendResponse(false, "La cantidad mínima debe ser mayor a 0");
                }

                if ($cantidad_maxima !== null && $cantidad_maxima <= $cantidad_minima) {
                    sendResponse(false, "La cantidad máxima debe ser mayor a la mínima");
                }

                if ($precio_final < 0) {
                    sendResponse(false, "El precio final no puede ser negativo");
                }

                // Insertar rango
                $query_insert = "INSERT INTO precio_rangos
                               (producto_id, precio_tipo, cantidad_minima, cantidad_maxima, precio)
                               VALUES (?, ?, ?, ?, ?)";

                $stmt_insert = $conn->prepare($query_insert);
                $stmt_insert->bind_param("isddd",
                    $producto_id,
                    $precio_tipo,
                    $cantidad_minima,
                    $cantidad_maxima,
                    $precio_final
                );

                if ($stmt_insert->execute()) {
                    $rangos_guardados[] = [
                        'precio_tipo' => $precio_tipo,
                        'cantidad_minima' => $cantidad_minima,
                        'cantidad_maxima' => $cantidad_maxima,
                        'precio_final' => round($precio_final, 2)
                    ];
                }
            }

            sendResponse(true, "Rangos de precio guardados exitosamente", $rangos_guardados);

        } catch (Exception $e) {
            sendResponse(false, "Error al guardar rangos: " . $e->getMessage());
        }
        break;

    case 'getRangosProducto':
        try {
            $producto_id = intval($datapost['producto_id'] ?? 0);

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

            $query = "SELECT
                        precio_tipo,
                        cantidad_minima,
                        cantidad_maxima,
                        precio
                      FROM precio_rangos
                      WHERE producto_id = ?
                      ORDER BY precio_tipo ASC, cantidad_minima ASC";

            $stmt = $conn->prepare($query);
            $stmt->bind_param("i", $producto_id);
            $stmt->execute();
            $result = $stmt->get_result();

            $rangos = [];
            while ($row = $result->fetch_assoc()) {
                $rangos[] = [
                    'precio_tipo' => $row['precio_tipo'],
                    'cantidad_minima' => floatval($row['cantidad_minima']),
                    'cantidad_maxima' => $row['cantidad_maxima'] ? floatval($row['cantidad_maxima']) : null,
                    'precio_final' => floatval($row['precio'])
                ];
            }

            sendResponse(true, "Rangos del producto obtenidos exitosamente", $rangos);

        } catch (Exception $e) {
            sendResponse(false, "Error al obtener rangos del producto: " . $e->getMessage());
        }
        break;

    default:
        sendResponse(false, "Operación no válida para configuración de rangos");
        break;
}
?>