<?php

require_once 'conexion.php';

class Producto
{

    // MODELOS CREADOS PARA LA ADMINISTRACIÓN DE LA BASE DE DATOS

    public static function addVarianteProductoById($id_producto, $id_producto_padre, $id_tipo_variacion, $atributo_variacion, $valor_atributo_variacion)
    {
        $conexion = new Conexion();
        $db = $conexion->get_connection();

        $sql = "INSERT INTO producto_variacion (id_producto, id_producto_padre, id_tipo_variacion, atributo_variacion, valor_atributo_variacion) 
                VALUES (:id_producto, :id_producto_padre, :id_tipo_variacion, :atributo_variacion, :valor_atributo_variacion)";

        $stmt = $db->prepare($sql);

        $stmt->bindParam(':id_producto', $id_producto, PDO::PARAM_INT);
        $stmt->bindParam(':id_producto_padre', $id_producto_padre, PDO::PARAM_INT);
        $stmt->bindParam(':id_tipo_variacion', $id_tipo_variacion, PDO::PARAM_INT);
        $stmt->bindParam(':atributo_variacion', $atributo_variacion, PDO::PARAM_STR);
        $stmt->bindParam(':valor_atributo_variacion', $valor_atributo_variacion, PDO::PARAM_STR);

        $stmt->execute();

        $id_producto_variacion = $db->lastInsertId();

        $db = null;

        return $id_producto_variacion;
    }

    public static function updateImagenesById($id_producto, $new_imagenes)
    {
        $conexion = new Conexion();
        $db = $conexion->get_connection();

        $sql = "UPDATE producto SET imagenes = :imagenes WHERE id_producto = :id_producto";

        $stmt = $db->prepare($sql);

        $stmt->bindParam(':id_producto', $id_producto, PDO::PARAM_INT);
        $stmt->bindParam(':imagenes', $new_imagenes, PDO::PARAM_STR);

        $stmt->execute();

        $response = ($stmt->rowCount() > 0) ? true : false;

        $db = null;

        return $response;
    }

    public static function mdlUpdateProductoImagen($id_producto, $imagenes)
    {
        $conexion = new Conexion();
        $db = $conexion->get_connection();

        $sql = "UPDATE producto SET imagenes = :imagenes WHERE id_producto = :id_producto";

        $stmt = $db->prepare($sql);

        $stmt->bindParam(':id_producto', $id_producto, PDO::PARAM_INT);
        $stmt->bindParam(':imagenes', $imagenes, PDO::PARAM_STR);

        $stmt->execute();

        $response = ($stmt->rowCount() > 0) ? true : false;

        $db = null;

        return $response;
    }

    public static function updateDescripcionById($id_producto, $descripcion)
    {
        $conexion = new Conexion();
        $db = $conexion->get_connection();

        $sql = "UPDATE producto SET descripcion = :descripcion WHERE id_producto = :id_producto";

        $stmt = $db->prepare($sql);

        $stmt->bindParam(':id_producto', $id_producto, PDO::PARAM_INT);
        $stmt->bindParam(':descripcion', $descripcion, PDO::PARAM_STR);

        $stmt->execute();

        $response = ($stmt->rowCount() > 0) ? true : false;

        $db = null;

        return $response;
    }

    public static function mdlUpdateById(
        $id_producto,
        $nombre,
        $descripcion_corta,
        $id_proveedor,
        $url_video,
        $is_soporte_tecnico,
        $url_pagina,
        $meta_title,
        $meta_description,
        $id_content_dynamic_fb,
        $tiempo_garantia
    ) {
        $conexion = new Conexion();
        $db = $conexion->get_connection();

        $sql = "UPDATE producto SET 
                nombre = :nombre, 
                descripcion_corta = :descripcion_corta, 
                id_proveedor = :id_proveedor, 
                url_video = :url_video, 
                is_soporte_tecnico = :is_soporte_tecnico, 
                url_pagina = :url_pagina, 
                meta_title = :meta_title, 
                meta_description = :meta_description, 
                id_content_dynamic_fb = :id_content_dynamic_fb, 
                tiempo_garantia = :tiempo_garantia 
                WHERE id_producto = :id_producto";

        $stmt = $db->prepare($sql);

        $stmt->bindParam(':id_producto', $id_producto, PDO::PARAM_INT);
        $stmt->bindParam(':nombre', $nombre, PDO::PARAM_STR);
        $stmt->bindParam(':descripcion_corta', $descripcion_corta, PDO::PARAM_STR);
        $stmt->bindParam(':id_proveedor', $id_proveedor, PDO::PARAM_INT);
        $stmt->bindParam(':url_video', $url_video, PDO::PARAM_STR);
        $stmt->bindParam(':is_soporte_tecnico', $is_soporte_tecnico, PDO::PARAM_INT);
        $stmt->bindParam(':url_pagina', $url_pagina, PDO::PARAM_STR);
        $stmt->bindParam(':meta_title', $meta_title, PDO::PARAM_STR);
        $stmt->bindParam(':meta_description', $meta_description, PDO::PARAM_STR);
        $stmt->bindParam(':id_content_dynamic_fb', $id_content_dynamic_fb, PDO::PARAM_STR);
        $stmt->bindParam(':tiempo_garantia', $tiempo_garantia, PDO::PARAM_INT);

        $stmt->execute();

        $response = ($stmt->rowCount() > 0) ? true : false;

        $db = null;

        return $response;
    }

    public static function mdlSearchTotal($filtros, $terminoBusqueda)
    {
        $conn = new Conexion();
        $db = $conn->get_connection();

        $sqlFiltro = '';
        $sqlBusqueda = '';
        $parametrosLike = array();

        if ($filtros != NULL) {
            $numFiltros = (empty($filtros)) ? 0 : count($filtros);
            $i = 1;
            foreach ($filtros as $key => $filtro) {

                $campo = $filtro['campo'];

                if ($campo == "estado") {
                    $sqlFiltro .= "producto.activo = " . $filtro['data']['activo'];
                }

                if ($campo == "fecha_alta") {
                    $tipoBusqueda = $filtro['data']['tipoBusqueda'];
                    switch ($tipoBusqueda) {
                        case '1':
                            $sqlFiltro .= "DATE(producto.fecha_alta) = '" . $filtro['data']['fecha'] . "'";
                            break;
                        case '2':
                            $sqlFiltro .= "(producto.fecha_alta >= '" . $filtro['data']['fecha_inicial'] . "' AND producto.fecha_alta <= '" . $filtro['data']['fecha_final'] . "')";
                            break;
                        case '3':
                            $sqlFiltro .= "producto.fecha_alta > '" . $filtro['data']['fecha'] . "'";
                            break;
                        case '4':
                            $sqlFiltro .= "producto.fecha_alta >= '" . $filtro['data']['fecha'] . "'";
                            break;
                        case '5':
                            $sqlFiltro .= "producto.fecha_alta < '" . $filtro['data']['fecha'] . "'";
                            break;
                        case '6':
                            $sqlFiltro .= "producto.fecha_alta <= '" . $filtro['data']['fecha'] . "'";
                            break;
                    }
                }

                if ($campo == "precio") {
                    $tipoBusqueda = $filtro['data']['tipoBusqueda'];
                    switch ($tipoBusqueda) {
                        case '1':
                            $sqlFiltro .= "precio.precio = " . $filtro['data']['precio'];
                            break;
                        case '2':
                            $sqlFiltro .= "(precio.precio >= " . $filtro['data']['precio_inicial'] . " AND precio.precio <= " . $filtro['data']['precio_final'] . ")";
                            break;
                        case '3':
                            $sqlFiltro .= "precio.precio > " . $filtro['data']['precio'];
                            break;
                        case '4':
                            $sqlFiltro .= "precio.precio < " . $filtro['data']['precio'];
                            break;
                    }
                }

                if ($campo == "id_proveedor") {
                    $sqlFiltro .= "producto.id_proveedor = " . $filtro['data']['id_proveedor'];
                }

                if ($campo == "id_categoria") {
                    $sqlFiltro .= "categoria.id_categoria = " . $filtro['data']['id_categoria'];
                }

                if ($campo == "proveedor") {
                    $sqlFiltro .= "producto.id_proveedor = " . $filtro['data']['id_proveedor'];
                }

                if ($campo == "categoria") {
                    $sqlFiltro .= "categoria.id_categoria = " . $filtro['data']['id_categoria'];
                }

                if ($numFiltros > 1) {
                    if ($i == $numFiltros) {
                        $sqlFiltro .= "";
                    } else {
                        $sqlFiltro .= " AND ";
                    }
                }

                $i++;
            }
        }

        if ($terminoBusqueda != NULL) {
            $sqlBusqueda .= "(producto.nombre LIKE ? OR producto.sku LIKE ?)";
            array_push(
                $parametrosLike,
                "%$terminoBusqueda%",
                "%$terminoBusqueda%"
            );
        }

        // CREAMOS EL COMPLEMENTO WHERE DEL QUERY PARA CONCATENARLO AL QUERY GENERAL
        $sqlTotal = '';
        if ($sqlFiltro != NULL)
            $sqlTotal .= 'WHERE ' . $sqlFiltro;

        if ($sqlBusqueda != NULL) {
            if ($sqlTotal != '')
                $sqlTotal .= ' AND ' . $sqlBusqueda;
            else
                $sqlTotal .= 'WHERE ' . $sqlBusqueda;
        }

        // ////////////////////////////////////////////////////////////////////////

        $sql = "SELECT DISTINCT COUNT(*) as total
            FROM producto 
                left join proveedor on producto.id_proveedor = proveedor.id_proveedor 
                inner join precio on producto.id_precio = precio.id_precio 
                inner join producto_categoria on producto.id_producto = producto_categoria.id_producto
                inner join categoria on producto_categoria.id_categoria = categoria.id_categoria
                 " . $sqlTotal;
        // echo $sql;
        $stmt = $db->prepare($sql);
        $stmt->execute($parametrosLike);
        return ($stmt->rowCount() >= 1) ? $stmt->fetch(PDO::FETCH_ASSOC) : false;
    }

    public static function mdlSearchLimit($filtros, $terminoBusqueda, $orden, $offset, $limit)
    {
        $conn = new Conexion();
        $db = $conn->get_connection();

        $sqlFiltro = '';
        $sqlBusqueda = '';
        $parametrosLike = array();
        $sqlOrden = '';

        if ($filtros != NULL) {
            $numFiltros = (empty($filtros)) ? 0 : count($filtros);
            $i = 1;
            foreach ($filtros as $key => $filtro) {

                $campo = $filtro['campo'];

                if ($campo == "estado") {
                    $sqlFiltro .= "producto.activo = " . $filtro['data']['activo'];
                }

                if ($campo == "fecha_alta") {
                    $tipoBusqueda = $filtro['data']['tipoBusqueda'];
                    switch ($tipoBusqueda) {
                        case '1':
                            $sqlFiltro .= "DATE(producto.fecha_alta) = '" . $filtro['data']['fecha'] . "'";
                            break;
                        case '2':
                            $sqlFiltro .= "(producto.fecha_alta >= '" . $filtro['data']['fecha_inicial'] . "' AND producto.fecha_alta <= '" . $filtro['data']['fecha_final'] . "')";
                            break;
                        case '3':
                            $sqlFiltro .= "producto.fecha_alta > '" . $filtro['data']['fecha'] . "'";
                            break;
                        case '4':
                            $sqlFiltro .= "producto.fecha_alta >= '" . $filtro['data']['fecha'] . "'";
                            break;
                        case '5':
                            $sqlFiltro .= "producto.fecha_alta < '" . $filtro['data']['fecha'] . "'";
                            break;
                        case '6':
                            $sqlFiltro .= "producto.fecha_alta <= '" . $filtro['data']['fecha'] . "'";
                            break;
                    }
                }

                if ($campo == "precio") {
                    $tipoBusqueda = $filtro['data']['tipoBusqueda'];
                    switch ($tipoBusqueda) {
                        case '1':
                            $sqlFiltro .= "precio.precio = " . $filtro['data']['precio'];
                            break;
                        case '2':
                            $sqlFiltro .= "(precio.precio >= " . $filtro['data']['precio_inicial'] . " AND precio.precio <= " . $filtro['data']['precio_final'] . ")";
                            break;
                        case '3':
                            $sqlFiltro .= "precio.precio > " . $filtro['data']['precio'];
                            break;
                        case '4':
                            $sqlFiltro .= "precio.precio < " . $filtro['data']['precio'];
                            break;
                    }
                }

                if ($campo == "proveedor") {
                    $sqlFiltro .= "producto.id_proveedor = " . $filtro['data']['id_proveedor'];
                }

                if ($campo == "categoria") {
                    $sqlFiltro .= "categoria.id_categoria = " . $filtro['data']['id_categoria'];
                }

                if ($numFiltros > 1) {
                    if ($i == $numFiltros) {
                        $sqlFiltro .= "";
                    } else {
                        $sqlFiltro .= " AND ";
                    }
                }

                $i++;
            }
        }

        if ($terminoBusqueda != NULL) {
            $sqlBusqueda .= "(producto.nombre LIKE ? OR producto.sku LIKE ?)";
            array_push(
                $parametrosLike,
                "%$terminoBusqueda%",
                "%$terminoBusqueda%"
            );
        }

        if ($orden != NULL) {
            // AQUI VA EL QUERY PARA EL TERMINO DE LA ORDEN
            if ($orden['campo'] == 'nombre')
                $sqlOrden .= ' ORDER BY producto.nombre ' . $orden['orden'];
            if ($orden['campo'] == 'fecha_alta')
                $sqlOrden .= ' ORDER BY producto.fecha_alta ' . $orden['orden'];
            if ($orden['campo'] == 'costo')
                $sqlOrden .= ' ORDER BY precio.precio ' . $orden['orden'];
            if ($orden['campo'] == 'ranking')
                $sqlOrden .= ' ORDER BY cantidad_vendida ' . $orden['orden'];
        } else {
            $sqlOrden .= ' ORDER BY producto.fecha_alta DESC';
        }

        // CREAMOS EL COMPLEMENTO WHERE DEL QUERY PARA CONCATENARLO AL QUERY GENERAL
        $sqlTotal = '';
        if ($sqlFiltro != NULL)
            $sqlTotal .= 'WHERE ' . $sqlFiltro;

        if ($sqlBusqueda != NULL) {
            if ($sqlTotal != '')
                $sqlTotal .= ' AND ' . $sqlBusqueda;
            else
                $sqlTotal .= 'WHERE ' . $sqlBusqueda;
        }

        // ////////////////////////////////////////////////////////////////////////

        $sql = "SELECT DISTINCT producto.*, proveedor.nombre as nombre_proveedor, precio.precio as precio_producto, categoria.color AS color_categoria, COUNT(producto_orden.id_producto) AS cantidad_vendida 
            FROM producto 
                left join proveedor on producto.id_proveedor = proveedor.id_proveedor 
                inner join precio on producto.id_precio = precio.id_precio 
                inner join producto_categoria on producto.id_producto = producto_categoria.id_producto
                inner join categoria on producto_categoria.id_categoria = categoria.id_categoria
                left join producto_orden ON producto.id_producto = producto_orden.id_producto
                 " . $sqlTotal . " GROUP BY producto.id_producto " . $sqlOrden . " LIMIT " . $offset . ", " . $limit;
        // echo $sql;
        $stmt = $db->prepare($sql);
        $stmt->execute($parametrosLike);
        return ($stmt->rowCount() >= 1) ? $stmt->fetchAll(PDO::FETCH_ASSOC) : false;
    }

    public static function mdlUpdatePrecio($id_producto, $id_precio)
    {
        $conexion = new Conexion();
        $db = $conexion->get_connection();

        $sql = "UPDATE producto SET id_precio = :id_precio WHERE id_producto = :id_producto";

        $stmt = $db->prepare($sql);

        $stmt->bindParam(':id_producto', $id_producto, PDO::PARAM_INT);
        $stmt->bindParam(':id_precio', $id_precio, PDO::PARAM_INT);

        $stmt->execute();

        $response = ($stmt->rowCount() > 0) ? true : false;

        $db = null;

        return $response;
    }

    public static function mdlAddProductoOdoo(
        $id_odoo,
        $nombre,
        $sku,
        $id_proveedor,
        $peso,
        $alto,
        $ancho,
        $largo
    ) {
        $conexion = new Conexion();
        $db = $conexion->get_connection();

        $sql = "INSERT INTO producto (id_producto_odoo, nombre, sku, id_proveedor, peso, alto, ancho, largo) 
                VALUES (:id_odoo, :nombre, :sku, :id_proveedor, :peso, :alto, :ancho, :largo)";

        $stmt = $db->prepare($sql);

        $stmt->bindParam(':id_odoo', $id_odoo, PDO::PARAM_INT);
        $stmt->bindParam(':nombre', $nombre, PDO::PARAM_STR);
        $stmt->bindParam(':sku', $sku, PDO::PARAM_STR);
        $stmt->bindParam(':id_proveedor', $id_proveedor, PDO::PARAM_INT);
        $stmt->bindParam(':peso', $peso);
        $stmt->bindParam(':alto', $alto);
        $stmt->bindParam(':ancho', $ancho);
        $stmt->bindParam(':largo', $largo);

        $stmt->execute();

        $id_producto = $db->lastInsertId();

        $db = null;

        return $id_producto;
    }

    public static function mdlDeleteProducto($id_producto)
    {
        $conexion = new Conexion();
        $db = $conexion->get_connection();
        $sql = "DELETE FROM producto WHERE id_producto = :id_producto";
        $stmt = $db->prepare($sql);
        $stmt->bindParam(':id_producto', $id_producto, PDO::PARAM_INT);
        $stmt->execute();
        $response = ($stmt->rowCount() > 0) ? true : false;
        $db = null;
        return $response;
    }

    public static function mdlGetAllProductosOdoo()
    {
        $conexion = new Conexion();
        $db = $conexion->get_connection();
        $sql = "SELECT id_producto, id_producto_odoo, fecha_alta, sku FROM producto ORDER BY fecha_alta DESC";
        $stmt = $db->prepare($sql);
        $stmt->execute();
        $response = ($stmt->rowCount() > 0) ? $stmt->fetchAll(PDO::FETCH_ASSOC) : false;
        $db = null;
        return $response;
    }

    // //////////////////////////////////////////////////////////

    public static function mdlGetProductosRecomendados()
    {
        $conexion = new Conexion();
        $db = $conexion->get_connection();

        $sql = "SELECT DISTINCT producto.*, categoria.color AS color_categoria FROM producto 
                LEFT JOIN precio ON producto.id_precio = precio.id_precio
                LEFT JOIN producto_categoria ON producto.id_producto = producto_categoria.id_producto
                LEFT JOIN categoria ON producto_categoria.id_categoria = categoria.id_categoria
                WHERE producto.activo = 1
                ORDER BY visitas DESC limit 10";

        $stmt = $db->prepare($sql);

        $stmt->execute();

        $response = ($stmt->rowCount() > 0) ? $stmt->fetchAll(PDO::FETCH_ASSOC) : false;

        $db = null;

        return $response;
    }

    public static function mdlGetCalificacionesProducto($id_producto)
    {
        $conexion = new Conexion();
        $db = $conexion->get_connection();

        $sql = "SELECT COUNT(*) AS total_calificaciones, AVG(calificacion) AS promedio_estrellas FROM
        calificacion_producto WHERE id_producto = :id_producto";

        $stmt = $db->prepare($sql);

        $stmt->bindParam(':id_producto', $id_producto);

        $stmt->execute();

        $response = ($stmt->rowCount() > 0) ? $stmt->fetch(PDO::FETCH_ASSOC) : false;

        $db = null;

        return $response;
    }

    public static function mdlGetEquiposRecientes()
    {
        $conexion = new Conexion();
        $db = $conexion->get_connection();

        $sql = "SELECT producto.*, categoria.color AS color_categoria FROM producto 
                LEFT JOIN producto_categoria ON producto.id_producto = producto_categoria.id_producto 
                LEFT JOIN categoria ON producto_categoria.id_categoria = categoria.id_categoria
                WHERE categoria.nombre = 'Equipos' AND producto.activo = 1
                ORDER BY fecha_alta DESC LIMIT 10";

        $stmt = $db->prepare($sql);

        $stmt->execute();

        $response = ($stmt->rowCount() > 0) ? $stmt->fetchAll(PDO::FETCH_ASSOC) : false;

        $db = null;

        return $response;
    }

    public static function mdlGetProductosCategoria($id_categoria)
    {
        $conexion = new Conexion();
        $db = $conexion->get_connection();

        $sql = "SELECT producto.*, precio.precio, categoria.color AS color_categoria FROM producto 
                INNER JOIN producto_categoria ON producto.id_producto = producto_categoria.id_producto
                LEFT JOIN categoria ON producto_categoria.id_categoria = categoria.id_categoria
                LEFT JOIN precio ON producto.id_precio = precio.id_precio
                WHERE producto_categoria.id_categoria = :id_categoria AND producto.activo = 1";

        $stmt = $db->prepare($sql);

        $stmt->bindParam(':id_categoria', $id_categoria);

        $stmt->execute();

        $totalRows = $stmt->rowCount();
        $data = ($totalRows > 0) ? $stmt->fetchAll(PDO::FETCH_ASSOC) : [];

        $response = ($totalRows > 0) ? ['productos' => $data, 'total' => $totalRows] : false;

        $db = null;

        return $response;
    }

    public static function mdlGetProductosMasVendidos()
    {
        $conexion = new Conexion();
        $db = $conexion->get_connection();

        $sql = "SELECT producto.*, categoria.color AS color_categoria, SUM(producto_orden.cantidad) AS ventas_totales 
                FROM producto
                INNER JOIN producto_categoria ON producto.id_producto = producto_categoria.id_producto
                LEFT JOIN categoria ON producto_categoria.id_categoria = categoria.id_categoria
                INNER JOIN producto_orden ON producto.id_producto = producto_orden.id_producto
                LEFT JOIN precio ON producto.id_precio = precio.id_precio
                WHERE producto.activo = 1
                GROUP BY producto.id_producto, producto.nombre, precio.precio, categoria.color
                ORDER BY ventas_totales DESC LIMIT 10";

        $stmt = $db->prepare($sql);

        $stmt->execute();

        $response = ($stmt->rowCount() > 0) ? $stmt->fetchAll(PDO::FETCH_ASSOC) : false;

        $db = null;

        return $response;
    }

    public static function mdlGetProductoById($id_producto)
    {
        $conexion = new Conexion();
        $db = $conexion->get_connection();

        $sql = "SELECT producto.*, categoria.color AS color_categoria, precio.precio, precio.precio_iva FROM producto
                INNER JOIN producto_categoria ON producto.id_producto = producto_categoria.id_producto
                INNER JOIN categoria ON producto_categoria.id_categoria = categoria.id_categoria
                INNER JOIN precio ON producto.id_precio = precio.id_precio
                WHERE producto.id_producto = :id_producto";

        $stmt = $db->prepare($sql);

        $stmt->bindParam(':id_producto', $id_producto);

        $stmt->execute();

        $response = ($stmt->rowCount() > 0) ? $stmt->fetch(PDO::FETCH_ASSOC) : false;

        $db = null;

        return $response;
    }

    public static function mdlGetProductoByURL($url_pagina)
    {
        $conexion = new Conexion();
        $db = $conexion->get_connection();

        $sql = "SELECT producto.*, categoria.color AS color_categoria, categoria.nombre AS nombre_categoria, subcategoria.nombre AS nombre_subcategoria
                FROM producto
                INNER JOIN producto_categoria ON producto.id_producto = producto_categoria.id_producto
                INNER JOIN categoria ON producto_categoria.id_categoria = categoria.id_categoria
                INNER JOIN subcategoria ON producto_categoria.id_subcategoria = subcategoria.id_subcategoria
                WHERE producto.url_pagina = :url_pagina";

        $stmt = $db->prepare($sql);

        $stmt->bindParam(':url_pagina', $url_pagina);

        $stmt->execute();

        $response = ($stmt->rowCount() > 0) ? $stmt->fetch(PDO::FETCH_ASSOC) : false;

        $db = null;

        return $response;
    }

    public static function mdlGetProductosCategoriaFiltros($filters)
    {
        $conexion = new Conexion();
        $db = $conexion->get_connection();

        $baseQuery = "SELECT producto.*, categoria.color AS color_categoria FROM producto 
                      INNER JOIN precio ON producto.id_precio = precio.id_precio 
                      INNER JOIN producto_categoria ON producto.id_producto = producto_categoria.id_producto 
                      INNER JOIN categoria ON producto_categoria.id_categoria = categoria.id_categoria 
                      WHERE producto.activo = 1";

        if (isset($filters['precio_max']) && $filters['precio_min'] !== null) {
            $baseQuery .= " AND precio.precio BETWEEN :min AND :max";
        }

        if (isset($filters['categoria'])) {
            $baseQuery .= " AND categoria.nombre = :categoria";
        }

        if (isset($filters['proveedor'])) {
            $baseQuery .= " AND producto.id_proveedor = :proveedor";
        }

        $orderBy = array();

        if (isset($filters['fecha'])) {
            $orderBy[] = "producto.ultima_actualizacion " . ($filters['fecha'] == 'ASC' ? 'ASC' : 'DESC');
        }

        if (isset($filters['precio'])) {
            $orderBy[] = "precio.precio " . ($filters['precio'] == 'ASC' ? 'ASC' : 'DESC');
        }

        if (!empty($orderBy)) {
            $baseQuery .= " ORDER BY " . implode(', ', $orderBy);
        }

        $stmt = $db->prepare($baseQuery);

        if (isset($filters['precio_max']) && $filters['precio_min'] !== null) {
            $stmt->bindParam(':min', $filters['precio_min']);
            $stmt->bindParam(':max', $filters['precio_max']);
        }

        if (isset($filters['categoria'])) {
            $stmt->bindParam(':categoria', $filters['categoria']);
        }

        if (isset($filters['proveedor'])) {
            $stmt->bindParam(':proveedor', $filters['proveedor']);
        }

        $stmt->execute();

        $response = ($stmt->rowCount() > 0) ? $stmt->fetchAll(PDO::FETCH_ASSOC) : false;

        $db = null;

        return $response;
    }

    public static function mdlGetProductosSubCategoriaFiltros($filters, $categoria, $subcategoria, $order)
    {
        $conexion = new Conexion();
        $db = $conexion->get_connection();

        $baseQuery = "SELECT producto.*, categoria.color AS color_categoria, subcategoria.id_subcategoria FROM producto 
                    INNER JOIN precio ON producto.id_precio = precio.id_precio 
                    INNER JOIN producto_categoria ON producto.id_producto = producto_categoria.id_producto 
                    INNER JOIN categoria ON producto_categoria.id_categoria = categoria.id_categoria 
                    INNER JOIN subcategoria ON producto_categoria.id_subcategoria = subcategoria.id_subcategoria 
                    WHERE producto.activo = 1 AND categoria.url_pagina LIKE :categoria AND subcategoria.url_pagina LIKE :subcategoria";

        if (isset($filters['precio_max']) && isset($filters['precio_min'])) {
            $baseQuery .= " AND (precio.precio BETWEEN :min AND :max) ";
        }

        if (isset($filters['proveedor'])) {
            $baseQuery .= " AND producto.id_proveedor = :proveedor";
        }

        $orderBy = array();

        if (isset($filters['fecha'])) {
            $orderBy[] = "producto.ultima_actualizacion " . ($filters['fecha'] == 'ASC' ? 'ASC' : 'DESC');
        }

        if (isset($filters['precio'])) {
            $orderBy[] = "precio.precio " . ($filters['precio'] == 'ASC' ? 'ASC' : 'DESC');
        }

        // Add the default order by producto.nombre
        $orderBy[] = "producto.nombre " . $order;

        if (!empty($orderBy)) {
            $baseQuery .= " ORDER BY " . implode(', ', $orderBy);
        }

        $stmt = $db->prepare($baseQuery);

        $cat = '%' . $categoria;
        $stmt->bindParam(':categoria', $cat);
        $subcat = '%' . $subcategoria;
        $stmt->bindParam(':subcategoria', $subcat);

        if (isset($filters['precio_max']) && isset($filters['precio_min'])) {
            $stmt->bindParam(':min', $filters['precio_min']);
            $stmt->bindParam(':max', $filters['precio_max']);
        }

        if (isset($filters['proveedor'])) {
            $stmt->bindParam(':proveedor', $filters['proveedor']);
        }

        $stmt->execute();

        $response = ($stmt->rowCount() > 0) ? $stmt->fetchAll(PDO::FETCH_ASSOC) : false;

        $db = null;

        return $response;
    }

    public static function mdlGetProductosBusqueda($termino_busqueda, $filters, $order)
    {
        $conexion = new Conexion();
        $db = $conexion->get_connection();

        // Base query with mandatory condition
        $baseQuery = "SELECT producto.*, categoria.color AS color_categoria FROM producto 
                  INNER JOIN precio ON producto.id_precio = precio.id_precio 
                  INNER JOIN producto_categoria ON producto.id_producto = producto_categoria.id_producto 
                  INNER JOIN categoria ON producto_categoria.id_categoria = categoria.id_categoria 
                  WHERE producto.activo = 1 AND producto.url_pagina IS NOT NULL";

        // Adding search term if provided
        $params = [];
        if (isset($termino_busqueda)) {
            // var_dump($termino_busqueda);
            $termino = explode("%20", $termino_busqueda);
            $conditions = [];
            foreach ($termino as $i => $term) {
                $conditions[] = "producto.nombre LIKE :termino" . $i;
                $conditions[] = "producto.descripcion_corta LIKE :desc_corta" . $i;
                $conditions[] = "producto.sku LIKE :sku" . $i;
                $params[':termino' . $i] = '%' . $term . '%';
                $params[':desc_corta' . $i] = '%' . $term . '%';
                $params[':sku' . $i] = '%' . $term . '%';
            }
            $baseQuery .= " AND (" . implode(" OR ", $conditions) . ")";
        }

        // Adding filters for price range
        if (isset($filters['precio_max']) && isset($filters['precio_min'])) {
            $baseQuery .= " AND precio.precio BETWEEN :min AND :max";
            $params[':min'] = $filters['precio_min'];
            $params[':max'] = $filters['precio_max'];
        }

        // Adding filter for category
        if (isset($filters['categoria'])) {
            $baseQuery .= " AND categoria.nombre = :categoria";
            $params[':categoria'] = $filters['categoria'];
        }

        // Adding filter for provider
        if (isset($filters['proveedor'])) {
            $baseQuery .= " AND producto.id_proveedor = :proveedor";
            $params[':proveedor'] = $filters['proveedor'];
        }

        // Handling dynamic ordering
        $orderBy = array();
        if (isset($filters['fecha'])) {
            $orderBy[] = "producto.ultima_actualizacion " . ($filters['fecha'] == 'ASC' ? 'ASC' : 'DESC');
        }
        if (isset($filters['precio'])) {
            $orderBy[] = "precio.precio " . ($filters['precio'] == 'ASC' ? 'ASC' : 'DESC');
        }
        if (!empty($orderBy)) {
            $baseQuery .= " ORDER BY " . implode(', ', $orderBy);
        } else {
            // If no dynamic ordering, use the provided $order
            $baseQuery .= " ORDER BY producto.fecha_alta " . $order;
        }

        $stmt = $db->prepare($baseQuery);

        // Binding parameters dynamically
        foreach ($params as $key => $value) {
            $stmt->bindValue($key, $value);
        }

        $stmt->execute();

        $response = ($stmt->rowCount() > 0) ? $stmt->fetchAll(PDO::FETCH_ASSOC) : false;

        $db = null;

        return $response;
    }


    public static function mdlGetRangoPrecios()
    {
        $conexion = new Conexion();
        $db = $conexion->get_connection();

        $baseQuery = "SELECT MAX(precio.precio) as precio_max, MIN(precio.precio) as precio_min FROM producto 
                      INNER JOIN precio ON producto.id_precio = precio.id_precio 
                      INNER JOIN producto_categoria ON producto.id_producto = producto_categoria.id_producto 
                      INNER JOIN categoria ON producto_categoria.id_categoria = categoria.id_categoria 
                      WHERE producto.activo = 1";

        $stmt = $db->prepare($baseQuery);

        $stmt->execute();

        $response = ($stmt->rowCount() > 0) ? $stmt->fetch(PDO::FETCH_ASSOC) : false;

        $db = null;

        return $response;
    }

    public static function mdlGetRangoPreciosByCategoria($categoria)
    {
        $conexion = new Conexion();
        $db = $conexion->get_connection();

        $sql = "SELECT MAX(precio.precio) as precio_max, MIN(precio.precio) as precio_min 
                FROM producto 
                INNER JOIN precio ON producto.id_precio = precio.id_precio 
                INNER JOIN producto_categoria ON producto.id_producto = producto_categoria.id_producto 
                INNER JOIN categoria ON producto_categoria.id_categoria = categoria.id_categoria 
                WHERE producto.activo = 1 AND categoria.nombre LIKE :categoria";

        $stmt = $db->prepare($sql);

        $categoriaParam = '%' . $categoria . '%';
        $stmt->bindParam(':categoria', $categoriaParam);

        $stmt->execute();

        $response = ($stmt->rowCount() > 0) ? $stmt->fetch(PDO::FETCH_ASSOC) : false;

        $db = null;

        return $response;
    }

    public static function mdlGetRangoPreciosBySubCategoria($categoria, $subcategoria)
    {
        $conexion = new Conexion();
        $db = $conexion->get_connection();

        $sql = "SELECT MAX(precio.precio) as precio_max, MIN(precio.precio) as precio_min 
                FROM producto 
                INNER JOIN precio ON producto.id_precio = precio.id_precio 
                INNER JOIN producto_categoria ON producto.id_producto = producto_categoria.id_producto
                INNER JOIN categoria ON producto_categoria.id_categoria = categoria.id_categoria
                INNER JOIN subcategoria ON producto_categoria.id_subcategoria = subcategoria.id_subcategoria 
                WHERE producto.activo = 1 AND categoria.url_pagina = :categoria AND subcategoria.url_pagina = :subcategoria";

        $stmt = $db->prepare($sql);

        $stmt->bindParam(':categoria', $categoria);
        $stmt->bindParam(':subcategoria', $subcategoria);

        $stmt->execute();

        $response = ($stmt->rowCount() > 0) ? $stmt->fetch(PDO::FETCH_ASSOC) : false;

        $db = null;

        return $response;
    }

    public static function mdlUpdateEstadoProducto($id_producto, $activo)
    {
        $conexion = new Conexion();
        $db = $conexion->get_connection();

        $sql = "UPDATE producto SET activo = :activo WHERE id_producto = :id_producto";

        $stmt = $db->prepare($sql);

        $stmt->bindParam(':activo', $activo, PDO::PARAM_BOOL);
        $stmt->bindParam(':id_producto', $id_producto, PDO::PARAM_INT);

        $stmt->execute();

        $response = ($stmt->rowCount() > 0) ? true : false;

        $db = null;

        return $response;
    }

    public static function mdlVerificarProductoStock($id_producto)
    {
        $conexion = new Conexion();
        $db = $conexion->get_connection();

        $sql = "SELECT producto.stock FROM producto WHERE id_producto = :id_producto";

        $stmt = $db->prepare($sql);

        $stmt->bindParam(':id_producto', $id_producto, PDO::PARAM_INT);

        $stmt->execute();

        $response = ($stmt->rowCount() > 0) ? $stmt->fetch(PDO::FETCH_ASSOC) : false;

        $db = null;

        return $response;
    }

    public static function mdlGetProductosByIdOrden($id_orden)
    {
        $conexion = new Conexion();
        $db = $conexion->get_connection();

        $sql = "SELECT producto.*, precio.precio, categoria.color AS color_categoria FROM producto_orden 
                INNER JOIN producto ON producto_orden.id_producto = producto.id_producto
                INNER JOIN producto_categoria ON producto.id_producto = producto_categoria.id_producto
                INNER JOIN categoria ON producto_categoria.id_categoria = categoria.id_categoria
                INNER JOIN precio ON producto.id_precio = precio.id_precio 
                WHERE producto_orden.id_orden = :id_orden";

        $stmt = $db->prepare($sql);

        $stmt->bindParam(':id_orden', $id_orden, PDO::PARAM_INT);

        $stmt->execute();

        $response = ($stmt->rowCount() > 0) ? $stmt->fetchAll(PDO::FETCH_ASSOC) : false;

        $db = null;

        return $response;
    }

    public static function mdlGetIdProductoOdoo($id_producto)
    {
        $conexion = new Conexion();
        $db = $conexion->get_connection();

        $sql = "SELECT id_producto_odoo FROM producto WHERE id_producto = :id_producto";

        $stmt = $db->prepare($sql);

        $stmt->bindParam(':id_producto', $id_producto, PDO::PARAM_INT);

        $stmt->execute();

        $response = ($stmt->rowCount() > 0) ? $stmt->fetch(PDO::FETCH_ASSOC) : false;

        $db = null;

        return $response;
    }

    public static function mdlGetNombreProductos()
    {
        $conexion = new Conexion();
        $db = $conexion->get_connection();

        $sql = "SELECT nombre FROM producto WHERE activo = 1";

        $stmt = $db->prepare($sql);

        $stmt->execute();

        $response = ($stmt->rowCount() > 0) ? $stmt->fetchAll(PDO::FETCH_ASSOC) : false;

        $db = null;

        return $response;
    }

    public static function mdlUpdateVisitas($id_producto)
    {
        $conexion = new Conexion();
        $db = $conexion->get_connection();

        $sql = "UPDATE producto SET visitas = visitas + 1 WHERE id_producto = :id_producto";

        $stmt = $db->prepare($sql);

        $stmt->bindParam(':id_producto', $id_producto, PDO::PARAM_INT);

        $stmt->execute();

        $response = ($stmt->rowCount() > 0) ? true : false;

        $db = null;

        return $response;
    }

    public static function mdlGetAllProductosActivo($activo)
    {
        $conexion = new Conexion();
        $db = $conexion->get_connection();

        $sql = "SELECT producto.nombre, producto.sku, producto.id_producto, precio.precio FROM producto 
                INNER JOIN precio ON producto.id_precio = precio.id_precio 
                WHERE producto.activo = :activo";

        $stmt = $db->prepare($sql);

        $stmt->bindParam(':activo', $activo, PDO::PARAM_INT);

        $stmt->execute();

        $response = ($stmt->rowCount() > 0) ? $stmt->fetchAll(PDO::FETCH_ASSOC) : false;

        $db = null;

        return $response;
    }

    public static function mdlGetProductosSinVariaciones($activo)
    {
        $conexion = new Conexion();
        $db = $conexion->get_connection();

        $sql = "SELECT producto.nombre, producto.sku, producto.id_producto, precio.precio FROM producto 
                INNER JOIN precio ON producto.id_precio = precio.id_precio 
                LEFT JOIN producto_variacion ON producto.id_producto = producto_variacion.id_producto
                WHERE producto.activo = :activo AND producto_variacion.id_producto IS NULL";

        $stmt = $db->prepare($sql);

        $stmt->bindParam(':activo', $activo, PDO::PARAM_INT);

        $stmt->execute();

        $response = ($stmt->rowCount() > 0) ? $stmt->fetchAll(PDO::FETCH_ASSOC) : false;

        $db = null;

        return $response;
    }

    public static function updateDatosOdooById($id_producto, $peso, $alto, $ancho, $largo)
    {
        $conexion = new Conexion();
        $db = $conexion->get_connection();

        $sql = "UPDATE producto SET peso = :peso, alto = :alto, ancho = :ancho, largo = :largo WHERE id_producto = :id_producto";

        $stmt = $db->prepare($sql);

        $stmt->bindParam(':id_producto', $id_producto, PDO::PARAM_INT);
        $stmt->bindParam(':peso', $peso, PDO::PARAM_INT);
        $stmt->bindParam(':alto', $alto, PDO::PARAM_INT);
        $stmt->bindParam(':ancho', $ancho, PDO::PARAM_INT);
        $stmt->bindParam(':largo', $largo, PDO::PARAM_INT);

        $stmt->execute();

        $response = ($stmt->rowCount() > 0) ? true : false;

        $db = null;

        return $response;
    }

    public static function mdlGetVentasTotalesAllProductos()
    {
        $conexion = new Conexion();
        $db = $conexion->get_connection();

        $sql = "SELECT id_producto, COUNT(*) AS cantidad_vendida 
                FROM producto_orden 
                GROUP BY id_producto 
                ORDER BY cantidad_vendida DESC";

        $stmt = $db->prepare($sql);

        $stmt->execute();

        $response = ($stmt->rowCount() > 0) ? $stmt->fetchAll(PDO::FETCH_ASSOC) : false;

        $db = null;

        return $response;
    }
}
