using Knot.Contracts.Conversations.Domain;
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using MediatR;
using Knot.Shared.Kernel;
using Knot.Shared.Kernel.Storage;
using Knot.Contracts.Settings.Application.Abstractions;
using Knot.Contracts.Settings.Application.DTOs;
using Knot.Modules.Conversations.Application.DTOs;

namespace Knot.Modules.Conversations.Application.Messages.UploadFile;

public record UploadFileCommand(string FileName, string ContentType, long Length, Stream FileStream) : ICommand<UploadFileResponseDto>;

internal sealed class UploadFileCommandHandler : ICommandHandler<UploadFileCommand, UploadFileResponseDto>
{
    private readonly IFileStorageService _fileStorage;
    private readonly IMessagesSettings _settingsService;

    public UploadFileCommandHandler(IFileStorageService fileStorage, IMessagesSettings settingsService)
    {
        _fileStorage = fileStorage;
        _settingsService = settingsService;
    }

    public async Task<Result<UploadFileResponseDto>> Handle(UploadFileCommand request, CancellationToken cancellationToken)
    {
        if (request.Length == 0)
        {
            return Result.Failure<UploadFileResponseDto>(ChatErrors.FileEmpty);
        }

        var maxBytes = _settingsService.Current.MaxMediaSizeBytes;
        var maxMb = maxBytes / (1024 * 1024);

        if (request.Length > maxBytes)
        {
            return Result.Failure<UploadFileResponseDto>(ChatErrors.FileTooLarge(maxMb));
        }

        var fileId = await _fileStorage.UploadFileAsync(request.FileStream, request.FileName, request.ContentType);

        return Result.Success(new UploadFileResponseDto("/api/files/" + fileId, request.FileName, request.Length));
    }
}


