using System.Text.Json;
using System.Text.Json.Serialization;
using TeleWave.Domain.Library;
using TeleWave.Domain.Programming;

namespace TeleWave.Application.Programming.Groups;

/// <summary>
/// Правило набора состава группы. Пустые поля не ограничивают.
///
/// В статической группе это помощник наполнения: правило находит подходящие позиции, а добавляет их
/// отдельная команда. В динамической — оно и есть состав, вычисляемый при каждом обращении.
/// </summary>
public sealed record GroupFilter(
    IReadOnlyList<GroupElementKind>? ElementKinds = null,
    IReadOnlyList<ShowKind>? ShowKinds = null,
    IReadOnlyList<Guid>? GenreIds = null,
    ShowAudience? MaxAudience = null,
    ShowAudience? MinAudience = null,
    int? YearMin = null,
    int? YearMax = null,
    int? UnitMinutesMin = null,
    int? UnitMinutesMax = null
)
{
    private static readonly JsonSerializerOptions Options = new()
    {
        PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
        DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
        Converters = { new JsonStringEnumConverter() },
    };

    public string ToJson() => JsonSerializer.Serialize(this, Options);

    /// <summary>Разбирает сохранённое правило. Повреждённый JSON трактуется как отсутствие фильтра:
    /// группа продолжает работать своим явным составом, а админ переустановит правило.</summary>
    public static GroupFilter? FromJson(string? json)
    {
        if (string.IsNullOrWhiteSpace(json))
            return null;

        try
        {
            return JsonSerializer.Deserialize<GroupFilter>(json, Options);
        }
        catch (JsonException)
        {
            return null;
        }
    }
}
