// EN: Command to reactivate a suspended merchant.
// VI: Command để kích hoạt lại merchant bị tạm ngưng.

using MediatR;
using MerchantService.Domain.AggregatesModel.MerchantAggregate;
using MerchantService.Domain.Exceptions;

namespace MerchantService.API.Application.Commands.Admin;

/// <summary>
/// EN: Command to reactivate a suspended merchant (Admin only).
/// VI: Command để kích hoạt lại merchant bị tạm ngưng (chỉ Admin).
/// </summary>
/// <param name="MerchantId">Merchant ID to reactivate / ID Merchant cần kích hoạt lại</param>
/// <param name="ReactivatedBy">Admin user ID / ID Admin kích hoạt lại</param>
public record ReactivateMerchantCommand(
    Guid MerchantId,
    Guid ReactivatedBy) : IRequest<ReactivateMerchantResult>;

/// <summary>
/// EN: Result of merchant reactivation.
/// VI: Kết quả kích hoạt lại merchant.
/// </summary>
public record ReactivateMerchantResult(
    Guid MerchantId,
    string Status,
    DateTime ReactivatedAt);

/// <summary>
/// EN: Handler for ReactivateMerchantCommand.
/// VI: Handler cho ReactivateMerchantCommand.
/// </summary>
public class ReactivateMerchantCommandHandler : IRequestHandler<ReactivateMerchantCommand, ReactivateMerchantResult>
{
    private readonly IMerchantRepository _merchantRepository;
    private readonly ILogger<ReactivateMerchantCommandHandler> _logger;

    public ReactivateMerchantCommandHandler(
        IMerchantRepository merchantRepository,
        ILogger<ReactivateMerchantCommandHandler> logger)
    {
        _merchantRepository = merchantRepository;
        _logger = logger;
    }

    public async Task<ReactivateMerchantResult> Handle(
        ReactivateMerchantCommand request,
        CancellationToken cancellationToken)
    {
        var merchant = await _merchantRepository.GetByIdAsync(request.MerchantId, cancellationToken)
            ?? throw new DomainException($"Merchant {request.MerchantId} not found");

        merchant.Reactivate();

        _merchantRepository.Update(merchant);
        await _merchantRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

        _logger.LogInformation(
            "Merchant {MerchantId} reactivated by Admin {AdminId}",
            request.MerchantId, request.ReactivatedBy);

        return new ReactivateMerchantResult(
            merchant.Id,
            merchant.Status.Name,
            DateTime.UtcNow);
    }
}
