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

namespace WhatsAppService.FunctionalTests.Controllers;

/// <summary>
/// EN: Functional tests for WhatsApp account and webhook endpoints.
/// VI: Functional tests cho endpoint tài khoản WhatsApp và webhook.
/// </summary>
public class WhatsAppAccountsControllerTests : IClassFixture<CustomWebApplicationFactory>
{
    private readonly HttpClient _client;

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

    [Fact]
    public async Task ConnectAccount_ThenGetByShopId_ShouldReturnConnectedAccount()
    {
        // Arrange
        var shopId = Guid.NewGuid();
        var request = new
        {
            shopId,
            phoneNumberId = "phone-123",
            accessToken = "plain-token",
            webhookUrl = "https://hook.example",
        };

        // Act
        var connectResponse = await _client.PostAsJsonAsync("/api/whatsappaccounts", request);
        var accountResponse = await _client.GetAsync($"/api/whatsappaccounts/shop/{shopId}");

        // Assert
        connectResponse.StatusCode.Should().Be(HttpStatusCode.OK);
        accountResponse.StatusCode.Should().Be(HttpStatusCode.OK);

        var payload = await accountResponse.Content.ReadFromJsonAsync<JsonElement>();
        payload.GetProperty("success").GetBoolean().Should().BeTrue();
        payload.GetProperty("data").GetProperty("shopId").GetGuid().Should().Be(shopId);
        payload.GetProperty("data").GetProperty("phoneNumberId").GetString().Should().Be("phone-123");
    }

    [Fact]
    public async Task VerifyWebhook_WithMatchingToken_ShouldReturnChallenge()
    {
        // Act
        var response = await _client.GetAsync(
            "/api/webhooks/whatsapp?hub.mode=subscribe&hub.challenge=test-challenge");

        // Assert
        response.StatusCode.Should().Be(HttpStatusCode.OK);
        var body = await response.Content.ReadAsStringAsync();
        body.Should().Contain("test-challenge");
    }

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

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