<?php
namespace App\Models;
use CodeIgniter\Model;
class VentasModel extends Model {
    protected $table = 'VentasCabecera';
    protected $primaryKey = 'Ven_Id';

    // Campos permitidos para operaciones de inserción o actualización
    protected $allowedFields = [
        'Cli_Id', 
        'Ven_FechaVenta', 
        'Ven_ValorTotal', 
        'Ven_Descuento', 
        'Ven_ValorEnvioNacional', 
        'Ven_NumeroFactura', 
        'Tpe_Id',
        'Ven_TotalPagoCliente',
        'Ven_EnvioGratis',
        'Ven_RegaloInfluencer'
    ];

    protected $useTimestamps = false; // Si no tienes campos created_at/updated_at, esto queda en false
    protected $returnType    = 'array'; // Devuelve resultados como array

    // Validaciones (opcional)
    protected $validationRules = [
        'Cli_Id'              => 'required|integer',
        'Ven_FechaVenta'      => 'required|valid_date',
        'Ven_ValorTotal'      => 'required|decimal',
        'Ven_Descuento'       => 'permit_empty|decimal',
        'Ven_ValorEnvioNacional' => 'permit_empty|decimal',
        'Ven_NumeroFactura'   => 'permit_empty|string',
        'Tpe_Id'              => 'required|integer'
    ];
    protected $validationMessages = [];
    protected $skipValidation     = false;

    // CRUD Methods
    public function getAllVentas()
    {
        return $this->findAll();
    }

    public function getById($id)
    {
        return $this->find($id);
    }

    public function create($data)
    {
        return $this->insert($data);
    }

    public function updateById($id, $data)
    {
        return $this->update($id, $data);
    }

    public function deleteById($id)
    {
        return $this->delete($id);
    }
    public function getVentasConDetalles()
    {
        $db = \Config\Database::connect();

        $query = $db->query("
            SELECT *
            FROM VentasCabecera vc
            LEFT JOIN VentasDetalle vd ON vc.Ven_Id = vd.Ven_Id
            INNER JOIN Clientes cl ON cl.Cli_Id = vc.Cli_Id
            INNER JOIN TipoPagoExterno tpe on tpe.Tpe_Id=vc.Tpe_Id
            INNER JOIN Productos pro on pro.Pro_Id=vd.Pro_Id
            ORDER BY Ven_FechaVenta ASC
        ");

        $result = $query->getResultArray(); 
        $ventas = [];

        // Estructurar los datos en un array anidado
        foreach ($result as $row) {
            $ventaId = $row['Ven_Id'];

            if (!isset($ventas[$ventaId])) {
                $ventas[$ventaId] = [
                    'cabecera' => [
                        'Ven_Id' => $row['Ven_Id'],
                        'Cli_Id' => $row['Cli_Nombre'],
                        'Ven_FechaVenta' => $row['Ven_FechaVenta'],
                        'Ven_ValorTotal' => $row['Ven_ValorTotal'],
                        'Ven_Descuento' => $row['Ven_Descuento'],
                        'Ven_ValorEnvioNacional' => $row['Ven_ValorEnvioNacional'],
                        'Ven_TotalPagoCliente' => $row['Ven_TotalPagoCliente'],
                        'Ven_EnvioGratis' => $row['Ven_EnvioGratis'],
                        'Ven_RegaloInfluencer' => $row['Ven_RegaloInfluencer'],
                        'Tpe_Id' => $row['Tpe_Nombre']
                    ],
                    'detalles' => []
                ];
            }

            // Agregar el detalle si existe
            if (!empty($row['Ved_Id'])) {
                $ventas[$ventaId]['detalles'][] = [
                    'Ved_Id' => $row['Ved_Id'],
                    'Pro_Nombre' => $row['Pro_Nombre'],
                    'Ved_Cantidad' => $row['Ved_Cantidad'],
                    'Ved_ValorUnitario' => $row['Ved_ValorUnitario'],
                    'Ved_ValorTotal' => $row['Ved_ValorTotal'],
                    'Ved_Observacion' => $row['Ved_Observacion'],
                    'Ved_Descuento' => $row['Ved_Descuento'],
                    'Ved_ValorUnitario_Real' => $row['Ved_ValorUnitario_Real']
                ];
            }
        }

        return $ventas;
    }
    public function obtenerVentasPorProducto($producto_id, $fecha_inicio, $fecha_fin) {
        return $this->db->table('VentasDetalle vd')
            ->select('vc.Ven_Id, vc.Ven_FechaVenta, c.Cli_Nombre, p.Pro_Nombre, vd.Ved_Cantidad, vd.Ved_ValorUnitario')
            ->join('VentasCabecera vc', 'vd.Ven_Id = vc.Ven_Id')
            ->join('Clientes c', 'vc.Cli_Id = c.Cli_Id')
            ->join('Productos p', 'vd.Pro_Id = p.Pro_Id')
            ->where('vd.Pro_Id', $producto_id)
            ->where('vc.Ven_FechaVenta >=', $fecha_inicio)
            ->where('vc.Ven_FechaVenta <=', $fecha_fin)
            ->orderBy('vc.Ven_FechaVenta', 'DESC')
            ->get()
            ->getResultArray();
    }
    public function obtenerVentasPorCliente($cliente_id) {
        return $this->db->table('VentasDetalle vd')
            ->select('vc.Ven_Id, vc.Ven_FechaVenta, c.Cli_Nombre, p.Pro_Nombre, vd.Ved_Cantidad, vd.Ved_ValorUnitario')
            ->join('VentasCabecera vc', 'vd.Ven_Id = vc.Ven_Id')
            ->join('Clientes c', 'vc.Cli_Id = c.Cli_Id')
            ->join('Productos p', 'vd.Pro_Id = p.Pro_Id')
            ->where('vc.Cli_Id', $cliente_id)
            ->orderBy('vc.Ven_FechaVenta', 'DESC')
            ->get()
            ->getResultArray();
    }
    public function obtenerClientesAlerta() {
        $query = $this->db->query(
            "WITH FechasCompras AS (
                SELECT vc.Cli_Id, vc.Ven_FechaVenta, 
                    LEAD(vc.Ven_FechaVenta) OVER (PARTITION BY vc.Cli_Id ORDER BY vc.Ven_FechaVenta) AS siguiente_compra,
                    SUM(vd.Ved_Cantidad) OVER (PARTITION BY vc.Cli_Id ORDER BY vc.Ven_FechaVenta) AS total_productos,p.Pro_Nombre as producto
                FROM VentasCabecera vc
                JOIN VentasDetalle vd ON vc.Ven_Id = vd.Ven_Id
                JOIN Productos p ON p.Pro_ID=vd.Pro_Id
            ),
            PromedioCompras AS (
                SELECT Cli_Id, 
                    AVG(DATEDIFF(siguiente_compra, Ven_FechaVenta)) AS promedio_dias,
                    MAX(siguiente_compra) AS ultima_compra_real,
                    AVG(total_productos) AS promedio_productos,producto
                FROM FechasCompras
                WHERE siguiente_compra IS NOT NULL
                GROUP BY Cli_Id
            )
            SELECT p.Cli_Id, c.Cli_Nombre, p.promedio_dias, p.ultima_compra_real AS ultima_compra, p.promedio_productos,
                DATE_ADD(p.ultima_compra_real, INTERVAL p.promedio_dias DAY) AS proxima_compra,p.producto
            FROM PromedioCompras p
            JOIN Clientes c ON p.Cli_Id = c.Cli_Id
            WHERE DATE_ADD(p.ultima_compra_real, INTERVAL p.promedio_dias DAY) <= CURDATE() + INTERVAL 3 DAY
            ORDER BY proxima_compra ASC"
        );
        return $query->getResultArray();
    }
    
    public function obtener_ventas_por_mes() {
        return $this->db->query(
            "SELECT MONTH(Ven_FechaVenta) AS mes, SUM(Ven_ValorTotal) AS total_ventas 
            FROM VentasCabecera 
            WHERE YEAR(Ven_FechaVenta) = YEAR(CURDATE()) 
            GROUP BY mes 
            ORDER BY mes"
        )->getResultArray();
    }

    public function obtener_ventas_por_producto() {
        return $this->db->query(
            "SELECT p.Pro_Nombre, SUM(vd.Ved_Cantidad) AS total_vendido 
            FROM VentasDetalle vd 
            JOIN Productos p ON vd.Pro_Id = p.Pro_Id 
            JOIN VentasCabecera vc ON vd.Ven_Id = vc.Ven_Id 
            WHERE YEAR(vc.Ven_FechaVenta) = YEAR(CURDATE()) 
            GROUP BY p.Pro_Nombre 
            ORDER BY total_vendido DESC"
        )->getResultArray();
    }

    public function obtener_ventas_productos_por_mes() {
        return $this->db->query(
            "SELECT MONTH(vc.Ven_FechaVenta) AS mes, p.Pro_Nombre, SUM(vd.Ved_Cantidad) AS total_vendido 
            FROM VentasDetalle vd 
            JOIN Productos p ON vd.Pro_Id = p.Pro_Id 
            JOIN VentasCabecera vc ON vd.Ven_Id = vc.Ven_Id 
            WHERE YEAR(vc.Ven_FechaVenta) = YEAR(CURDATE()) 
            GROUP BY mes, p.Pro_Nombre 
            ORDER BY mes, total_vendido DESC"
        )->getResultArray();
    }
    public function obtener_formulas_por_mes() {
        return $this->db->query(
            "SELECT MONTH(vc.Ven_FechaVenta) AS mes, SUM(vd.Ved_Cantidad) AS total_formulas 
            FROM VentasDetalle vd 
            JOIN Productos p ON vd.Pro_Id = p.Pro_Id 
            JOIN VentasCabecera vc ON vd.Ven_Id = vc.Ven_Id 
            WHERE YEAR(vc.Ven_FechaVenta) = YEAR(CURDATE()) 
            AND CONVERT(p.Pro_Nombre USING utf8mb4) COLLATE utf8mb4_general_ci LIKE '%HiPP%'
            GROUP BY mes 
            ORDER BY mes"
        )->getResultArray();
    }
}
?>
