using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Moq;
using QuantEngine.Application.Interfaces;
using QuantEngine.Application.Services;
using QuantEngine.Core.Domain;
using QuantEngine.Core.Interfaces;
using Xunit;

namespace QuantEngine.Core.Tests;

public class FactorComputationServiceTests
{
    [Fact]
    public async Task ComputeAndAppendFactorOutputs_WritesAuditAndHistory()
    {
        var storeMock = new Mock<IPostgresqlHistoryStore>();
        var auditTrailMock = new Mock<IRuntimeAuditTrailService>();
        storeMock.Setup(s => s.AppendAsync(It.IsAny<string>(), It.IsAny<IDictionary<string, object?>>()))
            .ReturnsAsync(1);

        var history = new HistoryIngestionService(storeMock.Object);
        var service = new FactorComputationService(history, auditTrailMock.Object);

        var outputs = new FactorOutputs(1, 2, 3, 4, 5, 6, 7);
        await service.AppendFactorOutputsAsync("005930", "v1", outputs);

        storeMock.Verify(s => s.AppendAsync("factor_output_history", It.IsAny<IDictionary<string, object?>>()), Times.Exactly(7));
        auditTrailMock.Verify(a => a.Append("factor_audit", "005930", It.IsAny<FactorComputationAudit>()), Times.Once);
    }

    [Fact]
    public async Task AppendFactorOutputsAsync_RejectsBlankTicker()
    {
        var storeMock = new Mock<IPostgresqlHistoryStore>();
        var auditTrailMock = new Mock<IRuntimeAuditTrailService>();
        var history = new HistoryIngestionService(storeMock.Object);
        var service = new FactorComputationService(history, auditTrailMock.Object);

        await Assert.ThrowsAsync<ArgumentException>(() =>
            service.AppendFactorOutputsAsync("  ", "v1", new FactorOutputs(1, 2, 3, 4, 5, 6, 7)));
    }
}
