using GestionIntegral.Api.Data.Repositories.Distribucion;
using GestionIntegral.Api.Data.Repositories.Reportes;
using GestionIntegral.Api.Data.Repositories.Suscripciones;
using GestionIntegral.Api.Dtos.Reportes;
using GestionIntegral.Api.Services.Contables;

namespace GestionIntegral.Api.Services.Reportes
{
    public class ReportesService : IReportesService
    {
        private readonly IReportesRepository _reportesRepository;
        private readonly IFacturaRepository _facturaRepository;
        private readonly IFacturaDetalleRepository _facturaDetalleRepository;
        private readonly IPublicacionRepository _publicacionRepository;
        private readonly IEmpresaRepository _empresaRepository;
        private readonly ISuscriptorRepository _suscriptorRepository;
        private readonly ISuscripcionRepository _suscripcionRepository;
        private readonly ICierreCuentaCorrienteService _cierreService;
        private readonly ILogger<ReportesService> _logger;

        public ReportesService(IReportesRepository reportesRepository, IFacturaRepository facturaRepository, IFacturaDetalleRepository facturaDetalleRepository, IPublicacionRepository publicacionRepository, IEmpresaRepository empresaRepository
            , ISuscriptorRepository suscriptorRepository, ISuscripcionRepository suscripcionRepository, ICierreCuentaCorrienteService cierreService, ILogger<ReportesService> logger)
        {
            _reportesRepository = reportesRepository;
            _facturaRepository = facturaRepository;
            _facturaDetalleRepository = facturaDetalleRepository;
            _publicacionRepository = publicacionRepository;
            _empresaRepository = empresaRepository;
            _suscriptorRepository = suscriptorRepository;
            _suscripcionRepository = suscripcionRepository;
            _cierreService = cierreService;
            _logger = logger;
        }

        public async Task<(IEnumerable<ExistenciaPapelDto> Data, string? Error)> ObtenerExistenciaPapelAsync(
            DateTime fechaDesde, DateTime fechaHasta, int? idPlanta, bool consolidado)
        {
            if (fechaDesde > fechaHasta)
            {
                return (Enumerable.Empty<ExistenciaPapelDto>(), "La fecha 'Desde' no puede ser mayor que la fecha 'Hasta'.");
            }

            if (!consolidado && !idPlanta.HasValue)
            {
                return (Enumerable.Empty<ExistenciaPapelDto>(), "Se requiere un ID de planta para reportes no consolidados.");
            }

            try
            {
                var dataFromRepo = await _reportesRepository.GetExistenciaPapelAsync(fechaDesde, fechaHasta, idPlanta, consolidado);
                var dataWithUtcDates = dataFromRepo.Select(dto =>
                {
                    if (dto.FechaEstimacionFinStock.HasValue)
                    {
                        dto.FechaEstimacionFinStock = DateTime.SpecifyKind(dto.FechaEstimacionFinStock.Value.Date, DateTimeKind.Utc);
                    }
                    return dto;
                }).ToList();
                return (dataWithUtcDates, null);
            }
            catch (ArgumentNullException ex) when (ex.ParamName == "idPlanta")
            {
                _logger.LogWarning(ex, "ArgumentNullException para idPlanta en ObtenerExistenciaPapelAsync.");
                return (Enumerable.Empty<ExistenciaPapelDto>(), ex.Message);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error en ReportesService al obtener Existencia de Papel.");
                return (Enumerable.Empty<ExistenciaPapelDto>(), "Error interno al generar el reporte de existencia de papel.");
            }
        }

        public async Task<(IEnumerable<MovimientoBobinasDto> Data, string? Error)> ObtenerMovimientoBobinasAsync(DateTime fechaDesde, DateTime fechaHasta, int idPlanta)
        {
            if (fechaDesde > fechaHasta)
            {
                return (Enumerable.Empty<MovimientoBobinasDto>(), "La fecha 'Desde' no puede ser mayor que la fecha 'Hasta'.");
            }
            int diasPeriodo = (fechaHasta.Date - fechaDesde.Date).Days + 1;

            try
            {
                var data = await _reportesRepository.GetMovimientoBobinasAsync(fechaDesde.Date, diasPeriodo, idPlanta);
                return (data, null);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error en ReportesService al obtener Movimiento de Bobinas.");
                return (Enumerable.Empty<MovimientoBobinasDto>(), "Error interno al generar el reporte de movimiento de bobinas.");
            }
        }

        public async Task<(IEnumerable<MovimientoBobinaEstadoDetalleDto> Detalle, IEnumerable<MovimientoBobinaEstadoTotalDto> Totales, string? Error)> ObtenerMovimientoBobinasPorEstadoAsync(DateTime fechaDesde, DateTime fechaHasta, int idPlanta)
        {
            if (fechaDesde > fechaHasta)
            {
                return (Enumerable.Empty<MovimientoBobinaEstadoDetalleDto>(), Enumerable.Empty<MovimientoBobinaEstadoTotalDto>(), "La fecha 'Desde' no puede ser mayor que la fecha 'Hasta'.");
            }

            try
            {
                var detalle = await _reportesRepository.GetMovimientoBobinasEstadoDetalleAsync(fechaDesde.Date, fechaHasta.Date, idPlanta);
                var totales = await _reportesRepository.GetMovimientoBobinasEstadoTotalesAsync(fechaDesde.Date, fechaHasta.Date, idPlanta);

                var detalleUtc = detalle.Select(d =>
                {
                    d.FechaMovimiento = DateTime.SpecifyKind(d.FechaMovimiento, DateTimeKind.Utc);
                    return d;
                }).ToList();

                return (detalleUtc, totales, null);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error en ReportesService al obtener Movimiento de Bobinas por Estado.");
                return (Enumerable.Empty<MovimientoBobinaEstadoDetalleDto>(), Enumerable.Empty<MovimientoBobinaEstadoTotalDto>(), "Error interno al generar el reporte de movimiento de bobinas por estado.");
            }
        }

        public async Task<(IEnumerable<ListadoDistribucionGeneralResumenDto> Resumen, IEnumerable<ListadoDistribucionGeneralPromedioDiaDto> Promedios, string? Error)> ObtenerListadoDistribucionGeneralAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta)
        {
            if (fechaDesde > fechaHasta)
                return (Enumerable.Empty<ListadoDistribucionGeneralResumenDto>(), Enumerable.Empty<ListadoDistribucionGeneralPromedioDiaDto>(), "La fecha 'Desde' no puede ser mayor que la fecha 'Hasta'.");

            try
            {
                // El SP SP_DistObtenerResumenMensual usa Mes y Año de fechaDesde.
                // El SP SP_DistObtenerResumenMensualPorDiaSemana también.
                var resumenData = await _reportesRepository.GetListadoDistribucionGeneralResumenAsync(idPublicacion, fechaDesde, fechaHasta);
                var promediosData = await _reportesRepository.GetListadoDistribucionGeneralPromedioDiaAsync(idPublicacion, fechaDesde, fechaHasta);

                var resumenUtc = resumenData.Select(r => { r.Fecha = DateTime.SpecifyKind(r.Fecha, DateTimeKind.Utc); return r; }).ToList();

                return (resumenUtc, promediosData, null);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error en ReportesService al obtener Listado Distribucion General.");
                return (Enumerable.Empty<ListadoDistribucionGeneralResumenDto>(), Enumerable.Empty<ListadoDistribucionGeneralPromedioDiaDto>(), "Error interno al generar el reporte.");
            }
        }

        public async Task<(IEnumerable<ListadoDistribucionCanillasSimpleDto> Simple, IEnumerable<ListadoDistribucionCanillasPromedioDiaDto> Promedios, string? Error)> ObtenerListadoDistribucionCanillasAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta)
        {
            if (fechaDesde > fechaHasta)
                return (Enumerable.Empty<ListadoDistribucionCanillasSimpleDto>(), Enumerable.Empty<ListadoDistribucionCanillasPromedioDiaDto>(), "La fecha 'Desde' no puede ser mayor que la fecha 'Hasta'.");

            try
            {
                var simpleData = await _reportesRepository.GetListadoDistribucionCanillasSimpleAsync(idPublicacion, fechaDesde, fechaHasta);
                var promediosData = await _reportesRepository.GetListadoDistribucionCanillasPromedioDiaAsync(idPublicacion, fechaDesde, fechaHasta);
                return (simpleData, promediosData, null);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error en ReportesService al obtener Listado Distribucion Canillas.");
                return (Enumerable.Empty<ListadoDistribucionCanillasSimpleDto>(), Enumerable.Empty<ListadoDistribucionCanillasPromedioDiaDto>(), "Error interno al generar el reporte.");
            }
        }

        public async Task<(IEnumerable<ListadoDistribucionCanillasImporteDto> Data, string? Error)> ObtenerListadoDistribucionCanillasConImporteAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta, bool esAccionista)
        {
            if (fechaDesde > fechaHasta)
                return (Enumerable.Empty<ListadoDistribucionCanillasImporteDto>(), "La fecha 'Desde' no puede ser mayor que la fecha 'Hasta'.");

            try
            {
                var data = await _reportesRepository.GetListadoDistribucionCanillasImporteAsync(idPublicacion, fechaDesde, fechaHasta, esAccionista);
                return (data, null);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error en ReportesService al obtener Listado Distribucion Canillas con Importe.");
                return (Enumerable.Empty<ListadoDistribucionCanillasImporteDto>(), "Error interno al generar el reporte.");
            }
        }

        public async Task<(IEnumerable<VentaMensualSecretariaElDiaDto> Data, string? Error)> ObtenerVentaMensualSecretariaElDiaAsync(DateTime fechaDesde, DateTime fechaHasta)
        {
            if (fechaDesde > fechaHasta) return (Enumerable.Empty<VentaMensualSecretariaElDiaDto>(), "La fecha 'Desde' no puede ser mayor que la fecha 'Hasta'.");
            try
            {
                var data = await _reportesRepository.GetVentaMensualSecretariaElDiaAsync(fechaDesde, fechaHasta);
                return (data, null);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error en ReportesService al obtener Venta Mensual Secretaria El Dia.");
                return (Enumerable.Empty<VentaMensualSecretariaElDiaDto>(), "Error interno al generar el reporte.");
            }
        }

        public async Task<(IEnumerable<VentaMensualSecretariaElPlataDto> Data, string? Error)> ObtenerVentaMensualSecretariaElPlataAsync(DateTime fechaDesde, DateTime fechaHasta)
        {
            if (fechaDesde > fechaHasta) return (Enumerable.Empty<VentaMensualSecretariaElPlataDto>(), "La fecha 'Desde' no puede ser mayor que la fecha 'Hasta'.");
            try
            {
                var data = await _reportesRepository.GetVentaMensualSecretariaElPlataAsync(fechaDesde, fechaHasta);
                return (data, null);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error en ReportesService al obtener Venta Mensual Secretaria El Plata.");
                return (Enumerable.Empty<VentaMensualSecretariaElPlataDto>(), "Error interno al generar el reporte.");
            }
        }

        public async Task<(IEnumerable<VentaMensualSecretariaTirDevoDto> Data, string? Error)> ObtenerVentaMensualSecretariaTirDevoAsync(DateTime fechaDesde, DateTime fechaHasta)
        {
            if (fechaDesde > fechaHasta) return (Enumerable.Empty<VentaMensualSecretariaTirDevoDto>(), "La fecha 'Desde' no puede ser mayor que la fecha 'Hasta'.");
            try
            {
                var data = await _reportesRepository.GetVentaMensualSecretariaTirDevoAsync(fechaDesde, fechaHasta);
                return (data, null);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error en ReportesService al obtener Venta Mensual Secretaria Tirada/Devolucion.");
                return (Enumerable.Empty<VentaMensualSecretariaTirDevoDto>(), "Error interno al generar el reporte.");
            }
        }

        public async Task<(
    IEnumerable<DetalleDistribucionCanillaDto> Canillas,
    IEnumerable<DetalleDistribucionCanillaDto> CanillasAcc,
    IEnumerable<DetalleDistribucionCanillaAllDto> CanillasAll,
    IEnumerable<DetalleDistribucionCanillaDto> CanillasFechaLiq,
    IEnumerable<DetalleDistribucionCanillaDto> CanillasAccFechaLiq,
    IEnumerable<ObtenerCtrlDevolucionesDto> CtrlDevolucionesRemitos,
    IEnumerable<ControlDevolucionesReporteDto> CtrlDevolucionesParaDistCan,
    IEnumerable<DevueltosOtrosDiasDto> CtrlDevolucionesOtrosDias,
    string? Error
)> ObtenerReporteDistribucionCanillasAsync(DateTime fecha, int idEmpresa, bool? esAccionista)
        {
            try
            {
                // Función helper para convertir fechas a UTC
                Func<IEnumerable<DetalleDistribucionCanillaDto>, IEnumerable<DetalleDistribucionCanillaDto>> toUtc =
                    items => items?.Select(c => { if (c.Fecha.HasValue) c.Fecha = DateTime.SpecifyKind(c.Fecha.Value.Date, DateTimeKind.Utc); return c; }).ToList()
                             ?? Enumerable.Empty<DetalleDistribucionCanillaDto>();

                // --- NUEVA LÓGICA PARA "TODAS LAS EMPRESAS" ---
                if (idEmpresa == 0)
                {
                    Task<IEnumerable<DetalleDistribucionCanillaDto>> canillasTask = Task.FromResult(Enumerable.Empty<DetalleDistribucionCanillaDto>());
                    Task<IEnumerable<DetalleDistribucionCanillaDto>> canillasAccTask = Task.FromResult(Enumerable.Empty<DetalleDistribucionCanillaDto>());

                    if (esAccionista == true) // Solo accionistas
                    {
                        canillasAccTask = _reportesRepository.GetDetalleDistribucionCanillasAccPubli_AllEmpresasAsync(fecha);
                    }
                    else // Solo canillitas (o si es null, por defecto canillitas)
                    {
                        canillasTask = _reportesRepository.GetDetalleDistribucionCanillasPubli_AllEmpresasAsync(fecha);
                    }

                    await Task.WhenAll(canillasTask, canillasAccTask);

                    return (
                        toUtc(await canillasTask),
                        toUtc(await canillasAccTask),
                        Enumerable.Empty<DetalleDistribucionCanillaAllDto>(), // El resumen no aplica
                        Enumerable.Empty<DetalleDistribucionCanillaDto>(), // Liquidaciones de otras fechas no aplican en esta vista simplificada
                        Enumerable.Empty<DetalleDistribucionCanillaDto>(),
                        Enumerable.Empty<ObtenerCtrlDevolucionesDto>(), // Control de devoluciones no aplica
                        Enumerable.Empty<ControlDevolucionesReporteDto>(),
                        Enumerable.Empty<DevueltosOtrosDiasDto>(),
                        null
                    );
                }

                // --- LÓGICA ORIGINAL PARA UNA EMPRESA ESPECÍFICA ---
                var canillasTaskOriginal = _reportesRepository.GetDetalleDistribucionCanillasPubliAsync(fecha, idEmpresa);
                var canillasAccTaskOriginal = _reportesRepository.GetDetalleDistribucionCanillasAccPubliAsync(fecha, idEmpresa);
                var canillasAllTask = _reportesRepository.GetDetalleDistribucionCanillasAllPubliAsync(fecha, idEmpresa);
                var canillasFechaLiqTask = _reportesRepository.GetDetalleDistribucionCanillasPubliFechaLiqAsync(fecha, idEmpresa);
                var canillasAccFechaLiqTask = _reportesRepository.GetDetalleDistribucionCanillasAccPubliFechaLiqAsync(fecha, idEmpresa);
                var ctrlDevolucionesRemitosTask = _reportesRepository.GetReporteObtenerCtrlDevolucionesAsync(fecha, idEmpresa);
                var ctrlDevolucionesParaDistCanTask = _reportesRepository.GetReporteCtrlDevolucionesParaDistCanAsync(fecha, idEmpresa);
                var ctrlDevolucionesOtrosDiasTask = _reportesRepository.GetEntradaSalidaOtrosDiasAsync(fecha, idEmpresa);

                await Task.WhenAll(
                    canillasTaskOriginal, canillasAccTaskOriginal, canillasAllTask,
                    canillasFechaLiqTask, canillasAccFechaLiqTask,
                    ctrlDevolucionesRemitosTask, ctrlDevolucionesParaDistCanTask,
                    ctrlDevolucionesOtrosDiasTask
                );

                var detallesOriginales = await ctrlDevolucionesParaDistCanTask ?? Enumerable.Empty<ControlDevolucionesReporteDto>();
                var detallesOrdenados = detallesOriginales.OrderBy(d => d.Tipo).ToList();

                return (
                    toUtc(await canillasTaskOriginal),
                    toUtc(await canillasAccTaskOriginal),
                    await canillasAllTask ?? Enumerable.Empty<DetalleDistribucionCanillaAllDto>(),
                    toUtc(await canillasFechaLiqTask),
                    toUtc(await canillasAccFechaLiqTask),
                    await ctrlDevolucionesRemitosTask ?? Enumerable.Empty<ObtenerCtrlDevolucionesDto>(),
                    detallesOrdenados,
                    await ctrlDevolucionesOtrosDiasTask ?? Enumerable.Empty<DevueltosOtrosDiasDto>(),
                    null
                );
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error en ReportesService al obtener Reporte Distribucion Canillas para fecha {Fecha} y empresa {IdEmpresa}.", fecha, idEmpresa);
                return (
                    Enumerable.Empty<DetalleDistribucionCanillaDto>(),
                    Enumerable.Empty<DetalleDistribucionCanillaDto>(),
                    Enumerable.Empty<DetalleDistribucionCanillaAllDto>(),
                    Enumerable.Empty<DetalleDistribucionCanillaDto>(),
                    Enumerable.Empty<DetalleDistribucionCanillaDto>(),
                    Enumerable.Empty<ObtenerCtrlDevolucionesDto>(),
                    Enumerable.Empty<ControlDevolucionesReporteDto>(),
                    Enumerable.Empty<DevueltosOtrosDiasDto>(),
                    "Error interno al generar el reporte de distribución de canillas."
                );
            }
        }

        public async Task<(IEnumerable<TiradasPublicacionesSeccionesDto> Data, string? Error)> ObtenerTiradasPublicacionesSeccionesAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta, int idPlanta)
        {
            if (fechaDesde > fechaHasta) return (Enumerable.Empty<TiradasPublicacionesSeccionesDto>(), "Fecha 'Desde' no puede ser mayor que 'Hasta'.");
            try
            {
                var data = await _reportesRepository.GetTiradasPublicacionesSeccionesAsync(idPublicacion, fechaDesde, fechaHasta, idPlanta);
                return (data, null);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error en ReportesService al obtener Tiradas por Publicación y Secciones.");
                return (Enumerable.Empty<TiradasPublicacionesSeccionesDto>(), "Error interno al generar el reporte.");
            }
        }

        public async Task<(IEnumerable<TiradasPublicacionesSeccionesDto> Data, string? Error)> ObtenerTiradasPublicacionesSeccionesConsolidadoAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta)
        {
            if (fechaDesde > fechaHasta) return (Enumerable.Empty<TiradasPublicacionesSeccionesDto>(), "Fecha 'Desde' no puede ser mayor que 'Hasta'.");
            try
            {
                var data = await _reportesRepository.GetTiradasPublicacionesSeccionesConsolidadoAsync(idPublicacion, fechaDesde, fechaHasta);
                return (data, null);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error en ReportesService al obtener Tiradas por Publicación y Secciones (Consolidado).");
                return (Enumerable.Empty<TiradasPublicacionesSeccionesDto>(), "Error interno al generar el reporte.");
            }
        }

        public async Task<(IEnumerable<ConsumoBobinasSeccionDto> Data, string? Error)> ObtenerConsumoBobinasPorSeccionAsync(DateTime fechaDesde, DateTime fechaHasta, int idPlanta)
        {
            if (fechaDesde > fechaHasta) return (Enumerable.Empty<ConsumoBobinasSeccionDto>(), "Fecha 'Desde' no puede ser mayor que 'Hasta'.");
            try
            {
                var data = await _reportesRepository.GetConsumoBobinasPorSeccionAsync(fechaDesde, fechaHasta, idPlanta);
                return (data, null);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error en ReportesService al obtener Consumo de Bobinas por Sección.");
                return (Enumerable.Empty<ConsumoBobinasSeccionDto>(), "Error interno al generar el reporte.");
            }
        }

        public async Task<(IEnumerable<ConsumoBobinasSeccionDto> Data, string? Error)> ObtenerConsumoBobinasPorSeccionConsolidadoAsync(DateTime fechaDesde, DateTime fechaHasta)
        {
            if (fechaDesde > fechaHasta) return (Enumerable.Empty<ConsumoBobinasSeccionDto>(), "Fecha 'Desde' no puede ser mayor que 'Hasta'.");
            try
            {
                var data = await _reportesRepository.GetConsumoBobinasPorSeccionConsolidadoAsync(fechaDesde, fechaHasta);
                return (data, null);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error en ReportesService al obtener Consumo de Bobinas por Sección (Consolidado).");
                return (Enumerable.Empty<ConsumoBobinasSeccionDto>(), "Error interno al generar el reporte.");
            }
        }

        public async Task<(IEnumerable<ConsumoBobinasPublicacionDto> Data, string? Error)> ObtenerConsumoBobinasPorPublicacionAsync(DateTime fechaDesde, DateTime fechaHasta)
        {
            if (fechaDesde > fechaHasta) return (Enumerable.Empty<ConsumoBobinasPublicacionDto>(), "Fecha 'Desde' no puede ser mayor que 'Hasta'.");
            try
            {
                var data = await _reportesRepository.GetConsumoBobinasPorPublicacionAsync(fechaDesde, fechaHasta);
                return (data, null);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error en ReportesService al obtener Consumo de Bobinas por Publicación.");
                return (Enumerable.Empty<ConsumoBobinasPublicacionDto>(), "Error interno al generar el reporte.");
            }
        }

        public async Task<(IEnumerable<ComparativaConsumoBobinasDto> Data, string? Error)> ObtenerComparativaConsumoBobinasAsync(DateTime fechaInicioMesA, DateTime fechaFinMesA, DateTime fechaInicioMesB, DateTime fechaFinMesB, int idPlanta)
        {
            if (fechaInicioMesA > fechaFinMesA || fechaInicioMesB > fechaFinMesB) return (Enumerable.Empty<ComparativaConsumoBobinasDto>(), "Fechas de inicio no pueden ser mayores que las de fin para los meses.");
            try
            {
                var data = await _reportesRepository.GetComparativaConsumoBobinasAsync(fechaInicioMesA, fechaFinMesA, fechaInicioMesB, fechaFinMesB, idPlanta);
                return (data, null);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error en ReportesService al obtener Comparativa de Consumo de Bobinas.");
                return (Enumerable.Empty<ComparativaConsumoBobinasDto>(), "Error interno al generar el reporte.");
            }
        }

        public async Task<(IEnumerable<ComparativaConsumoBobinasDto> Data, string? Error)> ObtenerComparativaConsumoBobinasConsolidadoAsync(DateTime fechaInicioMesA, DateTime fechaFinMesA, DateTime fechaInicioMesB, DateTime fechaFinMesB)
        {
            if (fechaInicioMesA > fechaFinMesA || fechaInicioMesB > fechaFinMesB) return (Enumerable.Empty<ComparativaConsumoBobinasDto>(), "Fechas de inicio no pueden ser mayores que las de fin para los meses.");
            try
            {
                var data = await _reportesRepository.GetComparativaConsumoBobinasConsolidadoAsync(fechaInicioMesA, fechaFinMesA, fechaInicioMesB, fechaFinMesB);
                return (data, null);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error en ReportesService al obtener Comparativa de Consumo de Bobinas (Consolidado).");
                return (Enumerable.Empty<ComparativaConsumoBobinasDto>(), "Error interno al generar el reporte.");
            }
        }

        // Implementación para ReporteCuentasDistribuidores.
        // Reemplaza el campo legacy "Saldos" (saldo actual sin sentido temporal) por "SaldoInicial":
        // saldo del último cierre + movimientos netos hasta fechaDesde-1 (0 si no hay cierre previo).
        public async Task<(
            IEnumerable<BalanceCuentaDistDto> EntradasSalidas,
            IEnumerable<BalanceCuentaDebCredDto> DebitosCreditos,
            IEnumerable<BalanceCuentaPagosDto> Pagos,
            decimal SaldoInicial,
            string? Error
        )> ObtenerReporteCuentasDistribuidorAsync(int idDistribuidor, int idEmpresa, DateTime fechaDesde, DateTime fechaHasta)
        {
            if (fechaDesde > fechaHasta)
                return (Enumerable.Empty<BalanceCuentaDistDto>(), Enumerable.Empty<BalanceCuentaDebCredDto>(), Enumerable.Empty<BalanceCuentaPagosDto>(), 0m, "Fecha 'Desde' no puede ser mayor que 'Hasta'.");

            try
            {
                var esTask = _reportesRepository.GetBalanceCuentaDistEntradaSalidaPorEmpresaAsync(idDistribuidor, idEmpresa, fechaDesde, fechaHasta);
                var dcTask = _reportesRepository.GetBalanceCuentDistDebCredEmpresaAsync(idDistribuidor, idEmpresa, fechaDesde, fechaHasta);
                var paTask = _reportesRepository.GetBalanceCuentDistPagosEmpresaAsync(idDistribuidor, idEmpresa, fechaDesde, fechaHasta);
                var siTask = _cierreService.CalcularSaldoInicialReporteAsync(idDistribuidor, idEmpresa, fechaDesde);

                await Task.WhenAll(esTask, dcTask, paTask, siTask);

                Func<IEnumerable<BalanceCuentaDistDto>, IEnumerable<BalanceCuentaDistDto>> esToUtc =
                    items => items?.Select(i => { i.Fecha = DateTime.SpecifyKind(i.Fecha.Date, DateTimeKind.Utc); return i; }).ToList()
                            ?? Enumerable.Empty<BalanceCuentaDistDto>();
                Func<IEnumerable<BalanceCuentaDebCredDto>, IEnumerable<BalanceCuentaDebCredDto>> dcToUtc =
                    items => items?.Select(i => { i.Fecha = DateTime.SpecifyKind(i.Fecha.Date, DateTimeKind.Utc); return i; }).ToList()
                            ?? Enumerable.Empty<BalanceCuentaDebCredDto>();
                Func<IEnumerable<BalanceCuentaPagosDto>, IEnumerable<BalanceCuentaPagosDto>> paToUtc =
                    items => items?.Select(i => { i.Fecha = DateTime.SpecifyKind(i.Fecha.Date, DateTimeKind.Utc); return i; }).ToList()
                            ?? Enumerable.Empty<BalanceCuentaPagosDto>();

                return (
                    esToUtc(await esTask),
                    dcToUtc(await dcTask),
                    paToUtc(await paTask),
                    await siTask,
                    null
                );
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error en ReportesService al obtener Reporte Cuentas Distribuidor.");
                return (
                    Enumerable.Empty<BalanceCuentaDistDto>(),
                    Enumerable.Empty<BalanceCuentaDebCredDto>(),
                    Enumerable.Empty<BalanceCuentaPagosDto>(),
                    0m,
                    "Error interno al generar el reporte."
                );
            }
        }

        public async Task<(IEnumerable<ListadoDistribucionDistSimpleDto> Simple, IEnumerable<ListadoDistribucionDistPromedioDiaDto> Promedios, string? Error)> ObtenerListadoDistribucionDistribuidoresAsync(int idDistribuidor, int idPublicacion, DateTime fechaDesde, DateTime fechaHasta)
        {
            if (fechaDesde > fechaHasta)
                return (Enumerable.Empty<ListadoDistribucionDistSimpleDto>(), Enumerable.Empty<ListadoDistribucionDistPromedioDiaDto>(), "La fecha 'Desde' no puede ser mayor que la fecha 'Hasta'.");

            try
            {
                // Llamar a los métodos específicos del repositorio
                var simpleDataTask = _reportesRepository.GetListadoDistribucionDistSimpleAsync(idDistribuidor, idPublicacion, fechaDesde, fechaHasta);
                var promediosDataTask = _reportesRepository.GetListadoDistribucionDistPromedioDiaAsync(idDistribuidor, idPublicacion, fechaDesde, fechaHasta);

                await Task.WhenAll(simpleDataTask, promediosDataTask);

                return (await simpleDataTask, await promediosDataTask, null);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error en ReportesService al obtener Listado Distribucion (Distribuidores). Params: Dist={idDistribuidor}, Pub={idPublicacion}, Desde={fechaDesde}, Hasta={fechaHasta}", idDistribuidor, idPublicacion, fechaDesde, fechaHasta);
                return (Enumerable.Empty<ListadoDistribucionDistSimpleDto>(), Enumerable.Empty<ListadoDistribucionDistPromedioDiaDto>(), "Error interno al generar el reporte.");
            }
        }

        public async Task<(
        IEnumerable<LiquidacionCanillaDetalleDto> Detalles,
        IEnumerable<LiquidacionCanillaGananciaDto> Ganancias,
        string? Error
    )> ObtenerDatosTicketLiquidacionAsync(DateTime fecha, int idCanilla)
        {
            try
            {
                var detallesTask = _reportesRepository.GetLiquidacionCanillaDetalleAsync(fecha, idCanilla);
                var gananciasTask = _reportesRepository.GetLiquidacionCanillaGananciasAsync(fecha, idCanilla);

                await Task.WhenAll(detallesTask, gananciasTask);

                var detalles = await detallesTask;
                var ganancias = await gananciasTask;

                if ((detalles == null || !detalles.Any()) && (ganancias == null || !ganancias.Any()))
                {
                    // Podrías optar por no devolver error aquí si es válido que uno de los dos esté vacío
                    // y manejarlo en el controlador o el RDLC.
                }

                // Convertir fechas a UTC si es necesario para el RDLC (aunque estos DTOs no tienen fechas)

                return (
                    detalles ?? Enumerable.Empty<LiquidacionCanillaDetalleDto>(),
                    ganancias ?? Enumerable.Empty<LiquidacionCanillaGananciaDto>(),
                    null
                );
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error en ReportesService al obtener datos para Ticket Liquidación Canilla. Fecha: {Fecha}, Canilla: {IdCanilla}", fecha, idCanilla);
                return (
                    Enumerable.Empty<LiquidacionCanillaDetalleDto>(),
                    Enumerable.Empty<LiquidacionCanillaGananciaDto>(),
                    "Error interno al obtener los datos para el ticket de liquidación."
                );
            }
        }

        public async Task<(IEnumerable<ListadoDistCanMensualDiariosDto> Data, string? Error)> ObtenerReporteMensualDiariosAsync(DateTime fechaDesde, DateTime fechaHasta, bool esAccionista)
        {
            try
            {
                var data = await _reportesRepository.GetReporteMensualDiariosAsync(fechaDesde, fechaHasta, esAccionista);
                return (data, null);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error al obtener reporte mensual canillitas (diarios).");
                return (Enumerable.Empty<ListadoDistCanMensualDiariosDto>(), "Error al obtener datos del reporte (diarios).");
            }
        }

        public async Task<(IEnumerable<ListadoDistCanMensualPubDto> Data, string? Error)> ObtenerReporteMensualPorPublicacionAsync(DateTime fechaDesde, DateTime fechaHasta, bool esAccionista)
        {
            try
            {
                var data = await _reportesRepository.GetReporteMensualPorPublicacionAsync(fechaDesde, fechaHasta, esAccionista);
                return (data, null);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error al obtener reporte mensual canillitas (por publicación).");
                return (Enumerable.Empty<ListadoDistCanMensualPubDto>(), "Error al obtener datos del reporte (por publicación).");
            }
        }

        public async Task<(IEnumerable<FacturasParaReporteDto> Data, string? Error)> ObtenerFacturasParaReportePublicidad(int anio, int mes)
        {
            if (anio < 2020 || mes < 1 || mes > 12)
            {
                return (Enumerable.Empty<FacturasParaReporteDto>(), "Período no válido.");
            }
            var periodo = $"{anio}-{mes:D2}";
            try
            {
                // Llamada directa al nuevo método del repositorio
                var data = await _reportesRepository.GetDatosReportePublicidadAsync(periodo);
                return (data, null);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error en servicio al obtener datos para reporte de publicidad para el período {Periodo}", periodo);
                return (new List<FacturasParaReporteDto>(), "Error interno al generar el reporte.");
            }
        }

        public async Task<(IEnumerable<DistribucionSuscripcionDto> Altas, IEnumerable<DistribucionSuscripcionDto> Bajas, string? Error)> ObtenerReporteDistribucionSuscripcionesAsync(DateTime fechaDesde, DateTime fechaHasta)
        {
            if (fechaDesde > fechaHasta)
            {
                return (Enumerable.Empty<DistribucionSuscripcionDto>(), Enumerable.Empty<DistribucionSuscripcionDto>(), "La fecha 'Desde' no puede ser mayor que la fecha 'Hasta'.");
            }

            try
            {
                // Ejecutamos ambas consultas en paralelo para mayor eficiencia
                var altasTask = _reportesRepository.GetDistribucionSuscripcionesActivasAsync(fechaDesde, fechaHasta);
                var bajasTask = _reportesRepository.GetDistribucionSuscripcionesBajasAsync(fechaDesde, fechaHasta);

                await Task.WhenAll(altasTask, bajasTask);

                return (await altasTask, await bajasTask, null);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error en servicio al obtener datos para reporte de distribución de suscripciones.");
                return (Enumerable.Empty<DistribucionSuscripcionDto>(), Enumerable.Empty<DistribucionSuscripcionDto>(), "Error interno al generar el reporte.");
            }
        }
    }
}