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

namespace JSMR.Tests.Ingestion.Japanese;

public class Insert_New_Upcoming_Release_Same_Day_Tests(MariaDbContainerFixture container) : JapaneseIngestionTestsBase(container)
{
    [Fact]
    public async Task Insert_New_Upcoming_Release_Same_Day()
    {
        await using AppDbContext dbContext = await GetAppDbContextAsync();

        VoiceWorkIngest ingest = new()
        {
            MakerId = "RG00001",
            MakerName = "Good Dreams",
            ProductId = "RJ1000002",
            Title = "Preview Only",
            Description = "Still upcoming.",
            Tags = [],
            Creators = [],
            WishlistCount = 100,
            Downloads = 0,
            HasTrial = false,
            HasChobit = false,
            AgeRating = AgeRating.AllAges,
            HasImage = false,
            SupportedLanguages = [SupportedLanguage.Japanese],
            SalesDate = null,
            ExpectedDate = new DateOnly(2025, 2, 1)
        };

        await UpsertAndVerify(dbContext, TokyoLocalToUtc(2025, 01, 09, 16, 00, 00), ingest, VoiceWorkStatus.NewAndUpcoming);

        VoiceWorkIngest updatedIngest = ingest with
        {
            Title = "Released on the Same Day",
            Description = "Should be indicated as a new release",
            SalesDate = new DateOnly(2025, 1, 10),
            ExpectedDate = null
        };

        await UpsertAndVerify(dbContext, TokyoLocalToUtc(2025, 01, 10, 00, 00, 00), updatedIngest, VoiceWorkStatus.NewRelease);
        await UpsertAndVerify(dbContext, TokyoLocalToUtc(2025, 01, 10, 15, 59, 59), updatedIngest, VoiceWorkStatus.NewRelease);
        await UpsertAndVerify(dbContext, TokyoLocalToUtc(2025, 01, 10, 16, 00, 00), updatedIngest, VoiceWorkStatus.Available);
        await UpsertAndVerify(dbContext, TokyoLocalToUtc(2025, 01, 11, 00, 00, 00), updatedIngest, VoiceWorkStatus.Available);
    }

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

        VoiceWork? voiceWork = await dbContext.VoiceWorks.SingleAsync(v => v.ProductId == ingest.ProductId, TestContext.Current.CancellationToken);
        voiceWork.Status.ShouldBe((byte)status);
    }
}