using Dapper;
using GestionIntegral.Api.Models.Suscripciones;
using System.Data;

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

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

        public async Task<IEnumerable<Pago>> GetByFacturaIdAsync(int idFactura)
        {
            const string sql = "SELECT * FROM dbo.susc_Pagos WHERE IdFactura = @IdFactura ORDER BY FechaPago DESC;";
            try
            {
                using var connection = _connectionFactory.CreateConnection();
                return await connection.QueryAsync<Pago>(sql, new { idFactura });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error al obtener pagos para la factura ID: {IdFactura}", idFactura);
                return Enumerable.Empty<Pago>();
            }
        }

        public async Task<Pago?> CreateAsync(Pago nuevoPago, 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_Pagos
                    (IdFactura, FechaPago, IdFormaPago, Monto, Estado, Referencia, Observaciones, IdUsuarioRegistro)
                OUTPUT INSERTED.*
                VALUES
                    (@IdFactura, @FechaPago, @IdFormaPago, @Monto, @Estado, @Referencia, @Observaciones, @IdUsuarioRegistro);";

            try
            {
                return await transaction.Connection.QuerySingleAsync<Pago>(sqlInsert, nuevoPago, transaction);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error al registrar un nuevo Pago para la Factura ID: {IdFactura}", nuevoPago.IdFactura);
                return null;
            }
        }

        public async Task<decimal> GetTotalPagadoAprobadoAsync(int idFactura, 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 sql = "SELECT ISNULL(SUM(Monto), 0) FROM dbo.susc_Pagos WHERE IdFactura = @IdFactura AND Estado = 'Aprobado';";
            return await transaction.Connection.ExecuteScalarAsync<decimal>(sql, new { idFactura }, transaction);
        }
    }
}