using Autofac;
using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.DataContracts;
using PlanTempus.Core.SeqLogging;

namespace PlanTempus.X.TDD.Logging;

[TestClass]
public class SeqLoggerTests : TestFixture
{
    private readonly string _testId;
    private readonly SeqHttpClient _httpClient;
    private readonly SeqLogger<SeqLoggerTests> _logger;

    public SeqLoggerTests()
    {
        _testId = Guid.NewGuid().ToString();
        var config = new SeqConfiguration("http://localhost:5341", null, "MSTEST");
        _httpClient = new SeqHttpClient(config);
        _logger = new SeqLogger<SeqLoggerTests>(_httpClient, config);
    }

    [TestMethod]
    public async Task LogTraceTelemetry_SendsCorrectDataWithErrorLevel()
    {
        // Arrange
        var traceTelemetry = new TraceTelemetry
        {
            Message = "Test trace error message",
            SeverityLevel = SeverityLevel.Error,
            Timestamp = DateTimeOffset.UtcNow
        };
        traceTelemetry.Properties.Add("TestId", _testId);

        // Act
        await _logger.LogAsync(traceTelemetry);
    }

    [TestMethod]
    public async Task LogTraceTelemetry_SendsCorrectDataWithWarningLevel()
    {
        // Arrange
        var traceTelemetry = new TraceTelemetry
        {
            Message = "Test trace warning message",
            SeverityLevel = SeverityLevel.Warning,
            Timestamp = DateTimeOffset.UtcNow
        };
        traceTelemetry.Properties.Add("TestId", _testId);

        // Act
        await _logger.LogAsync(traceTelemetry);
    }

    [TestMethod]
    public async Task LogEventTelemetry_SendsCorrectData()
    {
        // Arrange
        var eventTelemetry = new EventTelemetry
        {
            Name = "Test Event",
            Timestamp = DateTimeOffset.UtcNow
        };
        eventTelemetry.Properties.Add("TestId", _testId);
        eventTelemetry.Metrics.Add("TestMetric", 42.0);

        // Act
        await _logger.LogAsync(eventTelemetry);
    }

    [TestMethod]
    public async Task LogExceptionTelemetry_SendsCorrectData()
    {
        try
        {
            var t = 0;
            var result = 10 / t;
        }
        catch (Exception e)
        {
            // Arrange
            var exceptionTelemetry = new ExceptionTelemetry(e)
            {
                Timestamp = DateTimeOffset.UtcNow
            };
            exceptionTelemetry.Properties.Add("TestId", _testId);

            // Act
            await _logger.LogAsync(exceptionTelemetry);
        }
    }

    [TestMethod]
    public async Task LogDependencyTelemetry_SendsCorrectData()
    {
        // Arrange
        var dependencyTelemetry = new DependencyTelemetry
        {
            Name = "SQL Query",
            Type = "SQL",
            Target = "TestDB",
            Success = true,
            Duration = TimeSpan.FromMilliseconds(100),
            Timestamp = DateTimeOffset.UtcNow
        };
        dependencyTelemetry.Properties.Add("TestId", _testId);

        // Act
        await _logger.LogAsync(dependencyTelemetry);
    }

    /// <summary>
    ///     This is for scope test in SeqLogger. It is not testing anything related to the TelemetryChannel which logs to Seq.
    /// </summary>
    /// <returns></returns>
    [TestMethod]
    public async Task LogRequestTelemetryInOperationHolderWithParentChild_SendsCorrectData()
    {
        var telemetryClient = Container.Resolve<TelemetryClient>();

        using (var parent = telemetryClient.StartOperation<RequestTelemetry>("Parent First"))
        {
            parent.Telemetry.Duration = TimeSpan.FromMilliseconds(250);
            parent.Telemetry.Url = new Uri("http://parent.test.com/api/test");

            using (var child = telemetryClient.StartOperation<RequestTelemetry>("Child 1"))
            {
                child.Telemetry.Success = true;
                child.Telemetry.ResponseCode = "200";
                child.Telemetry.Duration = TimeSpan.FromMilliseconds(50);
                child.Telemetry.Url = new Uri("http://child.test.com/api/test");
                child.Telemetry.Timestamp = DateTimeOffset.UtcNow;

                child.Telemetry.Properties.Add("httpMethod", HttpMethod.Get.ToString());
                child.Telemetry.Properties.Add("TestId", _testId);

                await _logger.LogAsync(child);
            }

            ;

            await _logger.LogAsync(parent);
        }
    }
}