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

$user = requireAuth();

switch ($tipo) {
    case 'getProductos':
        try {
            $page = max(1, intval($datapost['page'] ?? $_GET['page'] ?? 1));
            $limit = max(1, min(100, intval($datapost['limit'] ?? $_GET['limit'] ?? 20)));
            $offset = ($page - 1) * $limit;

            // Filtros opcionales
            $q = trim($datapost['q'] ?? $_GET['q'] ?? '');
            $categoria_id = intval($datapost['categoria_id'] ?? $_GET['categoria_id'] ?? 0);
            $almacen_id = intval($datapost['almacen_id'] ?? $_GET['almacen_id'] ?? 0);
            $con_stock = isset($datapost['con_stock']) ? intval($datapost['con_stock']) : (isset($_GET['con_stock']) ? intval($_GET['con_stock']) : -1);

            $where = "WHERE p.activo = 1";
            $params = [];
            $types = "";

            if (!empty($q)) {
                $where .= " AND (p.nombre LIKE ? OR p.codigo_corto LIKE ? OR p.codigo_barras LIKE ?)";
                $searchTerm = "%{$q}%";
                $params[] = $searchTerm;
                $params[] = $searchTerm;
                $params[] = $searchTerm;
                $types .= "sss";
            }

            if ($categoria_id > 0) {
                $where .= " AND p.categoria_id = ?";
                $params[] = $categoria_id;
                $types .= "i";
            }

            if ($almacen_id > 0) {
                $where .= " AND p.almacen_id = ?";
                $params[] = $almacen_id;
                $types .= "i";
            }

            if ($con_stock === 1) {
                $where .= " AND p.stock > 0";
            } elseif ($con_stock === 0) {
                $where .= " AND p.stock <= 0";
            }

            // Contar total
            $countQuery = "SELECT COUNT(*) as total FROM productos p $where";
            $countStmt = $conn->prepare($countQuery);
            if (!empty($params)) {
                $countStmt->bind_param($types, ...$params);
            }
            $countStmt->execute();
            $total = $countStmt->get_result()->fetch_assoc()['total'];

            // Obtener productos paginados
            $query = "SELECT
                p.id,
                p.nombre,
                p.descripcion,
                p.codigo_corto,
                p.codigo_barras,
                p.categoria_id,
                c.nombre as categoria_nombre,
                p.almacen_id,
                a.nombre as almacen_nombre,
                p.precio_compra,
                p.precio_lista,
                p.precio1,
                p.precio2,
                p.precio3,
                p.precio4,
                p.precio5,
                p.precio6,
                p.stock,
                p.stock_minimo,
                p.unidad_medida,
                p.activo
            FROM productos p
            LEFT JOIN categorias c ON p.categoria_id = c.id
            LEFT JOIN almacenes a ON p.almacen_id = a.id
            $where
            ORDER BY p.nombre ASC
            LIMIT ? OFFSET ?";

            $params[] = $limit;
            $params[] = $offset;
            $types .= "ii";

            $stmt = $conn->prepare($query);
            $stmt->bind_param($types, ...$params);
            $stmt->execute();
            $result = $stmt->get_result();

            $productos = [];
            while ($row = $result->fetch_assoc()) {
                $productos[] = [
                    'id' => intval($row['id']),
                    'nombre' => $row['nombre'],
                    'descripcion' => $row['descripcion'],
                    'codigo_corto' => $row['codigo_corto'],
                    'codigo_barras' => $row['codigo_barras'],
                    'categoria_id' => $row['categoria_id'] ? intval($row['categoria_id']) : null,
                    'categoria_nombre' => $row['categoria_nombre'],
                    'almacen_id' => $row['almacen_id'] ? intval($row['almacen_id']) : null,
                    'almacen_nombre' => $row['almacen_nombre'],
                    'precio_compra' => floatval($row['precio_compra']),
                    'precio_lista' => floatval($row['precio_lista']),
                    'precio1' => floatval($row['precio1']),
                    'precio2' => floatval($row['precio2']),
                    'precio3' => floatval($row['precio3']),
                    'precio4' => floatval($row['precio4']),
                    'precio5' => floatval($row['precio5']),
                    'precio6' => floatval($row['precio6']),
                    'stock' => floatval($row['stock']),
                    'stock_minimo' => floatval($row['stock_minimo']),
                    'unidad_medida' => $row['unidad_medida'],
                    'estado_stock' => getEstadoStock($row['stock'], $row['stock_minimo'])
                ];
            }

            sendPaginatedResponse(true, "Productos obtenidos", $productos, $total, $page, $limit);
        } catch (Exception $e) {
            sendResponse(false, "Error al obtener productos: " . $e->getMessage());
        }
        break;

    case 'getProducto':
        $id = intval($datapost['id'] ?? $_GET['id'] ?? 0);

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

        try {
            $query = "SELECT
                p.id,
                p.nombre,
                p.descripcion,
                p.codigo_corto,
                p.codigo_barras,
                p.cve_cfdi,
                p.objeto_imp,
                p.tipo_factor_iva,
                p.tasa_iva,
                p.categoria_id,
                c.nombre as categoria_nombre,
                p.almacen_id,
                a.nombre as almacen_nombre,
                p.precio_compra,
                p.costo_precios,
                p.precio_lista,
                p.precio1,
                p.precio2,
                p.precio3,
                p.precio4,
                p.precio5,
                p.precio6,
                p.stock,
                p.stock_minimo,
                p.unidad_medida,
                p.activo,
                p.fecha_creacion,
                p.fecha_actualizacion
            FROM productos p
            LEFT JOIN categorias c ON p.categoria_id = c.id
            LEFT JOIN almacenes a ON p.almacen_id = a.id
            WHERE p.id = ?";

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

            if ($row = $result->fetch_assoc()) {
                // Obtener equivalencias
                $equivQuery = "SELECT pe.id, pe.producto_equivalente_id, pe.cantidad_equivalente,
                               p2.nombre as producto_equivalente_nombre, p2.codigo_corto as producto_equivalente_codigo
                               FROM producto_equivalencias pe
                               JOIN productos p2 ON pe.producto_equivalente_id = p2.id
                               WHERE pe.producto_id = ? AND pe.activo = 1";
                $equivStmt = $conn->prepare($equivQuery);
                $equivStmt->bind_param("i", $id);
                $equivStmt->execute();
                $equivResult = $equivStmt->get_result();

                $equivalencias = [];
                while ($eq = $equivResult->fetch_assoc()) {
                    $equivalencias[] = [
                        'id' => intval($eq['id']),
                        'producto_equivalente_id' => intval($eq['producto_equivalente_id']),
                        'producto_equivalente_nombre' => $eq['producto_equivalente_nombre'],
                        'producto_equivalente_codigo' => $eq['producto_equivalente_codigo'],
                        'cantidad_equivalente' => floatval($eq['cantidad_equivalente'])
                    ];
                }

                // Obtener descuentos por volumen
                $descVolQuery = "SELECT id, cantidad_minima, cantidad_maxima, descuento_porcentaje, precio_especial
                                FROM descuentos_volumen
                                WHERE producto_id = ? AND activo = 1
                                ORDER BY cantidad_minima ASC";
                $descVolStmt = $conn->prepare($descVolQuery);
                $descVolStmt->bind_param("i", $id);
                $descVolStmt->execute();
                $descVolResult = $descVolStmt->get_result();

                $descuentos_volumen = [];
                while ($dv = $descVolResult->fetch_assoc()) {
                    $descuentos_volumen[] = [
                        'id' => intval($dv['id']),
                        'cantidad_minima' => floatval($dv['cantidad_minima']),
                        'cantidad_maxima' => $dv['cantidad_maxima'] ? floatval($dv['cantidad_maxima']) : null,
                        'descuento_porcentaje' => floatval($dv['descuento_porcentaje']),
                        'precio_especial' => $dv['precio_especial'] ? floatval($dv['precio_especial']) : null
                    ];
                }

                $producto = [
                    'id' => intval($row['id']),
                    'nombre' => $row['nombre'],
                    'descripcion' => $row['descripcion'],
                    'codigo_corto' => $row['codigo_corto'],
                    'codigo_barras' => $row['codigo_barras'],
                    'cve_cfdi' => $row['cve_cfdi'],
                    'objeto_imp' => $row['objeto_imp'],
                    'tipo_factor_iva' => $row['tipo_factor_iva'],
                    'tasa_iva' => floatval($row['tasa_iva']),
                    'categoria_id' => $row['categoria_id'] ? intval($row['categoria_id']) : null,
                    'categoria_nombre' => $row['categoria_nombre'],
                    'almacen_id' => $row['almacen_id'] ? intval($row['almacen_id']) : null,
                    'almacen_nombre' => $row['almacen_nombre'],
                    'precio_compra' => floatval($row['precio_compra']),
                    'costo_precios' => floatval($row['costo_precios']),
                    'precio_lista' => floatval($row['precio_lista']),
                    'precio1' => floatval($row['precio1']),
                    'precio2' => floatval($row['precio2']),
                    'precio3' => floatval($row['precio3']),
                    'precio4' => floatval($row['precio4']),
                    'precio5' => floatval($row['precio5']),
                    'precio6' => floatval($row['precio6']),
                    'stock' => floatval($row['stock']),
                    'stock_minimo' => floatval($row['stock_minimo']),
                    'unidad_medida' => $row['unidad_medida'],
                    'activo' => intval($row['activo']),
                    'estado_stock' => getEstadoStock($row['stock'], $row['stock_minimo']),
                    'equivalencias' => $equivalencias,
                    'descuentos_volumen' => $descuentos_volumen,
                    'fecha_creacion' => $row['fecha_creacion'],
                    'fecha_actualizacion' => $row['fecha_actualizacion']
                ];

                sendResponse(true, "Producto obtenido exitosamente", $producto);
            } else {
                sendResponse(false, "Producto no encontrado");
            }
        } catch (Exception $e) {
            sendResponse(false, "Error al obtener producto: " . $e->getMessage());
        }
        break;

    case 'buscarProductos':
        $q = trim($datapost['q'] ?? $_GET['q'] ?? '');

        if (empty($q)) {
            sendResponse(false, "Término de búsqueda requerido");
        }

        try {
            // Búsqueda rápida: primero por código exacto, luego por nombre
            $query = "SELECT
                p.id,
                p.nombre,
                p.codigo_corto,
                p.codigo_barras,
                p.categoria_id,
                c.nombre as categoria_nombre,
                p.almacen_id,
                a.nombre as almacen_nombre,
                p.precio_lista,
                p.precio1,
                p.precio2,
                p.precio3,
                p.precio4,
                p.precio5,
                p.precio6,
                p.stock,
                p.unidad_medida
            FROM productos p
            LEFT JOIN categorias c ON p.categoria_id = c.id
            LEFT JOIN almacenes a ON p.almacen_id = a.id
            WHERE p.activo = 1 AND (
                p.codigo_barras = ? OR
                p.codigo_corto = ? OR
                p.nombre LIKE ? OR
                p.codigo_barras LIKE ?
            )
            ORDER BY
                CASE
                    WHEN p.codigo_barras = ? THEN 1
                    WHEN p.codigo_corto = ? THEN 2
                    ELSE 3
                END,
                p.nombre ASC
            LIMIT 50";

            $searchTerm = "%{$q}%";
            $stmt = $conn->prepare($query);
            $stmt->bind_param("ssssss", $q, $q, $searchTerm, $searchTerm, $q, $q);
            $stmt->execute();
            $result = $stmt->get_result();

            $productos = [];
            while ($row = $result->fetch_assoc()) {
                $productos[] = [
                    'id' => intval($row['id']),
                    'nombre' => $row['nombre'],
                    'codigo_corto' => $row['codigo_corto'],
                    'codigo_barras' => $row['codigo_barras'],
                    'categoria_id' => $row['categoria_id'] ? intval($row['categoria_id']) : null,
                    'categoria_nombre' => $row['categoria_nombre'],
                    'almacen_id' => $row['almacen_id'] ? intval($row['almacen_id']) : null,
                    'almacen_nombre' => $row['almacen_nombre'],
                    'precio_lista' => floatval($row['precio_lista']),
                    'precio1' => floatval($row['precio1']),
                    'precio2' => floatval($row['precio2']),
                    'precio3' => floatval($row['precio3']),
                    'precio4' => floatval($row['precio4']),
                    'precio5' => floatval($row['precio5']),
                    'precio6' => floatval($row['precio6']),
                    'stock' => floatval($row['stock']),
                    'unidad_medida' => $row['unidad_medida']
                ];
            }

            sendResponse(true, "Búsqueda completada", $productos);
        } catch (Exception $e) {
            sendResponse(false, "Error al buscar productos: " . $e->getMessage());
        }
        break;

    case 'getCategorias':
        try {
            $query = "SELECT
                c.id,
                c.nombre,
                COUNT(p.id) as productos_count
            FROM categorias c
            LEFT JOIN productos p ON c.id = p.categoria_id AND p.activo = 1
            WHERE c.activo = 1
            GROUP BY c.id, c.nombre
            ORDER BY c.nombre ASC";

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

            while ($row = $result->fetch_assoc()) {
                $categorias[] = [
                    'id' => intval($row['id']),
                    'nombre' => $row['nombre'],
                    'productos_count' => intval($row['productos_count'])
                ];
            }

            sendResponse(true, "Categorías obtenidas", $categorias);
        } catch (Exception $e) {
            sendResponse(false, "Error al obtener categorías: " . $e->getMessage());
        }
        break;

    case 'getAlmacenes':
        try {
            // Retornar almacenes asignados al usuario
            $query = "SELECT a.id, a.nombre, a.codigo
                     FROM usuario_almacenes ua
                     JOIN almacenes a ON ua.almacen_id = a.id
                     WHERE ua.usuario_id = ? AND a.activo = 1
                     ORDER BY a.nombre ASC";

            $stmt = $conn->prepare($query);
            $stmt->bind_param("i", $user['id']);
            $stmt->execute();
            $result = $stmt->get_result();

            $almacenes = [];
            while ($row = $result->fetch_assoc()) {
                $almacenes[] = [
                    'id' => intval($row['id']),
                    'nombre' => $row['nombre'],
                    'codigo' => $row['codigo']
                ];
            }

            sendResponse(true, "Almacenes obtenidos", $almacenes);
        } catch (Exception $e) {
            sendResponse(false, "Error al obtener almacenes: " . $e->getMessage());
        }
        break;

    case 'getInventarioAlmacen':
        $almacen_id = intval($datapost['almacen_id'] ?? $_GET['almacen_id'] ?? 0);

        if ($almacen_id <= 0) {
            sendResponse(false, "ID de almacén requerido");
        }

        try {
            $page = max(1, intval($datapost['page'] ?? $_GET['page'] ?? 1));
            $limit = max(1, min(100, intval($datapost['limit'] ?? $_GET['limit'] ?? 20)));
            $offset = ($page - 1) * $limit;

            $countQuery = "SELECT COUNT(*) as total FROM productos WHERE almacen_id = ? AND activo = 1";
            $countStmt = $conn->prepare($countQuery);
            $countStmt->bind_param("i", $almacen_id);
            $countStmt->execute();
            $total = $countStmt->get_result()->fetch_assoc()['total'];

            $query = "SELECT
                p.id,
                p.nombre,
                p.codigo_corto,
                p.codigo_barras,
                p.stock,
                p.stock_minimo,
                p.unidad_medida,
                p.precio1
            FROM productos p
            WHERE p.almacen_id = ? AND p.activo = 1
            ORDER BY p.nombre ASC
            LIMIT ? OFFSET ?";

            $stmt = $conn->prepare($query);
            $stmt->bind_param("iii", $almacen_id, $limit, $offset);
            $stmt->execute();
            $result = $stmt->get_result();

            $productos = [];
            while ($row = $result->fetch_assoc()) {
                $productos[] = [
                    'id' => intval($row['id']),
                    'nombre' => $row['nombre'],
                    'codigo_corto' => $row['codigo_corto'],
                    'codigo_barras' => $row['codigo_barras'],
                    'stock' => floatval($row['stock']),
                    'stock_minimo' => floatval($row['stock_minimo']),
                    'unidad_medida' => $row['unidad_medida'],
                    'precio1' => floatval($row['precio1']),
                    'estado_stock' => getEstadoStock($row['stock'], $row['stock_minimo'])
                ];
            }

            sendPaginatedResponse(true, "Inventario obtenido", $productos, $total, $page, $limit);
        } catch (Exception $e) {
            sendResponse(false, "Error al obtener inventario: " . $e->getMessage());
        }
        break;

    case 'getPreciosProducto':
        $producto_id = intval($datapost['producto_id'] ?? $_GET['producto_id'] ?? 0);

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

        try {
            $query = "SELECT precio_lista, precio1, precio2, precio3, precio4, precio5, precio6
                     FROM productos WHERE id = ? AND activo = 1";
            $stmt = $conn->prepare($query);
            $stmt->bind_param("i", $producto_id);
            $stmt->execute();
            $result = $stmt->get_result();

            if ($row = $result->fetch_assoc()) {
                // Descuentos por volumen
                $descQuery = "SELECT cantidad_minima, cantidad_maxima, descuento_porcentaje, precio_especial
                             FROM descuentos_volumen
                             WHERE producto_id = ? AND activo = 1
                             ORDER BY cantidad_minima ASC";
                $descStmt = $conn->prepare($descQuery);
                $descStmt->bind_param("i", $producto_id);
                $descStmt->execute();
                $descResult = $descStmt->get_result();

                $descuentos = [];
                while ($d = $descResult->fetch_assoc()) {
                    $descuentos[] = [
                        'cantidad_minima' => floatval($d['cantidad_minima']),
                        'cantidad_maxima' => $d['cantidad_maxima'] ? floatval($d['cantidad_maxima']) : null,
                        'descuento_porcentaje' => floatval($d['descuento_porcentaje']),
                        'precio_especial' => $d['precio_especial'] ? floatval($d['precio_especial']) : null
                    ];
                }

                sendResponse(true, "Precios obtenidos", [
                    'precio_lista' => floatval($row['precio_lista']),
                    'precio1' => floatval($row['precio1']),
                    'precio2' => floatval($row['precio2']),
                    'precio3' => floatval($row['precio3']),
                    'precio4' => floatval($row['precio4']),
                    'precio5' => floatval($row['precio5']),
                    'precio6' => floatval($row['precio6']),
                    'descuentos_volumen' => $descuentos
                ]);
            } else {
                sendResponse(false, "Producto no encontrado");
            }
        } catch (Exception $e) {
            sendResponse(false, "Error al obtener precios: " . $e->getMessage());
        }
        break;

    case 'calcularPrecio':
        $producto_id = intval($datapost['producto_id'] ?? 0);
        $cantidad = floatval($datapost['cantidad'] ?? 1);
        $nivel_precio = trim($datapost['nivel_precio'] ?? 'precio1');
        $cliente_id = intval($datapost['cliente_id'] ?? 0);

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

        try {
            // Obtener precios del producto
            $query = "SELECT precio_lista, precio1, precio2, precio3, precio4, precio5, precio6
                     FROM productos WHERE id = ? AND activo = 1";
            $stmt = $conn->prepare($query);
            $stmt->bind_param("i", $producto_id);
            $stmt->execute();
            $result = $stmt->get_result();

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

            // Determinar nivel de precio del cliente si se proporciona
            if ($cliente_id > 0) {
                $clienteQuery = "SELECT precio_venta FROM clientes WHERE id = ? AND activo = 1";
                $clienteStmt = $conn->prepare($clienteQuery);
                $clienteStmt->bind_param("i", $cliente_id);
                $clienteStmt->execute();
                $clienteResult = $clienteStmt->get_result();
                if ($clienteData = $clienteResult->fetch_assoc()) {
                    $nivel_precio = $clienteData['precio_venta'];
                }
            }

            // Obtener precio base según nivel
            $precios_validos = ['precio_lista', 'precio1', 'precio2', 'precio3', 'precio4', 'precio5', 'precio6'];
            if (!in_array($nivel_precio, $precios_validos)) {
                $nivel_precio = 'precio1';
            }
            $precio_unitario = floatval($producto[$nivel_precio]);

            // Verificar descuento por volumen
            $descQuery = "SELECT descuento_porcentaje, precio_especial
                         FROM descuentos_volumen
                         WHERE producto_id = ? AND activo = 1
                         AND cantidad_minima <= ?
                         AND (cantidad_maxima IS NULL OR cantidad_maxima >= ?)
                         ORDER BY cantidad_minima DESC
                         LIMIT 1";
            $descStmt = $conn->prepare($descQuery);
            $descStmt->bind_param("idd", $producto_id, $cantidad, $cantidad);
            $descStmt->execute();
            $descResult = $descStmt->get_result();

            $descuento_porcentaje = 0;
            $precio_final = $precio_unitario;

            if ($desc = $descResult->fetch_assoc()) {
                if ($desc['precio_especial'] && floatval($desc['precio_especial']) > 0) {
                    $precio_final = floatval($desc['precio_especial']);
                } elseif ($desc['descuento_porcentaje'] > 0) {
                    $descuento_porcentaje = floatval($desc['descuento_porcentaje']);
                    $precio_final = $precio_unitario * (1 - $descuento_porcentaje / 100);
                }
            }

            $subtotal = $precio_final * $cantidad;

            sendResponse(true, "Precio calculado", [
                'producto_id' => $producto_id,
                'cantidad' => $cantidad,
                'nivel_precio' => $nivel_precio,
                'precio_unitario' => round($precio_unitario, 2),
                'descuento_porcentaje' => $descuento_porcentaje,
                'precio_final' => round($precio_final, 2),
                'subtotal' => round($subtotal, 2)
            ]);
        } catch (Exception $e) {
            sendResponse(false, "Error al calcular precio: " . $e->getMessage());
        }
        break;

    default:
        sendResponse(false, "Operación no válida para productos");
        break;
}
