<?php
/**
 * Modelo Reporte
 * Consultas optimizadas para generación de reportes de letras
 */
class Reporte
{
    private PDO $db;

    public function __construct()
    {
        $this->db = Conexion::getConexion();
    }

    /**
     * Obtener letras para reporte filtradas por rango de fechas de vencimiento y empresa
     * Agrupadas por empresa
     * 
     * @param string $fechaDesde Fecha vencimiento desde (Y-m-d)
     * @param string $fechaHasta Fecha vencimiento hasta (Y-m-d)
     * @param array $empresaIds Empty = todas las empresas
     * @return array Datos agrupados por empresa
     */
    public function getReporteLetras(string $fechaDesde, string $fechaHasta, array $empresaIds = []): array
    {
        $sql = "SELECT l.id, l.numero_en_grupo as n, l.grupo_id as g, l.numero_letra as documento,
                DATE_FORMAT(l.fecha_emision, '%d/%m/%Y') as fec_emision,
                DATE_FORMAT(l.created_at, '%d/%m/%Y') as fec_ingreso,
                l.fecha_vencimiento,
                DATE_FORMAT(l.fecha_vencimiento, '%d/%m/%Y') as fecha_vec_formato,
                l.fecha_pago,
                DATE_FORMAT(l.fecha_pago, '%d/%m/%Y') as fecha_pag_formato,
                l.importe as total,
                l.moneda,
                l.observaciones as obs,
                DATEDIFF(l.fecha_pago, CURDATE()) as dias_restantes,
                l.banco,
                l.estado,
                CASE 
                    WHEN l.tipo_letra = 'REN' THEN 'R'
                    WHEN l.estado = 'pagada' THEN 'A'
                    WHEN l.estado = 'renovada' THEN 'R'
                    WHEN l.estado = 'pendiente' THEN 'P'
                    WHEN l.estado = 'vencida' THEN 'V'
                    WHEN l.estado = 'protestada' THEN 'PR'
                    ELSE l.estado
                END as estado_letra,
                l.referencia_unica,
                l.tipo_letra,
                e.id as empresa_id,
                e.razon_social,
                g2.documento_sunat
                FROM letras l
                INNER JOIN empresas e ON l.empresa_id = e.id
                INNER JOIN grupos_letras g2 ON l.grupo_id = g2.id
                WHERE l.fecha_vencimiento BETWEEN :fecha_desde AND :fecha_hasta";
        
        $params = [
            ':fecha_desde' => $fechaDesde,
            ':fecha_hasta' => $fechaHasta,
        ];

        if (!empty($empresaIds)) {
            $placeholders = [];
            foreach ($empresaIds as $i => $id) {
                $key = ":emp_id_{$i}";
                $placeholders[] = $key;
                $params[$key] = $id;
            }
            $sql .= " AND l.empresa_id IN (" . implode(',', $placeholders) . ")";
        }

        $sql .= " ORDER BY e.razon_social ASC, l.fecha_vencimiento ASC";

        $stmt = $this->db->prepare($sql);
        $stmt->execute($params);
        $letras = $stmt->fetchAll();

        // Agrupar por empresa
        $agrupado = [];
        foreach ($letras as $letra) {
            $empresaNombre = $letra['razon_social'];
            if (!isset($agrupado[$empresaNombre])) {
                $agrupado[$empresaNombre] = [
                    'empresa_id'    => $letra['empresa_id'],
                    'razon_social'  => $empresaNombre,
                    'letras'        => [],
                    'total_dolares' => 0,
                    'total_soles'   => 0,
                    'cantidad'      => 0,
                ];
            }
            $agrupado[$empresaNombre]['letras'][] = $letra;
            $agrupado[$empresaNombre]['cantidad']++;
            
            if ($letra['moneda'] === 'USD') {
                $agrupado[$empresaNombre]['total_dolares'] += (float)$letra['total'];
            } else {
                $agrupado[$empresaNombre]['total_soles'] += (float)$letra['total'];
            }
        }

        return $agrupado;
    }

    /**
     * Obtener totales generales del reporte
     */
    public function getTotalesReporte(string $fechaDesde, string $fechaHasta, array $empresaIds = []): array
    {
        $sql = "SELECT 
                COUNT(*) as total_letras,
                COALESCE(SUM(CASE WHEN moneda = 'USD' THEN importe ELSE 0 END), 0) as total_dolares,
                COALESCE(SUM(CASE WHEN moneda = 'PEN' THEN importe ELSE 0 END), 0) as total_soles,
                COUNT(CASE WHEN estado = 'pendiente' THEN 1 END) as letras_pendientes
                FROM letras 
                WHERE fecha_vencimiento BETWEEN :fecha_desde AND :fecha_hasta";
        
        $params = [
            ':fecha_desde' => $fechaDesde,
            ':fecha_hasta' => $fechaHasta,
        ];

        if (!empty($empresaIds)) {
            $placeholders = [];
            foreach ($empresaIds as $i => $id) {
                $key = ":emp_id_{$i}";
                $placeholders[] = $key;
                $params[$key] = $id;
            }
            $sql .= " AND empresa_id IN (" . implode(',', $placeholders) . ")";
        }

        $stmt = $this->db->prepare($sql);
        $stmt->execute($params);
        return $stmt->fetch();
    }
}
