using Microsoft.AspNetCore.Mvc.Testing;
using Xunit;
using Xunit.Abstractions;
using System.Text.Json;

namespace DiunaBI.Tests;

public class ApiConnectionTests : IClassFixture<WebApplicationFactory<Program>>
{
    private readonly WebApplicationFactory<Program> _factory;
    private readonly ITestOutputHelper _output;

    public ApiConnectionTests(WebApplicationFactory<Program> factory, ITestOutputHelper output)
    {
        _factory = factory;
        _output = output;
    }

    [Fact]
    public async Task PingToApi()
    {
        var client = _factory.CreateClient();
        _output.WriteLine($"Test started: {nameof(PingToApi)}");

        var response = await client.GetAsync("/api/Tests/Ping");
        var content = await response.Content.ReadAsStringAsync();
        var statusCode = (int)response.StatusCode;

        _output.WriteLine($"Status Code: {statusCode}");
        _output.WriteLine($"Response Content: {content}");
        _output.WriteLine($"Headers: {string.Join(", ", response.Headers)}");

        Assert.Equal(200, statusCode);
        Assert.Equal("Pong", content);
    }

    [Fact]
    [Trait("Category", "LocalOnly")]
    public async Task DatabaseConnectionTest()
    {
        var client = _factory.CreateClient();
        _output.WriteLine($"Test started: {nameof(DatabaseConnectionTest)}");

        var response = await client.GetAsync("/api/Layers?start=0&limit=1");
        var content = await response.Content.ReadAsStringAsync();
        var statusCode = (int)response.StatusCode;

        _output.WriteLine($"Status Code: {statusCode}");
        _output.WriteLine($"Response Content: {content}");
        _output.WriteLine($"Content Type: {response.Content.Headers.ContentType}");

        Assert.Equal(200, statusCode);
        var layers = JsonSerializer.Deserialize<dynamic>(content);
        Assert.NotNull(layers);
    }

    [Fact]
    public async Task LoadPluginsTest()
    {
        var client = _factory.CreateClient();
        _output.WriteLine($"Test started: {nameof(LoadPluginsTest)}");
        
        var pluginsPath = Path.Combine(AppContext.BaseDirectory, "Plugins");
        _output.WriteLine($"Looking for plugins in: {pluginsPath}");
        if (Directory.Exists(pluginsPath))
        {
            _output.WriteLine("Files in plugins directory:");
            foreach (var file in Directory.GetFiles(pluginsPath))
            {
                _output.WriteLine($"- {Path.GetFileName(file)}");
            }
        }
        else
        {
            _output.WriteLine("❌ Plugins directory not found!");
        }

        var response = await client.GetAsync("/api/Tests/Plugins");
        var content = await response.Content.ReadAsStringAsync();
        _output.WriteLine($"API Response: {content}");

        if (!int.TryParse(content, out var pluginsCount))
        {
            _output.WriteLine($"❌ Failed to parse plugins count from response: {content}");
            Assert.Fail($"Expected numeric response but got: {content}");
        }

        Assert.Equal(200, (int)response.StatusCode);
        Assert.True(pluginsCount > 0, 
            $"Expected plugins count to be greater than 0. Got: {pluginsCount}");
    }
}