using Dapper;
using System.Data;

namespace GestionIntegral.Api.Data.Repositories.Suscripciones
{
    public class FacturaDetalleRepository : IFacturaDetalleRepository
    {
        private readonly DbConnectionFactory _connectionFactory;
        private readonly ILogger<FacturaDetalleRepository> _logger;

        public FacturaDetalleRepository(DbConnectionFactory connectionFactory, ILogger<FacturaDetalleRepository> logger)
        {
            _connectionFactory = connectionFactory;
            _logger = logger;
        }

        public async Task<FacturaDetalle?> CreateAsync(FacturaDetalle nuevoDetalle, IDbTransaction transaction)
        {
            if (transaction == null || transaction.Connection == null)
            {
                throw new ArgumentNullException(nameof(transaction), "La transacción o su conexión no pueden ser nulas.");
            }
            const string sqlInsert = @"
                INSERT INTO dbo.susc_FacturaDetalles (IdFactura, IdSuscripcion, Descripcion, ImporteBruto, DescuentoAplicado, ImporteNeto)
                OUTPUT INSERTED.*
                VALUES (@IdFactura, @IdSuscripcion, @Descripcion, @ImporteBruto, @DescuentoAplicado, @ImporteNeto);";
            
            return await transaction.Connection.QuerySingleOrDefaultAsync<FacturaDetalle>(sqlInsert, nuevoDetalle, transaction);
        }

        public async Task<IEnumerable<FacturaDetalle>> GetDetallesPorFacturaIdAsync(int idFactura)
        {
            const string sql = "SELECT * FROM dbo.susc_FacturaDetalles WHERE IdFactura = @IdFactura;";
            using var connection = _connectionFactory.CreateConnection();
            return await connection.QueryAsync<FacturaDetalle>(sql, new { IdFactura = idFactura });
        }
        
        public async Task<IEnumerable<FacturaDetalle>> GetDetallesPorPeriodoAsync(string periodo)
        {
            const string sql = @"
                SELECT fd.* 
                FROM dbo.susc_FacturaDetalles fd
                JOIN dbo.susc_Facturas f ON fd.IdFactura = f.IdFactura
                WHERE f.Periodo = @Periodo;";
            
            try
            {
                using var connection = _connectionFactory.CreateConnection();
                return await connection.QueryAsync<FacturaDetalle>(sql, new { Periodo = periodo });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error al obtener los detalles de factura para el período {Periodo}", periodo);
                return Enumerable.Empty<FacturaDetalle>();
            }
        }
    }
}