using JSMR.Application.Enums;
using JSMR.Domain.ValueObjects;
using JSMR.Infrastructure.Http;
using System.Text.RegularExpressions;

namespace JSMR.Infrastructure.Scanning;

public partial class JapaneseVoiceWorksScanner(IHtmlLoader loader) : VoiceWorksScanner(loader)
{
    [GeneratedRegex("(.*?)年(.*?)月(.*)", RegexOptions.IgnoreCase, "en-US")]
    private static partial Regex EstimatedDateRegex();

    [GeneratedRegex("販売日:&nbsp;(.*?)年(.*?)月(.*)日", RegexOptions.IgnoreCase, "en-US")]
    private static partial Regex SalesDateRegex();

    protected override Locale Locale => Locale.Japanese;

    protected override SupportedLanguage[] SupportedLanguages =>
    [
        SupportedLanguage.Japanese,
        SupportedLanguage.English,
        SupportedLanguage.ChineseTraditional,
        SupportedLanguage.ChineseSimplified,
        SupportedLanguage.Korean,
        SupportedLanguage.Alingual
    ];

    protected override DateOnly? GetEstimatedReleaseDate(string expectedDate)
    {
        if (expectedDate.Contains("販売中") || expectedDate.Contains("発売予定未定"))
            return null;

        Regex textRegex = EstimatedDateRegex();
        MatchCollection textMatches = textRegex.Matches(expectedDate);

        if (textMatches.Count == 0 || textMatches[0].Groups.Count < 4)
            return null;

        int releaseYear = Convert.ToInt32(textMatches[0].Groups[1].Value);
        int releaseMonth = Convert.ToInt32(textMatches[0].Groups[2].Value);
        int releaseDay = 1;

        string releaseTime = textMatches[0].Groups[3].Value;

        switch (releaseTime)
        {
            case "上旬発売予定":
            case "上旬 発売予定":
                releaseDay = 1;
                break;
            case "中旬発売予定":
            case "中旬 発売予定":
                releaseDay = 11;
                break;
            case "下旬発売予定":
            case "下旬 発売予定":
                releaseDay = 21;
                break;
        }

        return new DateOnly(releaseYear, releaseMonth, releaseDay);
    }

    protected override DateOnly? GetSalesDate(string salesDate)
    {
        Regex textRegex = SalesDateRegex();
        MatchCollection textMatches = textRegex.Matches(salesDate);

        if (textMatches.Count == 0 || textMatches[0].Groups.Count < 4)
            return null;

        int releaseYear = Convert.ToInt32(textMatches[0].Groups[1].Value);
        int releaseMonth = Convert.ToInt32(textMatches[0].Groups[2].Value);
        int releaseDay = Convert.ToInt32(textMatches[0].Groups[3].Value);

        return new DateOnly(releaseYear, releaseMonth, releaseDay);
    }
}