using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using StorageService.API.Controllers;
using StorageService.Infrastructure.Persistence;

namespace StorageService.API.Application.Queries;

/// <summary>
/// EN: Handler for GetMultipartUploadProgressQuery.
/// VI: Handler cho GetMultipartUploadProgressQuery.
/// </summary>
public class GetMultipartUploadProgressQueryHandler 
    : IRequestHandler<GetMultipartUploadProgressQuery, MultipartUploadProgressResult?>
{
    private readonly StorageServiceContext _context;
    private readonly ILogger<GetMultipartUploadProgressQueryHandler> _logger;

    public GetMultipartUploadProgressQueryHandler(
        StorageServiceContext context,
        ILogger<GetMultipartUploadProgressQueryHandler> logger)
    {
        _context = context;
        _logger = logger;
    }

    public async Task<MultipartUploadProgressResult?> Handle(
        GetMultipartUploadProgressQuery request,
        CancellationToken cancellationToken)
    {
        try
        {
            _logger.LogInformation(
                "Getting progress for multipart upload {UploadId}",
                request.UploadId);

            // EN: Get multipart upload with parts / VI: Lấy multipart upload với parts
            var upload = await _context.MultipartUploads
                .Include(u => u.Parts)
                .FirstOrDefaultAsync(u => u.Id == request.UploadId, cancellationToken);

            if (upload == null)
            {
                _logger.LogWarning("Multipart upload not found: {UploadId}", request.UploadId);
                return null;
            }

            // EN: Verify ownership / VI: Xác minh quyền sở hữu
            if (upload.UserId != request.UserId)
            {
                _logger.LogWarning(
                    "User {UserId} attempted to access upload owned by {OwnerId}",
                    request.UserId, upload.UserId);
                return null;
            }

            // EN: Calculate progress / VI: Tính toán tiến độ
            var uploadedBytes = upload.Parts.Sum(p => p.SizeBytes);

            return new MultipartUploadProgressResult
            {
                UploadId = upload.Id,
                FileName = upload.FileName,
                TotalSizeBytes = upload.TotalSizeBytes,
                UploadedBytes = uploadedBytes,
                TotalChunks = upload.TotalChunks,
                UploadedChunks = upload.Parts.Count,
                ProgressPercentage = upload.GetProgressPercentage(),
                Status = upload.Status.ToString(),
                CreatedAt = upload.CreatedAt,
                ExpiresAt = upload.ExpiresAt
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error getting progress for multipart upload {UploadId}", request.UploadId);
            throw;
        }
    }
}
