using Dapper;
using ErsatzTV.Core;
using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Errors;
using ErsatzTV.Infrastructure.Data;
using ErsatzTV.Infrastructure.Extensions;
using Microsoft.EntityFrameworkCore;

namespace ErsatzTV.Application.Resolutions;

public class DeleteCustomResolutionHandler : IRequestHandler<DeleteCustomResolution, Option<BaseError>>
{
    private readonly IDbContextFactory<TvContext> _dbContextFactory;

    public DeleteCustomResolutionHandler(IDbContextFactory<TvContext> dbContextFactory) =>
        _dbContextFactory = dbContextFactory;

    public async Task<Option<BaseError>> Handle(DeleteCustomResolution request, CancellationToken cancellationToken)
    {
        await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);

        Option<Resolution> maybeAnyResolution = await dbContext.Resolutions
            .AsNoTracking()
            .SelectOneAsync(p => p.Id, p => p.Id == request.ResolutionId, cancellationToken);

        foreach (Resolution existingResolution in maybeAnyResolution)
        {
            if (!existingResolution.IsCustom)
            {
                return BaseError.New($"Resolution {request.ResolutionId} is not a custom resolution.");
            }

            // reset any ffmpeg profiles using this resolution to 1920x1080
            await dbContext.Connection.ExecuteAsync(
                @"UPDATE FFmpegProfile SET ResolutionId = 3 WHERE ResolutionId = @ResolutionId",
                new { request.ResolutionId });

            dbContext.Resolutions.Remove(existingResolution);
            await dbContext.SaveChangesAsync(cancellationToken);
        }

        return maybeAnyResolution.IsNone
            ? new NotFoundError($"Resolution {request.ResolutionId} does not exist.")
            : Option<BaseError>.None;
    }
}
