using Application.Abstractions.Messaging;
using Domain.Entities.Donations.ValueObject;
using SharedKernel.Results;
using SharedKernel.Storage;

namespace Application.Features.Api.DonationAlert.UploadMedia;

internal sealed class Handler(IFileStorage fileStorage) : ICommandHandler<Command, Result<string>>
{
    private static readonly string[] ImageExtensions = [".jpg", ".jpeg", ".png", ".gif"];
    private static readonly string[] SoundExtensions = [".mp3", ".ogg", ".wav", ".m4a"];

    public async Task<Result<string>> Handle(Command r, CancellationToken ct) 
    {
        var (extensions, maxSizeMB) = r.Type switch
        {
            "image" => (ImageExtensions, DonationConstants.Alert.MaxImageFileSizeMB),
            "sound" => (SoundExtensions, DonationConstants.Alert.MaxSoundFileSizeMB),
            _ => throw new ArgumentException("유효하지 않은 파일 타입입니다.")
        };

        if (r.File.Length > maxSizeMB * 1024 * 1024)
        {
            return Result.Failure<string>(Error.Problem("UploadMedia.FileTooLarge", $"파일 크기는 {maxSizeMB}MB 이하여야 합니다."));
        }

        var path = new FileStoragePath(UploadTarget.Upload, UploadFolder.DonationAlert, r.ChannelID);
        var result = await fileStorage.SaveFileAsync(r.File, path, extensions, ct);

        if (result is null)
        {
            return Result.Failure<string>(Error.Problem("UploadMedia.Failed", "파일 업로드에 실패했습니다. 허용된 확장자를 확인하세요."));
        }

        return Result.Success(result.Url);
    }
}