<?php
require_once '../models/model_producto.php';
require_once '../models/model_categoria.php';

class ControllerProducto {
    private $model;
    private $modelCategoria;

    public function __construct() {
        $this->model = new ModelProducto();
        $this->modelCategoria = new ModelCategoria();
    }

    // Manejar todas las acciones desde una sola entrada
    public function manejarAccion() {
        $accion = $_REQUEST['accion'] ?? 'listar';
        
        switch ($accion) {
            case 'listar':
                return $this->listar();
            case 'listar_por_categoria':
                return $this->listarPorCategoria();
            case 'crear':
                return $this->crear();
            case 'obtener':
                return $this->obtener();
            case 'actualizar':
                return $this->actualizar();
            case 'cambiar_estado':
                return $this->cambiarEstado();
            case 'eliminar':
                return $this->eliminar();
            case 'buscar':
                return $this->buscar();
            case 'filtrar_precio':
                return $this->filtrarPorPrecio();
            case 'validar_titulo':
                return $this->validarTitulo();
            case 'menu_publico':
                return $this->menuPublico();
            default:
                return $this->respuestaJson(['success' => false, 'message' => 'Acción no válida']);
        }
    }

    // Listar todos los productos
    private function listar() {
        try {
            $solo_activos = isset($_GET['solo_activos']) ? (bool)$_GET['solo_activos'] : false;
            $resultado = $this->model->leerTodos($solo_activos);
            return $this->respuestaJson($resultado);
        } catch (Exception $e) {
            return $this->respuestaJson(['success' => false, 'message' => 'Error interno del servidor']);
        }
    }

    // Listar productos por categoría
    private function listarPorCategoria() {
        try {
            $id_categoria = $_GET['id_categoria'] ?? null;
            $solo_activos = isset($_GET['solo_activos']) ? (bool)$_GET['solo_activos'] : false;

            if (!$id_categoria || !is_numeric($id_categoria)) {
                return $this->respuestaJson(['success' => false, 'message' => 'ID de categoría no válido']);
            }

            $resultado = $this->model->leerPorCategoria($id_categoria, $solo_activos);
            return $this->respuestaJson($resultado);
        } catch (Exception $e) {
            return $this->respuestaJson(['success' => false, 'message' => 'Error interno del servidor']);
        }
    }

    // Crear nuevo producto
    private function crear() {
        try {
            // Validar método HTTP
            if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
                return $this->respuestaJson(['success' => false, 'message' => 'Método no permitido']);
            }

            // Obtener y validar datos
            $datos = $this->obtenerDatosFormulario();
            $validacion = $this->validarDatos($datos);
            
            if (!$validacion['valido']) {
                return $this->respuestaJson(['success' => false, 'message' => $validacion['mensaje']]);
            }

            // Verificar que no exista el título en la misma categoría
            if ($this->model->existeTitulo($datos['titulo'], $datos['id_categoria'])) {
                return $this->respuestaJson(['success' => false, 'message' => 'Ya existe un producto con este título en la categoría seleccionada']);
            }

            // Manejar subida de imagen
            $foto_url = $this->manejarSubidaImagen();

            // Crear producto
            $resultado = $this->model->crear(
                $datos['id_categoria'],
                $datos['titulo'],
                $datos['descripcion'],
                $datos['precio'],
                $foto_url,
                $datos['activo']
            );
            
            return $this->respuestaJson($resultado);

        } catch (Exception $e) {
            return $this->respuestaJson(['success' => false, 'message' => 'Error interno del servidor']);
        }
    }

    // Obtener un producto por ID
    private function obtener() {
        try {
            $id = $_GET['id'] ?? null;
            
            if (!$id || !is_numeric($id)) {
                return $this->respuestaJson(['success' => false, 'message' => 'ID de producto no válido']);
            }

            $resultado = $this->model->leerPorId($id);
            return $this->respuestaJson($resultado);

        } catch (Exception $e) {
            return $this->respuestaJson(['success' => false, 'message' => 'Error interno del servidor']);
        }
    }

    // Actualizar producto
    private function actualizar() {
        try {
            // Validar método HTTP
            if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
                return $this->respuestaJson(['success' => false, 'message' => 'Método no permitido']);
            }

            // Obtener ID
            $id = $_POST['id'] ?? null;
            if (!$id || !is_numeric($id)) {
                return $this->respuestaJson(['success' => false, 'message' => 'ID de producto no válido']);
            }

            // Obtener y validar datos
            $datos = $this->obtenerDatosFormulario();
            $validacion = $this->validarDatos($datos);
            
            if (!$validacion['valido']) {
                return $this->respuestaJson(['success' => false, 'message' => $validacion['mensaje']]);
            }

            // Verificar que no exista el título (excluyendo el producto actual)
            if ($this->model->existeTitulo($datos['titulo'], $datos['id_categoria'], $id)) {
                return $this->respuestaJson(['success' => false, 'message' => 'Ya existe un producto con este título en la categoría seleccionada']);
            }

            // Manejar subida de imagen (si se proporciona una nueva)
            $foto_url = $this->manejarSubidaImagen();
            
            // Si no se subió nueva imagen, mantener la actual
            if ($foto_url === null) {
                $productoActual = $this->model->leerPorId($id);
                if ($productoActual['success']) {
                    $foto_url = $productoActual['data']['foto_url'];
                }
            }

            // Actualizar producto
            $resultado = $this->model->actualizar(
                $id,
                $datos['id_categoria'],
                $datos['titulo'],
                $datos['descripcion'],
                $datos['precio'],
                $foto_url,
                $datos['activo']
            );
            
            return $this->respuestaJson($resultado);

        } catch (Exception $e) {
            return $this->respuestaJson(['success' => false, 'message' => 'Error interno del servidor']);
        }
    }

    // Cambiar estado activo/inactivo
    private function cambiarEstado() {
        try {
            if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
                return $this->respuestaJson(['success' => false, 'message' => 'Método no permitido']);
            }

            $id = $_POST['id'] ?? null;
            $activo = isset($_POST['activo']) ? (int)$_POST['activo'] : null;

            if (!$id || !is_numeric($id)) {
                return $this->respuestaJson(['success' => false, 'message' => 'ID de producto no válido']);
            }

            if ($activo !== 0 && $activo !== 1) {
                return $this->respuestaJson(['success' => false, 'message' => 'Estado no válido']);
            }

            $resultado = $this->model->cambiarEstado($id, $activo);
            return $this->respuestaJson($resultado);

        } catch (Exception $e) {
            return $this->respuestaJson(['success' => false, 'message' => 'Error interno del servidor']);
        }
    }

    // Eliminar producto
    private function eliminar() {
        try {
            if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
                return $this->respuestaJson(['success' => false, 'message' => 'Método no permitido']);
            }

            $id = $_POST['id'] ?? null;
            if (!$id || !is_numeric($id)) {
                return $this->respuestaJson(['success' => false, 'message' => 'ID de producto no válido']);
            }

            $resultado = $this->model->eliminar($id);
            return $this->respuestaJson($resultado);

        } catch (Exception $e) {
            return $this->respuestaJson(['success' => false, 'message' => 'Error interno del servidor']);
        }
    }

    // Buscar productos
    private function buscar() {
        try {
            $termino = trim($_GET['termino'] ?? '');
            $solo_activos = isset($_GET['solo_activos']) ? (bool)$_GET['solo_activos'] : false;

            if (strlen($termino) < 2) {
                return $this->respuestaJson(['success' => false, 'message' => 'El término de búsqueda debe tener al menos 2 caracteres']);
            }

            $resultado = $this->model->buscar($termino, $solo_activos);
            return $this->respuestaJson($resultado);

        } catch (Exception $e) {
            return $this->respuestaJson(['success' => false, 'message' => 'Error interno del servidor']);
        }
    }

    // Filtrar por rango de precio
    private function filtrarPorPrecio() {
        try {
            $precio_min = $_GET['precio_min'] ?? 0;
            $precio_max = $_GET['precio_max'] ?? 9999;
            $solo_activos = isset($_GET['solo_activos']) ? (bool)$_GET['solo_activos'] : false;

            if (!is_numeric($precio_min) || !is_numeric($precio_max)) {
                return $this->respuestaJson(['success' => false, 'message' => 'Los precios deben ser numéricos']);
            }

            if ($precio_min > $precio_max) {
                return $this->respuestaJson(['success' => false, 'message' => 'El precio mínimo no puede ser mayor al máximo']);
            }

            $resultado = $this->model->leerPorRangoPrecio($precio_min, $precio_max, $solo_activos);
            return $this->respuestaJson($resultado);

        } catch (Exception $e) {
            return $this->respuestaJson(['success' => false, 'message' => 'Error interno del servidor']);
        }
    }

    // Validar título de producto (AJAX)
    private function validarTitulo() {
        try {
            $titulo = $_GET['titulo'] ?? '';
            $id_categoria = $_GET['id_categoria'] ?? null;
            $excluir_id = $_GET['excluir_id'] ?? null;

            if (empty($titulo) || !$id_categoria) {
                return $this->respuestaJson(['disponible' => false, 'message' => 'Datos incompletos']);
            }

            $existe = $this->model->existeTitulo($titulo, $id_categoria, $excluir_id);
            return $this->respuestaJson([
                'disponible' => !$existe,
                'message' => $existe ? 'Este título ya está en uso en la categoría' : 'Título disponible'
            ]);

        } catch (Exception $e) {
            return $this->respuestaJson(['disponible' => false, 'message' => 'Error al validar']);
        }
    }

    // Obtener menú público organizado por categorías
    private function menuPublico() {
        try {
            // Obtener categorías
            $categorias = $this->modelCategoria->leerTodas();
            if (!$categorias['success']) {
                return $this->respuestaJson(['success' => false, 'message' => 'Error al cargar categorías']);
            }

            $menuCompleto = [];
            
            foreach ($categorias['data'] as $categoria) {
                $productos = $this->model->leerPorCategoria($categoria['id_categoria'], true);
                
                if ($productos['success'] && !empty($productos['data'])) {
                    $menuCompleto[] = [
                        'categoria' => $categoria,
                        'productos' => $productos['data']
                    ];
                }
            }

            return $this->respuestaJson(['success' => true, 'data' => $menuCompleto]);

        } catch (Exception $e) {
            return $this->respuestaJson(['success' => false, 'message' => 'Error interno del servidor']);
        }
    }

    // Obtener datos del formulario
    private function obtenerDatosFormulario() {
        return [
            'id_categoria' => (int)($_POST['id_categoria'] ?? 0),
            'titulo' => trim($_POST['titulo'] ?? ''),
            'descripcion' => trim($_POST['descripcion'] ?? ''),
            'precio' => (float)($_POST['precio'] ?? 0),
            'activo' => isset($_POST['activo']) ? (int)$_POST['activo'] : 1
        ];
    }

    // Validar datos de entrada
    private function validarDatos($datos) {
        // Validar categoría
        if (!$datos['id_categoria']) {
            return ['valido' => false, 'mensaje' => 'Debe seleccionar una categoría'];
        }

        // Verificar que la categoría existe
        $categoria = $this->modelCategoria->leerPorId($datos['id_categoria']);
        if (!$categoria['success']) {
            return ['valido' => false, 'mensaje' => 'La categoría seleccionada no existe'];
        }

        // Validar título
        if (empty($datos['titulo'])) {
            return ['valido' => false, 'mensaje' => 'El título del producto es requerido'];
        }

        if (strlen($datos['titulo']) > 100) {
            return ['valido' => false, 'mensaje' => 'El título no puede exceder 100 caracteres'];
        }

        // Validar precio
        if ($datos['precio'] <= 0) {
            return ['valido' => false, 'mensaje' => 'El precio debe ser mayor a 0'];
        }

        if ($datos['precio'] > 9999.99) {
            return ['valido' => false, 'mensaje' => 'El precio no puede exceder $9,999.99'];
        }

        // Validar descripción (opcional)
        if (!empty($datos['descripcion']) && strlen($datos['descripcion']) > 1000) {
            return ['valido' => false, 'mensaje' => 'La descripción no puede exceder 1000 caracteres'];
        }

        return ['valido' => true, 'mensaje' => 'Datos válidos'];
    }

    // Manejar subida de imagen
    private function manejarSubidaImagen() {
        if (!isset($_FILES['foto']) || $_FILES['foto']['error'] === UPLOAD_ERR_NO_FILE) {
            return null;
        }

        if ($_FILES['foto']['error'] !== UPLOAD_ERR_OK) {
            throw new Exception('Error al subir la imagen');
        }

        $archivo = $_FILES['foto'];
        $extensionesPermitidas = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
        $tamanoMaximo = 5 * 1024 * 1024; // 5MB

        // Validar tamaño
        if ($archivo['size'] > $tamanoMaximo) {
            throw new Exception('La imagen no puede exceder 5MB');
        }

        // Validar extensión
        $extension = strtolower(pathinfo($archivo['name'], PATHINFO_EXTENSION));
        if (!in_array($extension, $extensionesPermitidas)) {
            throw new Exception('Formato de imagen no permitido');
        }

        // Generar nombre único
        $nombreArchivo = 'producto_' . uniqid() . '.' . $extension;
        $rutaDestino = '../uploads/productos/' . $nombreArchivo;

        // Crear directorio si no existe
        if (!is_dir('../uploads/productos/')) {
            mkdir('../uploads/productos/', 0755, true);
        }

        // Mover archivo
        if (move_uploaded_file($archivo['tmp_name'], $rutaDestino)) {
            return 'uploads/productos/' . $nombreArchivo;
        }

        throw new Exception('Error al guardar la imagen');
    }

    // Respuesta JSON estándar
    private function respuestaJson($datos) {
        header('Content-Type: application/json; charset=utf-8');
        echo json_encode($datos, JSON_UNESCAPED_UNICODE);
        exit;
    }
}

// Ejecutar el controlador si se accede directamente
if (basename(__FILE__) == basename($_SERVER['SCRIPT_FILENAME'])) {
    $controller = new ControllerProducto();
    $controller->manejarAccion();
}
?>