using Bugsnag;
using ErsatzTV.Core;
using ErsatzTV.Core.Interfaces.Repositories;
using ErsatzTV.Core.Interfaces.Search;
using ErsatzTV.Core.Search;
using ErsatzTV.Infrastructure.Search;

namespace ErsatzTV.Application.Maintenance;

public class EmptyTrashHandler : IRequestHandler<EmptyTrash, Either<BaseError, Unit>>
{
    private readonly IClient _client;
    private readonly IMediaItemRepository _mediaItemRepository;
    private readonly ISearchIndex _searchIndex;

    public EmptyTrashHandler(
        IClient client,
        IMediaItemRepository mediaItemRepository,
        ISearchIndex searchIndex)
    {
        _client = client;
        _mediaItemRepository = mediaItemRepository;
        _searchIndex = searchIndex;
    }

    public async Task<Either<BaseError, Unit>> Handle(
        EmptyTrash request,
        CancellationToken cancellationToken)
    {
        string[] types =
        {
            LuceneSearchIndex.MovieType,
            LuceneSearchIndex.ShowType,
            LuceneSearchIndex.SeasonType,
            LuceneSearchIndex.EpisodeType,
            LuceneSearchIndex.MusicVideoType,
            LuceneSearchIndex.OtherVideoType,
            LuceneSearchIndex.SongType,
            LuceneSearchIndex.ArtistType
        };

        var ids = new List<int>();

        foreach (string type in types)
        {
            SearchResult result = await _searchIndex.Search(_client, $"type:{type} AND (state:FileNotFound)", 0, 0);
            ids.AddRange(result.Items.Map(i => i.Id));
        }

        Either<BaseError, Unit> deleteResult = await _mediaItemRepository.DeleteItems(ids);
        if (deleteResult.IsRight)
        {
            await _searchIndex.RemoveItems(ids);
            _searchIndex.Commit();
        }

        return deleteResult;
    }
}
