using Books.Api.Banking;
using AwesomeAssertions;
using Microsoft.Extensions.Logging.Abstractions;

namespace Books.Api.Tests.Integration;

/// <summary>
/// Integration tests for Enable Banking API client.
/// These tests call the real Enable Banking API.
/// </summary>
[Trait("Category", "Integration")]
public class EnableBankingClientTests : IDisposable
{
    private readonly EnableBankingClient _client;
    private readonly HttpClient _httpClient;

    public EnableBankingClientTests()
    {
        var options = new EnableBankingOptions
        {
            ApplicationId = "0bafa28d-41ea-4275-a4d5-221a78c72350",
            KeyId = "0bafa28d-41ea-4275-a4d5-221a78c72350",
            PrivateKey = File.ReadAllText(Path.Combine(
                Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
                "projects/ledger/private.key"))
        };

        _httpClient = new HttpClient
        {
            BaseAddress = new Uri("https://api.enablebanking.com")
        };

        _client = new EnableBankingClient(_httpClient, options, NullLogger<EnableBankingClient>.Instance);
    }

    public void Dispose()
    {
        _client.Dispose();
        _httpClient.Dispose();
    }

    [Fact]
    public async Task GetAspsps_ReturnsDanishBanks()
    {
        // Act
        var banks = await _client.GetAspspsAsync("DK");

        // Assert
        banks.Should().NotBeEmpty();
        banks.Should().Contain(b => b.Name.Contains("Danske", StringComparison.OrdinalIgnoreCase));
    }

    [Fact(Skip = "Requires redirect URL to be registered in Enable Banking dashboard")]
    public async Task StartAuthorization_WithRegisteredRedirectUrl_ReturnsAuthorizationUrl()
    {
        // Arrange - First get actual bank name from API
        var banks = await _client.GetAspspsAsync("DK");
        var danskeBank = banks.FirstOrDefault(b => b.Name.Contains("Danske", StringComparison.OrdinalIgnoreCase));
        danskeBank.Should().NotBeNull("Danske Bank should exist in available banks");

        // Note: This redirect URL must be registered in Enable Banking dashboard
        // Configure at: https://enablebanking.com/dashboard
        var redirectUrl = "https://your-registered-url.com/callback";
        var state = Guid.NewGuid().ToString();

        // Act
        var result = await _client.StartAuthorizationAsync(
            aspspName: danskeBank!.Name,
            redirectUrl: redirectUrl,
            state: state,
            psuType: "personal");

        // Assert
        result.Should().NotBeNull();
        result.AuthorizationId.Should().NotBeNullOrEmpty();
        result.Url.Should().StartWith("https://");
    }

    [Fact]
    public async Task StartAuthorization_WithUnregisteredRedirectUrl_ThrowsExpectedError()
    {
        // Arrange
        var banks = await _client.GetAspspsAsync("DK");
        var bank = banks.First();

        var unregisteredRedirectUrl = "https://unregistered-domain.example.com/callback";
        var state = Guid.NewGuid().ToString();

        // Act
        var act = async () => await _client.StartAuthorizationAsync(
            aspspName: bank.Name,
            redirectUrl: unregisteredRedirectUrl,
            state: state,
            psuType: "personal");

        // Assert - Should get REDIRECT_URI_NOT_ALLOWED error (proves API auth works)
        var exception = await act.Should().ThrowAsync<HttpRequestException>();
        exception.Which.Message.Should().Contain("REDIRECT_URI_NOT_ALLOWED");
    }
}
