using System.Net;
using System.Net.Http.Json;
using FluentAssertions;
using Microsoft.AspNetCore.Mvc.Testing;
using Xunit;

namespace MyService.FunctionalTests.Controllers;

/// <summary>
/// EN: Functional tests for Samples API endpoints.
/// VI: Functional tests cho các endpoints API Samples.
/// </summary>
public class SamplesControllerTests : IClassFixture<CustomWebApplicationFactory>
{
    private readonly HttpClient _client;

    public SamplesControllerTests(CustomWebApplicationFactory factory)
    {
        _client = factory.CreateClient(new WebApplicationFactoryClientOptions
        {
            AllowAutoRedirect = false
        });
    }

    [Fact]
    public async Task GetSamples_ShouldReturnOkWithEmptyList()
    {
        // Act
        var response = await _client.GetAsync("/api/v1/samples");

        // Assert
        response.StatusCode.Should().Be(HttpStatusCode.OK);
        var content = await response.Content.ReadFromJsonAsync<ApiResponse<List<object>>>();
        content?.Success.Should().BeTrue();
    }

    [Fact]
    public async Task CreateSample_WithValidData_ShouldReturnCreated()
    {
        // Arrange
        var request = new { Name = "Test Sample", Description = "Test Description" };

        // Act
        var response = await _client.PostAsJsonAsync("/api/v1/samples", request);

        // Assert
        response.StatusCode.Should().Be(HttpStatusCode.Created);
        var content = await response.Content.ReadFromJsonAsync<ApiResponse<CreateSampleResult>>();
        content?.Success.Should().BeTrue();
        content?.Data?.Id.Should().NotBeEmpty();
    }

    [Fact]
    public async Task GetSample_WithInvalidId_ShouldReturnNotFound()
    {
        // Arrange
        var invalidId = Guid.NewGuid();

        // Act
        var response = await _client.GetAsync($"/api/v1/samples/{invalidId}");

        // Assert
        response.StatusCode.Should().Be(HttpStatusCode.NotFound);
    }

    [Fact]
    public async Task HealthCheck_ShouldReturnHealthy()
    {
        // Act
        var response = await _client.GetAsync("/health/live");

        // Assert
        response.StatusCode.Should().Be(HttpStatusCode.OK);
    }

    // EN: Helper DTOs for deserialization
    // VI: Helper DTOs để deserialize
    private record ApiResponse<T>(bool Success, T? Data);
    private record CreateSampleResult(Guid Id);
}
