using JSMR.Application.Enums;
using JSMR.Domain.ValueObjects;
using JSMR.Infrastructure.Globalization;

namespace JSMR.Infrastructure.Scanning;

public sealed class DLSiteSearchFilterBuilder
{
    private readonly List<string> _optionsAnd = [];
    private readonly List<string> _optionsNot = [];
    private readonly List<string> _excludedMakers = [];

    private Locale _locale = Locale.Japanese;

    private void AddToOptionsAnd(string value)
    {
        if (_optionsAnd.Contains(value))
            return;

        _optionsAnd.Add(value);
    }

    private void AddToOptionsNot(string value)
    {
        if (_optionsNot.Contains(value))
            return;

        _optionsNot.Add(value);
    }

    public DLSiteSearchFilterBuilder UseLocale(Locale locale)
    {
        _locale = locale;

        return this;
    }

    public DLSiteSearchFilterBuilder IncludeSupportedLanguages(SupportedLanguage[] languages)
    {
        foreach (SupportedLanguage language in languages)
        {
            IncludeSupportedLanguage(language);
        }

        return this;
    }

    public DLSiteSearchFilterBuilder IncludeSupportedLanguage(SupportedLanguage language)
    {
        AddToOptionsAnd(language.Code);

        return this;
    }

    public DLSiteSearchFilterBuilder ExcludeMakers(string[] makerIds)
    {
        foreach (var makerId in makerIds)
            ExcludeMaker(makerId);

        return this;
    }

    public DLSiteSearchFilterBuilder ExcludeMaker(string makerId)
    {
        if (string.IsNullOrWhiteSpace(makerId))
            return this;

        string trimmedMakerId = makerId.Trim();

        if (_excludedMakers.Contains(trimmedMakerId))
            return this;

        _excludedMakers.Add(trimmedMakerId);

        return this;
    }

    public DLSiteSearchFilterBuilder ExcludePartiallyAIGeneratedWorks()
    {
        AddToOptionsNot("AIP");

        return this;
    }

    public DLSiteSearchFilterBuilder ExcludeAIGeneratedWorks()
    {
        AddToOptionsNot("AIG");

        return this;
    }

    public string BuildSearchQuery(int pageNumber, int pageSize)
    {
        //string localeAbbreviation = LocaleMapper.ToAbbreviation(_locale);
        //string localeCode = LocaleMapper.ToDLSiteLocale(_locale);

        var (localeAbbreviation, localeCode) = LocaleMapper.Map[_locale];

        using (var writer = new StringWriter())
        {
            writer.Write($"https://www.dlsite.com/maniax/");
            writer.Write($"fsr/=/language/{localeAbbreviation}/");

            writer.Write("sex_category[0]/male/");
            writer.Write("ana_flg/all/");
            writer.Write("work_category[0]/doujin/");
            writer.Write("order[0]/release_d/");
            writer.Write("work_type_category[0]/audio/");
            writer.Write("work_type_category_name[0]/ボイス・ASMR/");

            if (_optionsAnd.Count > 0)
            {
                writer.Write("options_and_or/and/");

                for (int index = 0; index < _optionsAnd.Count; index++)
                {
                    writer.Write($"options[{index}]/{_optionsAnd[index]}/");
                }
            }

            if (_excludedMakers.Count > 0)
            {
                List<string> spamMakers = [.. _excludedMakers.Select(x => "-" + x)];
                string makerFilterValue = string.Join("+", spamMakers).Trim();
                writer.Write($"keyword_maker_name/{makerFilterValue}/");
            }

            for (int index = 0; index < _optionsNot.Count; index++)
            {
                writer.Write($"options_not[{index}]/{_optionsNot[index]}/");
            }

            writer.Write($"per_page/{pageSize}/");
            writer.Write($"page/{pageNumber}/");
            writer.Write("show_type/1/");
            writer.Write($"?locale={localeCode}");

            return writer.ToString();
        }
    }
}