<?php

// Validacion de token

if ($_SERVER['REQUEST_METHOD'] === 'POST') {

    if (!isset($_POST['csrf_token']) || !hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) { // Recorre todos los caracteres (siempre) y retorna true or false
        $_SESSION['flash_error'] = 'Acción inválida.';
        header('Location: index.php?opt=inicio_operador');
        exit;
    }
}

// Requiere el modelo de producto

require_once __DIR__ . '/../models/productoModel.php';
$productomodel = new productoModel;

// Validar sesón

if (!isset($_SESSION['user'])) {
    header("Location: index.php?opt=login_operador");
    exit;
}

$opt = $_GET['opt'] ?? null;

// Manejo de opciones $opt

switch($opt) {

    // LISTAR PRODUCTOS

    case 'productos':

        // Utilizamos el modelo para obtener la lista completa de productos

        $productos = $productomodel->listarProductos();

        // Saneamiento de datos para enviar a la view

        foreach ($productos as $i => $p) {

            if (($p['precio'] === null) || ($p['precio'] == 0)) {
                $productos[$i]['precio'] = '-';
            } else {
                $productos[$i]['precio'] = '$ ' . number_format($p['precio'], 2, '.', ',');
            }

            if ($p['stock'] === null || $p['stock'] === 0) {
                $productos[$i]['stock'] = '-';
            }

            $productos[$i]['descuento_total'] = number_format($p['descuento_total'], 2, '.', '') . ' %';
        }

        ob_start();
        require __DIR__ . '/../views/productos/listaProductosView.php';
        return ob_get_clean();

    // LISTAR PRODUCTOS INACTIVOS

    case 'productos_inactivos':

        // Utilizamos el modelo para obtener la lista completa de productos

        $productos = $productomodel->listarProductosInactivos();

        ob_start();
        require __DIR__ . '/../views/productos/listaProductosInactivosView.php';
        return ob_get_clean();

    // CREAR PRODUCTO

    case 'crear_producto':

        // Mostramos la vista con los datos correspondientes

        if ($_SERVER['REQUEST_METHOD'] === 'GET') {
            $categorias = $productomodel->listarCategorias();
            $tipos = $productomodel->listarTipos();

            ob_start();
            require __DIR__ . '/../views/productos/crearProductoView.php';
            return ob_get_clean();
        }

        // En caso de modificación de datos

        if ($_SERVER['REQUEST_METHOD'] === 'POST') {

            $marca = trim($_POST['marca'] ?? '');
            $modelo = trim($_POST['modelo'] ?? '');
            $id_categoria = trim($_POST['categoria'] ?? '');
            $id_tipo = trim($_POST['tipo'] ?? '');

            // Normalización de datos

            $descuentoRaw = trim($_POST['descuento'] ?? '');
            $descuento = $descuentoRaw === '' ? null : $descuentoRaw;

            $errores = [];

            // Validaciones

            if ($marca === '') {
                $errores[] = "La marca no puede estar vacía.";
            } else if (!preg_match("/^[A-Za-zÁÉÍÓÚÑáéíóúñ0-9]+(?: [A-Za-zÁÉÍÓÚÑáéíóúñ0-9]+)*$/", $marca)) {
                $errores[] = "La marca solo puede contener letras, números y espacios.";
            } else if (strlen($marca) < 2) {
                $errores[] = "La marca debe tener al menos 2 caracteres.";
            } else if (strlen($marca) > 50) {
                $errores[] = "La marca no puede superar los 50 caracteres.";
            }

            if ($modelo === '') {
                $errores[] = "El modelo no puede estar vacío.";
            } else if (!preg_match("/^[A-Za-zÁÉÍÓÚÑáéíóúñ0-9.\-]+(?: [A-Za-zÁÉÍÓÚÑáéíóúñ0-9.\-]+)*$/", $modelo)) {
                $errores[] = "El modelo solo puede contener letras, números, espacios, guiones y puntos";
            } else if (strlen($modelo) < 2) {
                $errores[] = "El modelo debe tener al menos 2 caracteres.";
            } else if (strlen($modelo) > 50) {
                $errores[] = "El modelo no puede superar los 50 caracteres.";
            }
            
            if ($descuento !== null) {

                if (!preg_match("/^\d{1,3}(\.\d{1,2})?$/", $descuento)) {
                    $errores[] = "El descuento debe ser un número válido con hasta 2 decimales.";
                } else if ((float)$descuento <= 0 || (float)$descuento > 100) {
                    $errores[] = "El descuento debe estar entre 0 a 100.";
                }
            }

            if ($id_categoria === '') {
                $errores[] = "Debe seleccionar una categoría.";
            } else if (!filter_var($id_categoria, FILTER_VALIDATE_INT) || $id_categoria <= 0) {
                $errores[] = "La categoría seleccionada no es válida.";
            } else if (!$productomodel->existeCategoria($id_categoria)) {
                $errores[] = "La categoría ingresada no existe.";
            }

            if ($id_tipo === '') {
                $errores[] = "Debe seleccionar un tipo.";
            } else if (!filter_var($id_tipo, FILTER_VALIDATE_INT) || $id_tipo <= 0) {
                $errores[] = "El tipo seleccionado no es válido.";
            } else if (!$productomodel->existeTipo($id_tipo)) {
                $errores[] = "El tipo ingresado no existe.";
            }

            if (($id_tipo === 2) && ($descuento !== null)) {
                $errores[] = "No se permite descuento si el tipo de producto es Servicio.";
            }

            if (!empty($errores)) {
                $_SESSION['flash_error'] = implode('<br>', $errores);
                header("Location: index.php?opt=crear_producto");
                exit;
            }

            // Utilizamos el método del modelo para crear el producto

            if ($productomodel->crearProducto([
                'marca' => $marca,
                'modelo' => $modelo,
                'precio' => null,
                'stock' => null,
                'descuento' => $descuento !== null ? (float)$descuento : null,
                'id_categoria' => $id_categoria,
                'id_tipo' => $id_tipo
            ])) {
                $_SESSION['flash_success'] = "Producto creado correctamente.";
            } else {
                $_SESSION['flash_error'] = "No se pudo crear el producto.";
            }

            header("Location: index.php?opt=productos");
            exit;
        }

    // EDITAR PRODUCTO

    case 'editar_producto':

        $idEditar = (int) ($_GET['id'] ?? 0);

        if ($idEditar <= 0) {
            header("Location: index.php?opt=productos");
            exit;
        }

        // Busco el producto en la base de datos mediante el modelo

        $producto = $productomodel->obtenerPorId($idEditar);

        if (!$producto) {
            $_SESSION['flash_error'] = "No se encontró el producto.";
            header("Location: index.php?opt=productos");
            exit;
        };
        
        // (Para indicar que aún no existen pedidos que incluyan dicho producto (no existe ID de pedido))

        if ($producto['id_pedido'] === null) {
            $producto['id_pedido'] = 'Aún no existe pedido que incluya este producto';
        }

        // Si el descuento es null lo seteamos en 0

        if ($producto['descuento'] === null) {
            $producto['descuento'] = 0;
        }

        // Mostrar datos de producto

        if ($_SERVER['REQUEST_METHOD'] === 'GET') {
            $categorias = $productomodel->listarCategorias();
            $tipos = $productomodel->listarTipos();

            ob_start();
            require __DIR__ . '/../views/productos/editarProductoView.php';
            return ob_get_clean();
        }

        // Caso en donde se modifican los datos

        if ($_SERVER['REQUEST_METHOD'] === 'POST') {

            // Normalización de datos

            $descuentoRaw = trim($_POST['descuento'] ?? '');
            $descuento = $descuentoRaw === '' ? null : $descuentoRaw;

            $errores = [];

            // Validaciones

            if ($descuento !== null) {

                if (!preg_match("/^\d{1,3}(\.\d{1,2})?$/", $descuento)) {
                    $errores[] = "El descuento debe ser un número válido con hasta 2 decimales.";
                } else if ((float)$descuento < 0 || (float)$descuento > 100) {
                    $errores[] = "El descuento debe estar entre 0 a 100.";
                }
            }

            if (!empty($errores)) {
                $_SESSION['flash_error'] = implode('<br>', $errores);
                header("Location: index.php?opt=editar_producto&id=" . $idEditar);
                exit;
            }

            // Recalculoamos precio (en caso de que se modifique descuento)

            require_once __DIR__ . '/../models/pedidoModel.php';
            $pedidomodel = new pedidoModel();

            $costoUnitario = $pedidomodel->obtenerCosto($_GET['id']);
            $categoria = $productomodel->obtenerPorIdCategoria($producto['id_categoria']);

            // Antes de guardar los datos verificamos que la suma del descuento no sea mayor a 100

            if (($categoria['porcentaje_ganancia'] + $descuento) > 100) {
                $_SESSION['flash_error'] = "La suma entre el descuento ingresado y el descuento de la categoria supera el 100%. Verifique.";
                header("Location:index.php?opt=editar_producto&id=$idEditar");
                exit;
            } 

            // Creamos el array con los datos correspondientes

            $guardarData = [
                'precio' => $costoUnitario !== null ? (100 + $categoria['porcentaje_ganancia']) * $costoUnitario / 100 : null,
                'descuento' => $descuento !== null ? (float) $descuento : null,
                'id_categoria' => $producto['id_categoria']
            ];

            // Utilizamos la función del modelo para actualizar el producto

            if ($productomodel->actualizarProducto($_GET['id'], $guardarData)) {
                $_SESSION['flash_success'] = "Datos actualizados correctamente.";
            } else {
                $_SESSION['flash_error'] = "No se pudo actualizar los datos.";
            }

            header("Location: index.php?opt=productos");
            exit;
        }

    // CAMBIAR ESTADO DEL PRODUCTO (ACTIVO / INACTIVO)

    case 'cambiar_estado':

        $idProducto = (int) ($_POST['id'] ?? 0);
        $nuevoEstado = isset($_POST['estado']) ? (bool) $_POST['estado'] : null;

        if ($idProducto <= 0 || !is_bool($nuevoEstado)) {
            header("Location: index.php?opt=productos");
            exit;
        };

        $productomodel->actualizarEstado($idProducto, $nuevoEstado);

        $_SESSION['flash_success'] = "Estado actualizado correctamente.";
        header("Location: index.php?opt=productos");
        exit;

    // LISTAR LAS CATEGORIAS DE PRODUCTOS

    case 'categorias':    

        $categorias = $productomodel->listarCategorias();

        foreach ($categorias as $i => $c) {

            if (($categorias)[$i]['porcentaje_ganancia'] === null) {
                $c['porcentaje_ganancia'] = 0;
            }

            if (($categorias)[$i]['descuento'] === null) {
                $c['descuento'] = 0;
            }

            $categorias[$i]['porcentaje_ganancia'] = number_format($c['porcentaje_ganancia'], 2, '.', '') . ' %';
            $categorias[$i]['descuento'] = number_format($c['descuento'], 2, '.', '') . ' %';
        }

        ob_start();
        require __DIR__ . '/../views/productos/listaCategoriasView.php';
        return ob_get_clean();

    // CREAR NUEVA CATEGORIA DE PRODUCTOS

    case 'crear_categoria':

        if ($_SERVER['REQUEST_METHOD'] === 'GET') {
            ob_start();
            require __DIR__ . '/../views/productos/crearCategoriaView.php';
            return ob_get_clean();
        }

        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            
            $nombre = trim($_POST['nombre'] ?? '');

            // Normalización

            $porcentaje_gananciaRaw = trim($_POST['porcentaje_ganancia'] ?? '');
            $porcentaje_ganancia = $porcentaje_gananciaRaw === '' ? null : $porcentaje_gananciaRaw;

            $descuentoRaw = trim($_POST['descuento'] ?? '');
            $descuento = $descuentoRaw === '' ? null : $descuentoRaw;

            $errores = [];

            // Validaciones

            if ($nombre === '') {
                $errores[] = "El nombre no puede estar vacío.";
            } else if (!preg_match("/^[A-Za-zÁÉÍÓÚÑáéíóúñ0-9]+(?: [A-Za-zÁÉÍÓÚÑáéíóúñ0-9]+)*$/", $nombre)) {
                $errores[] = "El nombre solo puede contener letras, números y espacios.";
            } else if (strlen($nombre) < 2) {
                $errores[] = "El nombre debe tener al menos 2 caracteres.";
            } else if (strlen($nombre) > 50) {
                $errores[] = "El nombre no puede superar los 50 caracteres.";
            }

            if ($porcentaje_ganancia !== null) {

                if (!preg_match("/^\d{1,3}(\.\d{1,2})?$/", $porcentaje_ganancia)) {
                    $errores[] = "La ganancia debe ser un número válido con hasta 2 decimales.";
                } else if ((float)$porcentaje_ganancia <= 0 || (float)$porcentaje_ganancia > 100) {
                    $errores[] = "La ganancia debe estar entre 0 a 100.";
                }
            }

            if ($descuento !== null) {

                if (!preg_match("/^\d{1,3}(\.\d{1,2})?$/", $descuento)) {
                    $errores[] = "El descuento debe ser un número válido con hasta 2 decimales.";
                } else if ((float)$descuento < 0 || (float)$descuento > 100) {
                    $errores[] = "El descuento debe estar entre 0 a 100.";
                }
            }

            if (!empty($errores)) {
                $_SESSION['flash_error'] = implode('<br>', $errores);
                header("Location: index.php?opt=crear_categoria");
                exit;
            }

            if ($productomodel->crearCategoria([
                'nombre' => $nombre,
                'porcentaje_ganancia' => $porcentaje_ganancia !== null ? (float) $porcentaje_ganancia : null,
                'descuento' => $descuento !== null ? (float) $descuento : null
            ])) {
                $_SESSION['flash_success'] = "Categoría creada correctamente.";
            } else {
                $_SESSION['flash_error'] = "No se pudo crear la categoría.";
            }

            header("Location: index.php?opt=categorias");
            exit;
        }

    // EDITAR CATEGORIA

    case 'editar_categoria':

        $idEditar = (int) ($_GET['id'] ?? 0);

        if ($idEditar <= 0) {
            header("Location: index.php?opt=categorias");
            exit;
        }

        // Busco la categoría en la base de datos mediante el modelo

        $categorias = $productomodel->obtenerPorIdCategoria($idEditar);

        if (!$categorias) {
            header("Location: index.php?opt=categorias");
            exit;
        };

        // Si el descuento o el porcentaje_ganancia es null lo seteamos en 0

        if ($categorias['porcentaje_ganancia'] === null) {
            $categorias['porcentaje_ganancia'] = 0;
        }

        if ($categorias['descuento'] === null) {
            $categorias['descuento'] = 0;
        }

        // Mostrar datos de producto

        if ($_SERVER['REQUEST_METHOD'] === 'GET') {
            ob_start();
            require __DIR__ . '/../views/productos/editarCategoriaView.php';
            return ob_get_clean();
        }

        // Caso en donde se modifican los datos

        if ($_SERVER['REQUEST_METHOD'] === 'POST') {

            $nombre = trim($_POST['nombre'] ?? '');

            // Normalización

            $porcentaje_gananciaRaw = trim($_POST['porcentaje_ganancia'] ?? '');
            $porcentaje_ganancia = $porcentaje_gananciaRaw === '' ? null : $porcentaje_gananciaRaw;

            $descuentoRaw = trim($_POST['descuento'] ?? '');
            $descuento = $descuentoRaw === '' ? null : $descuentoRaw;

            $errores = [];

            // Validaciones

            if ($nombre === '') {
                $errores[] = "El nombre no puede estar vacío.";
            } else if (!preg_match("/^[A-Za-zÁÉÍÓÚÑáéíóúñ0-9]+(?: [A-Za-zÁÉÍÓÚÑáéíóúñ0-9]+)*$/", $nombre)) {
                $errores[] = "El nombre solo puede contener letras, números y espacios.";
            } else if (strlen($nombre) < 2) {
                $errores[] = "El nombre debe tener al menos 2 caracteres.";
            } else if (strlen($nombre) > 50) {
                $errores[] = "El nombre no puede superar los 50 caracteres.";
            }

            if ($porcentaje_ganancia !== null) {

                if (!preg_match("/^\d{1,3}(\.\d{1,2})?$/", $porcentaje_ganancia)) {
                    $errores[] = "La ganancia debe ser un número válido con hasta 2 decimales.";
                } else if ((float)$porcentaje_ganancia <= 0 || (float)$porcentaje_ganancia > 100) {
                    $errores[] = "La ganancia debe estar entre 0 a 100.";
                }
            }

            if ($descuento !== null) {

                if (!preg_match("/^\d{1,3}(\.\d{1,2})?$/", $descuento)) {
                    $errores[] = "El descuento debe ser un número válido con hasta 2 decimales.";
                } else if ((float)$descuento < 0 || (float)$descuento > 100) {
                    $errores[] = "El descuento debe estar entre 0 a 100.";
                }
            }

            if (!empty($errores)) {
                $_SESSION['flash_error'] = implode('<br>', $errores);
                header("Location: index.php?opt=editar_categoria&id=" . $idEditar);
                exit;
            }

            // Verificamos que la suma entre los descuentos no supere el 100%

            require_once __DIR__ . '/../models/productoModel.php';
            $productomodel = new productoModel();

            $productosDescuentos = $productomodel->obtenerDescuento($idEditar);

            foreach ($productosDescuentos as $i => $p) {
                
                if (($productosDescuentos[$i]['descuento'] + $descuento) > 100) {
                    $_SESSION['flash_error'] = "Existe al menos un producto que supera el 100% de sumatoria en el descuento. Verifique.";
                    header("Location:index.php?opt=editar_categoria&id=$idEditar");
                    exit;
                }
            }

            $guardarData = [
                'nombre' => $nombre,
                'porcentaje_ganancia' => $porcentaje_ganancia !== null ? (float) $porcentaje_ganancia : null,
                'descuento' => $descuento !== null ? (float) $descuento : null
            ];

            // Obtenemos productos con sus respectivos costos para recalcular el precio de venta

            require_once __DIR__ . '/../models/pedidoModel.php';
            $pedidomodel = new pedidoModel();

            $costosProductos = $pedidomodel->obtenerCostosPorCategoria($idEditar);

            if ($productomodel->actualizarPreciosPorCategoria($idEditar, $guardarData, $costosProductos)) {
                $_SESSION['flash_success'] = "Datos actualizados correctamente.";
            } else {
                $_SESSION['flash_error'] = "No se pudo actualizar la categoría.";
            }

            header("Location: index.php?opt=categorias");
            exit;
        }

    // DEFAULT (404)

    default:

        ob_start();
        require __DIR__ . '/../views/404View.php';
        return ob_get_clean();
}