<?php

require_once __DIR__ . '/../database/database.php';

class informeModel {

    private PDO $db;

    public function __construct() {
        $this->db = Database::getConnection();
    }

    // OBTENER BALANCE ANUAL

    public function obtenerBalanceAnual($anio) {

        $sql = "WITH meses AS (
                    SELECT generate_series(1,12) AS mes
                ),

                -- INGRESOS DE VENTAS

                ingresos_ventas AS (
                    SELECT mes, SUM(total) AS total FROM (
                        SELECT
                            EXTRACT(MONTH FROM v.fecha)::int AS mes,
                            SUM(v.total) AS total
                        FROM ventas v
                        WHERE EXTRACT(YEAR FROM v.fecha)::int = :anio
                        GROUP BY mes

                    ) sub GROUP BY mes
                ),

                -- INGRESOS DE SERVICIOS

                ingresos_servicios AS (
                    SELECT mes, SUM(total) AS total FROM (
                        SELECT
                            EXTRACT(MONTH FROM s.fecha_terminado)::int AS mes,
                            SUM(s.total) AS total
                        FROM servicios s
                        WHERE EXTRACT(YEAR FROM s.fecha_terminado)::int = :anio
                        GROUP BY mes
                    ) sub GROUP BY mes
                ),

                -- COSTOS DE PEDIDOS

                costos_pedidos AS (
                    SELECT mes, SUM(total) AS total FROM (
                        SELECT
                            EXTRACT(MONTH FROM p.fecha)::int AS mes,
                            SUM(p.total) AS total
                        FROM pedidos p
                        WHERE EXTRACT(YEAR FROM p.fecha)::int = :anio
                        GROUP BY mes
                    ) sub GROUP BY mes
                )

                -- SUMAS Y CALCULO DE UTILIDAD

                SELECT
                    m.mes,
                    COALESCE(SUM(iv.total),0) AS ventas,
                    COALESCE(SUM(isv.total),0) AS servicios,
                    COALESCE(SUM(cp.total),0) AS costos,
                    COALESCE(SUM(iv.total),0)
                    + COALESCE(SUM(isv.total),0)
                    - COALESCE(SUM(cp.total),0) AS utilidad
                FROM meses m
                LEFT JOIN ingresos_ventas iv ON (iv.mes = m.mes)
                LEFT JOIN ingresos_servicios isv ON (isv.mes = m.mes)
                LEFT JOIN costos_pedidos cp ON (cp.mes = m.mes)
                GROUP BY m.mes
                ORDER BY m.mes";

        try {

            $stmt = $this->db->prepare($sql);
            $stmt->bindValue(':anio', $anio, PDO::PARAM_INT);
            $stmt->execute();

            $resultados = $stmt->fetchAll(PDO::FETCH_ASSOC);

            $meses = [];
            $ventas = [];
            $servicios = [];
            $costos = [];
            $utilidades = [];

            $totalVentas = 0;
            $totalServicios = 0;
            $totalCostos = 0;
            $totalUtilidad = 0;

            $mejorMes = '';
            $maxUtilidad = null;

            // Calculo de totales

            foreach ($resultados as $row) {

                $meses[] = (int) $row['mes'];
                $ventas[] = (float) $row['ventas'];
                $servicios[] = (float) $row['servicios'];
                $costos[] = (float) $row['costos'];
                $utilidades[] = (float) $row['utilidad'];

                $totalVentas += $row['ventas'];
                $totalServicios += $row['servicios'];
                $totalCostos += $row['costos'];
                $totalUtilidad += $row['utilidad'];

                if ($maxUtilidad === null || $row['utilidad'] > $maxUtilidad) {
                    $maxUtilidad = $row['utilidad'];
                    $mejorMes = $row['mes'];
                }
            }

            // Mapeo de nombres de mes

            $nombresMeses = [
                1=>'Enero',2=>'Febrero',3=>'Marzo',4=>'Abril',
                5=>'Mayo',6=>'Junio',7=>'Julio',8=>'Agosto',
                9=>'Septiembre',10=>'Octubre',11=>'Noviembre',12=>'Diciembre'
            ];

            $mejorMesNombre = $nombresMeses[$mejorMes] ?? '';

            // Retorno de array completo

            return [
                'meses' => $meses,
                'ventas' => $ventas,
                'servicios' => $servicios,
                'costos' => $costos,
                'utilidad' => $utilidades,
                'kpis' => [
                    'totalIngresos' => $totalVentas + $totalServicios,
                    'totalCostos' => $totalCostos,
                    'resultado' => $totalUtilidad,
                    'mejorMes' => $mejorMesNombre
                ]
            ];

        } catch (PDOException $e) {

            // Log interno

            error_log($e->getMessage());

            return [];
        }
    }

    // OBTENER MONTOS A COBRAR

    public function obtenerACobrar($anio) {

        $sql = "WITH meses AS (
                    SELECT generate_series(1,12) AS mes
                ),

                -- SERVICIOS PENDIENTES

                servicios_pendientes AS (
                    SELECT 
                        EXTRACT(MONTH FROM s.fecha_registro)::int AS mes,
                        SUM(s.total) AS total
                    FROM servicios s
                    WHERE s.estado = 'pendiente - enviado'
                    AND EXTRACT(YEAR FROM s.fecha_registro)::int = :anio
                    GROUP BY mes
                )

                -- RESULTADO FINAL

                SELECT 
                    m.mes,
                    COALESCE(sp.total,0) AS servicios
                FROM meses m
                LEFT JOIN servicios_pendientes sp ON (sp.mes = m.mes)
                ORDER BY m.mes";

        try {
            $stmt = $this->db->prepare($sql);
            $stmt->bindValue(':anio', $anio, PDO::PARAM_INT);
            $stmt->execute();

            $resultados = $stmt->fetchAll(PDO::FETCH_ASSOC);

            $meses = $totales = [];

            foreach ($resultados as $row) {
                $meses[] = (int) $row['mes'];
                $totales[] = (float) $row['servicios'];
            }

            return [
                'meses' => $meses,
                'totales' => $totales,
                'kpis' => [
                    'totalACobrar' => array_sum($totales)
                ]
            ];

        } catch (PDOException $e) {

            // Log interno

            error_log($e->getMessage());

            return [];
        }
    }
}