using JSMR.Application.Enums;
using JSMR.Application.Scanning.Contracts;
using JSMR.Application.Scanning.Ports;
using JSMR.Domain.Entities;
using JSMR.Infrastructure.Common.Time;
using JSMR.Infrastructure.Data;
using JSMR.Infrastructure.Ingestion;
using JSMR.Tests.Fixtures;
using NSubstitute;
using System.Runtime.InteropServices;

namespace JSMR.Tests.Ingestion.Japanese;

public abstract class JapaneseIngestionTestsBase(MariaDbContainerFixture container) : IngestionTestsBase(container)
{
    protected static async Task<VoiceWorkUpsertResult[]> UpsertAsync(AppDbContext dbContext, DateTime dateTime, VoiceWorkIngest[] ingests)
    {
        DateTime utcDateTime = DateTime.SpecifyKind(dateTime, DateTimeKind.Utc);

        IClock clock = Substitute.For<IClock>();
        clock.UtcNow.Returns(new DateTimeOffset(utcDateTime));

        TokyoTimeProvider timeProvider = new(clock);

        VoiceWorkUpdater updater = new(dbContext, timeProvider);

        return await updater.UpsertAsync(ingests, TestContext.Current.CancellationToken);
    }

    protected static async Task UpdateSearchAsync(AppDbContext dbContext, int[] voiceWorkIds)
    {
        VoiceWorkSearchUpdater updater = new(dbContext);

        await updater.UpdateAsync(voiceWorkIds, TestContext.Current.CancellationToken);
    }

    protected static DateTime TokyoLocalToUtc(int year, int month, int day, int hour, int minute, int second)
    {
        var tokyo = TimeZoneInfo.FindSystemTimeZoneById(
            RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "Tokyo Standard Time" : "Asia/Tokyo");

        var localUnspec = new DateTime(year, month, day, hour, minute, second, DateTimeKind.Unspecified);
        var utc = TimeZoneInfo.ConvertTimeToUtc(localUnspec, tokyo);

        return utc;
    }
}