namespace TeleWave.Domain.Library;

/// <summary>
/// Вариант написания жанра для сопоставления с внешними источниками. Хранит уже нормализованное
/// значение (см. <see cref="Normalize"/>), поэтому поиск — это точное сравнение, без LIKE и без
/// приведения регистра на стороне БД.
///
/// Формы значения: числовой идентификатор провайдера (<c>tmdb:28</c>) либо имя жанра на любом языке
/// (<c>action</c>, <c>боевик</c>, <c>sci-fi</c>). Один жанр справочника собирает под собой сколько
/// угодно вариантов — так «Action» и «Action &amp; Adventure» из TMDb сводятся к одному «Боевику».
/// </summary>
public class GenreAlias
{
    public Guid Id { get; private set; }
    public Guid GenreId { get; private set; }

    /// <summary>Нормализованное значение — уникально по всему справочнику.</summary>
    public string Value { get; private set; } = string.Empty;

    private GenreAlias() { }

    internal static GenreAlias Create(Guid genreId, string value) =>
        new()
        {
            Id = Guid.NewGuid(),
            GenreId = genreId,
            Value = Normalize(value),
        };

    /// <summary>Приводит написание к каноничному виду: нижний регистр, схлопнутые пробелы, без краёв.</summary>
    public static string Normalize(string? value)
    {
        if (string.IsNullOrWhiteSpace(value))
            return string.Empty;

        var trimmed = value.Trim().ToLowerInvariant();
        return string.Join(
            ' ',
            trimmed.Split(
                ' ',
                StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries
            )
        );
    }

    /// <summary>Псевдоним по идентификатору жанра во внешнем источнике (<c>tmdb:28</c>).</summary>
    public static string ProviderKey(string provider, string externalId) =>
        Normalize($"{provider}:{externalId}");
}
