using FluentValidation;
using LiteCqrs;
using TeleWave.Application.Common.Models;

namespace TeleWave.Application.Media.ManualInbox;

/// <summary>
/// Один файл к разбору. <paramref name="Season"/> и <paramref name="Episode"/> приходят с клиента:
/// там пользователь видит распознанные номера и может поправить их регуляркой или ручным сезоном,
/// и сохраниться должно ровно то, что он видел. Не заданы — сервер разберёт имя сам.
/// </summary>
public sealed record ManualImportItem(string RelativePath, int? Season, int? Episode);

/// <summary>
/// Забирает выбранные файлы из <c>manual/</c> в шоу. Файлы уходят из каталога, как и из обычного
/// <c>inbox/</c>, а рядом лежавшие спутники (субтитры, nfo, обложки) удаляются, чтобы каталог
/// не зарастал мусором. Шоу обязательно: ручной разбор затевается ровно ради того, чтобы разложить
/// файлы по сериям, а «просто в библиотеку» уже умеют загрузка и автоматический inbox.
/// </summary>
public sealed record ImportManualInboxCommand(IReadOnlyList<ManualImportItem> Items, Guid ShowId)
    : ICommand<Result<ImportManualInboxResultDto>>;

/// <summary>Итог разбора: что взяли и что не смогли — по файлам, а не одной ошибкой на всё.</summary>
public sealed record ImportManualInboxResultDto(
    int Imported,
    IReadOnlyList<ImportFailureDto> Failed
);

public sealed record ImportFailureDto(string RelativePath, string Reason);

public sealed class ImportManualInboxCommandValidator : AbstractValidator<ImportManualInboxCommand>
{
    public ImportManualInboxCommandValidator()
    {
        RuleFor(x => x.Items).NotEmpty();
        RuleFor(x => x.Items.Count).LessThanOrEqualTo(500);
        RuleFor(x => x.ShowId).NotEmpty();

        // Ноль — законный номер: пилот часто идёт как E00, а спецвыпуски живут в нулевом сезоне.
        RuleForEach(x => x.Items)
            .Must(i => i.Season is null or (>= 0 and <= 99))
            .WithMessage("Сезон вне допустимого диапазона.");
        RuleForEach(x => x.Items)
            .Must(i => i.Episode is null or (>= 0 and <= 999))
            .WithMessage("Номер серии вне допустимого диапазона.");
    }
}
