using JSMR.Application.Scanning.Contracts;
using JSMR.Domain.Entities;
using JSMR.Domain.ValueObjects;
using JSMR.Infrastructure.Data;
using JSMR.Tests.Fixtures;
using Microsoft.EntityFrameworkCore;
using Shouldly;

namespace JSMR.Tests.Ingestion.Japanese;

public class Update_Supported_Langauge_Tests(MariaDbContainerFixture container) : JapaneseIngestionTestsBase(container)
{
    [Fact]
    public async Task Update_Supported_Langauge()
    {
        VoiceWorkIngest ingest = new()
        {
            MakerId = "RG1",
            MakerName = "The Maker",
            ProductId = "RJ1",
            Title = "Title",
            Description = "Description",
            SupportedLanguages = [SupportedLanguage.Japanese]
        };

        await using AppDbContext dbContext = await GetAppDbContextAsync();
        DateTime currentDateTime = TokyoLocalToUtc(2025, 01, 05, 10, 0, 0);

        await UpsertAndVerify(dbContext, TokyoLocalToUtc(2025, 01, 05, 10, 0, 0), ingest, [SupportedLanguage.Japanese]);

        // Add English
        VoiceWorkIngest addSupportedLanguageIngest = ingest with
        {
            SupportedLanguages = [SupportedLanguage.Japanese, SupportedLanguage.English]
        };

        await UpsertAndVerify(dbContext, TokyoLocalToUtc(2025, 01, 05, 10, 0, 0), addSupportedLanguageIngest, [SupportedLanguage.Japanese, SupportedLanguage.English]);

        // Remove Japanese
        VoiceWorkIngest removeSupportedLanguageIngest = ingest with
        {
            SupportedLanguages = [SupportedLanguage.English]
        };

        await UpsertAndVerify(dbContext, TokyoLocalToUtc(2025, 01, 05, 10, 0, 0), removeSupportedLanguageIngest, [SupportedLanguage.English]);
    }

    private static async Task UpsertAndVerify(AppDbContext dbContext, DateTime dateTime, VoiceWorkIngest ingest, SupportedLanguage[] expectedSupportedLanguages)
    {
        await UpsertAsync(dbContext, dateTime, [ingest]);

        VoiceWork? voiceWork = await dbContext.VoiceWorks
            .Include(x => x.SupportedLanguages)
            .SingleAsync(v => v.ProductId == ingest.ProductId, TestContext.Current.CancellationToken);
        
        voiceWork.ShouldNotBeNull();

        string[] languageCodes = [.. voiceWork.SupportedLanguages.Select(x => x.Language).OrderBy(x => x)];
        string[] expectedLanguageCode = [.. expectedSupportedLanguages.Select(x => x.Code).OrderBy(x => x)];

        languageCodes.ShouldBe(expectedLanguageCode);
    }
}