<?php

class presupuestoModel {

    private string $presupuestoKey = 'productosPresupuesto';
    private ?string $error = null;

    public function __construct() {

        if (!isset($_SESSION[$this->presupuestoKey])) {
            $_SESSION[$this->presupuestoKey] = [];
        }
    }

    // MÉTODO PARA OBTENER ERRORES E INFORMAR A TRAVEZ DEL CONTROLLER

    public function getError(): ?string {
        return $this->error;
    }

    // AGREGAR PRODUCTO

    public function agregarProducto(array $producto, int $cantidad): bool {

        if ($cantidad <= 0 || empty($producto['id'])) {
            $this->error = 'Datos inválidos del producto.';
            return false;
        }

        $id = $producto['id'];

        $cantidadActual = $_SESSION[$this->presupuestoKey][$id]['cantidad'] ?? 0;
        $stockDisponible = $producto['stock'];

        if (($cantidadActual + $cantidad) > $stockDisponible) {
            $this->error = 'La cantidad supera el stock disponible.';
            return false;
        }

        $descuentoTotal = $producto['descuento_producto'] + $producto['descuento_categoria'];

        $precioFinal = ((100 - $descuentoTotal) * $producto['precio'] / 100); // PRECIO UNITARIO MENOS EL DESCUENTO

        if (isset($_SESSION[$this->presupuestoKey][$id])) {
            $_SESSION[$this->presupuestoKey][$id]['cantidad'] = $cantidad;
            return true;
        }

        $_SESSION[$this->presupuestoKey][$id] = [
            'id_producto' => $id,
            'marca' => $producto['marca'],
            'modelo' => $producto['modelo'],
            'precio' => $producto['precio'],
            'descuento_total' => $descuentoTotal,
            'cantidad' => $cantidad,
            'stock' => $producto['stock'],
            'precio_final' => $precioFinal
        ];

        return true;
    }

    // LISTAR PRODUCTOS

    public function listarProductos(): array {
        return $_SESSION[$this->presupuestoKey];
    }

    // ELIMINAR PRODUCTO

    public function eliminarProducto(int $id): bool {

        if (!isset($_SESSION[$this->presupuestoKey][$id])) {
            $this->error = 'El producto no existe en la caja.';
            return false;
        } else{
            unset($_SESSION[$this->presupuestoKey][$id]);
        }

        return true;
    }

    // EDITAR CANTIDAD DE PRODUCTO

    public function editarCantidad(int $id, int $nuevaCantidad): bool {

        if (!isset($_SESSION[$this->presupuestoKey][$id])) {
            $this->error = 'Producto inexistente en la caja.';
            return false;
        }

        if ($nuevaCantidad <= 0) {
            $this->error = 'La cantidad debe ser mayor a cero.';
            return false;
        }

        if ($nuevaCantidad > $_SESSION[$this->presupuestoKey][$id]['stock']) {
            $this->error = 'La cantidad supera el stock disponible.';
            return false;
        }

        $_SESSION[$this->presupuestoKey][$id]['cantidad'] = $nuevaCantidad;
        return true;
    }

    // CALCULAR SUBTOTAL

    public function calcularSubtotal(): float {

        $total = 0;

        foreach ($_SESSION[$this->presupuestoKey] as $item) {
            
            $precio = (float) $item['precio'];

            $total += $precio * $item['cantidad'];
        }

        return round($total, 2);
    }

    // CALCULAR PRECIO TOTAL

    public function calcularPrecioTotal(): float {

        $total = 0;

        foreach ($_SESSION[$this->presupuestoKey] as $item) {
            
            $precio = (float) $item['precio'];

            if (!empty($item['descuento_total'])) {
                $precio -= ($item['descuento_total'] * $precio / 100);
            }

            $total += $precio * $item['cantidad'];
        }

        return round($total, 2);
    }

    // CALCULAR DESCUENTO TOTAL

    public function calcularDescuentoTotal(): float {

        $total = 0;

        foreach ($_SESSION[$this->presupuestoKey] as $item) {
            
            $precio = (float) $item['precio'];
            $descuento = 0;

            if (!empty($item['descuento_total'])) {
                $descuento += ($item['descuento_total'] * $precio / 100);
            }

            $total += $descuento * $item['cantidad'];
        }

        return round($total, 2);
    }

    // VACIAR CAJA DE PRODUCTOS

    public function vaciarCajaPresupuesto(): bool {
        $_SESSION[$this->presupuestoKey] = [];
        return true;
    }

    // CALCULAR TOTAL PROVISORIO APLICANDO DESCUENTO Y RECARGO EN BASE A TIPO Y FORMA DE PAGO

    public function actualizarDatosProvisorio($descuentoPresupuesto, $recargoPresupuesto, $subtotal, $descuento): ?array {

        // El descuento propio del presupuesto se calcula en base al subtotal con los descuento de productos aplicados

        $descuentoProvisorio = ($descuentoPresupuesto * ($subtotal - $descuento) / 100) + $descuento; // Sumamos los dos descuentos

        // Calculo el recargo teniendo en cuenta el subtotal (descuentos de productos ya aplicados)

        $recargoProvisorio = ($recargoPresupuesto * ($subtotal - $descuento) / 100);

        $totalProvisorio = $subtotal + $recargoProvisorio - $descuentoProvisorio;
        
        return $_SESSION['prov_presupuesto'] = [
            'recargo' => $recargoProvisorio,
            'descuento' => $descuentoProvisorio,
            'total' => $totalProvisorio
        ];
    }
}