using System.Threading.Channels;
using ErsatzTV.Application;
using ErsatzTV.Application.Maintenance;
using ErsatzTV.Core;
using ErsatzTV.Extensions;
using ErsatzTV.Filters;
using MediatR;
using Microsoft.AspNetCore.Mvc;

namespace ErsatzTV.Controllers.Api;

[ApiController]
[EndpointGroupName("general")]
[RequiresAuthentication]
public class MaintenanceController(IMediator mediator, ChannelWriter<IBackgroundServiceRequest> workerChannel)
{
    [HttpPost("/api/v1/maintenance/gc")]
    [Tags("Maintenance")]
    [EndpointSummary("Garbage collect")]
    public async Task<IActionResult> GarbageCollection([FromQuery] bool force = false)
    {
        await mediator.Send(new ReleaseMemory(force));
        return new OkResult();
    }

    [HttpPost("/api/v1/maintenance/empty_trash")]
    [Tags("Maintenance")]
    [EndpointSummary("Empty trash")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status422UnprocessableEntity)]
    public async Task<IActionResult> EmptyTrash()
    {
        Either<BaseError, Unit> result = await mediator.Send(new EmptyTrash());
        foreach (BaseError error in result.LeftToSeq())
        {
            return error.ToErrorResult();
        }

        return new OkResult();
    }

    [HttpPost("/api/v1/maintenance/clean_artwork")]
    [Tags("Maintenance")]
    [EndpointSummary("Clean artwork cache")]
    [ProducesResponseType(StatusCodes.Status202Accepted)]
    public async Task<IActionResult> CleanArtwork(CancellationToken cancellationToken)
    {
        await workerChannel.WriteAsync(new DeleteOrphanedArtwork(), cancellationToken);
        return new AcceptedResult();
    }
}
