using MediatR;
using StorageService.Domain.AggregatesModel.FileShareAggregate;

namespace StorageService.API.Application.Commands.Admin;

/// <summary>
/// EN: Handler for AdminRevokeShareCommand.
/// VI: Handler cho AdminRevokeShareCommand.
/// </summary>
public class AdminRevokeShareCommandHandler : IRequestHandler<AdminRevokeShareCommand, AdminRevokeShareResult>
{
    private readonly IFileShareRepository _shareRepository;
    private readonly ILogger<AdminRevokeShareCommandHandler> _logger;

    public AdminRevokeShareCommandHandler(
        IFileShareRepository shareRepository,
        ILogger<AdminRevokeShareCommandHandler> logger)
    {
        _shareRepository = shareRepository;
        _logger = logger;
    }

    public async Task<AdminRevokeShareResult> Handle(AdminRevokeShareCommand request, CancellationToken cancellationToken)
    {
        try
        {
            // EN: Get share / VI: Lấy share
            var share = await _shareRepository.GetByIdAsync(request.ShareId, cancellationToken);
            
            if (share == null)
            {
                return new AdminRevokeShareResult(false, null, null, "Share not found.");
            }

            var fileId = share.FileId;
            var shareOwner = share.SharedBy;

            // EN: Log admin action / VI: Log hành động admin
            _logger.LogWarning(
                "Admin {AdminId} revoking share {ShareId} (owner: {OwnerId}, file: {FileId}) for reason: {Reason}",
                request.AdminUserId, request.ShareId, shareOwner, fileId, request.Reason);

            // EN: Revoke share / VI: Thu hồi share
            share.Revoke();
            _shareRepository.Update(share);

            // EN: Save changes / VI: Lưu thay đổi
            await _shareRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

            _logger.LogInformation(
                "Share {ShareId} revoked by admin {AdminId}. Reason: {Reason}",
                request.ShareId, request.AdminUserId, request.Reason);

            return new AdminRevokeShareResult(true, fileId, shareOwner, null);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error revoking share {ShareId} by admin", request.ShareId);
            return new AdminRevokeShareResult(false, null, null, "An error occurred while revoking the share.");
        }
    }
}
