// EN: Command to transfer shop ownership to another merchant.
// VI: Command để chuyển quyền sở hữu shop cho merchant khác.

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

namespace MerchantService.API.Application.Commands.Shops;

/// <summary>
/// EN: Command to transfer shop ownership from one merchant to another.
/// VI: Command để chuyển quyền sở hữu shop từ merchant này sang merchant khác.
/// </summary>
public record TransferShopCommand : IRequest<TransferShopResult>
{
    /// <summary>
    /// EN: Current owner merchant ID.
    /// VI: ID merchant chủ sở hữu hiện tại.
    /// </summary>
    public Guid MerchantId { get; init; }

    /// <summary>
    /// EN: Shop ID to transfer.
    /// VI: ID shop cần chuyển.
    /// </summary>
    public Guid ShopId { get; init; }

    /// <summary>
    /// EN: New owner merchant ID.
    /// VI: ID merchant chủ sở hữu mới.
    /// </summary>
    public Guid NewMerchantId { get; init; }

    /// <summary>
    /// EN: Reason for transfer (optional).
    /// VI: Lý do chuyển (tùy chọn).
    /// </summary>
    public string? Reason { get; init; }
}

/// <summary>
/// EN: Result of shop transfer.
/// VI: Kết quả chuyển shop.
/// </summary>
public record TransferShopResult(
    Guid ShopId,
    string ShopName,
    Guid PreviousMerchantId,
    Guid NewMerchantId,
    DateTime TransferredAt
);

/// <summary>
/// EN: Handler for TransferShopCommand.
/// VI: Handler cho TransferShopCommand.
/// </summary>
public class TransferShopCommandHandler : IRequestHandler<TransferShopCommand, TransferShopResult>
{
    private readonly IMerchantRepository _merchantRepository;
    private readonly IShopRepository _shopRepository;
    private readonly ILogger<TransferShopCommandHandler> _logger;

    public TransferShopCommandHandler(
        IMerchantRepository merchantRepository,
        IShopRepository shopRepository,
        ILogger<TransferShopCommandHandler> logger)
    {
        _merchantRepository = merchantRepository;
        _shopRepository = shopRepository;
        _logger = logger;
    }

    public async Task<TransferShopResult> Handle(TransferShopCommand request, CancellationToken cancellationToken)
    {
        // EN: Verify current owner merchant exists
        // VI: Xác minh merchant chủ sở hữu hiện tại tồn tại
        var currentMerchant = await _merchantRepository.GetByIdAsync(request.MerchantId, cancellationToken);
        if (currentMerchant == null)
        {
            throw new DomainException("Current merchant not found / Không tìm thấy merchant hiện tại");
        }

        // EN: Verify shop exists and belongs to current merchant
        // VI: Xác minh shop tồn tại và thuộc về merchant hiện tại
        var shop = await _shopRepository.GetByIdAsync(request.ShopId, cancellationToken);
        if (shop == null)
        {
            throw new DomainException("Shop not found / Không tìm thấy shop");
        }

        if (shop.MerchantId != request.MerchantId)
        {
            throw new DomainException("Shop does not belong to this merchant. You do not have permission to transfer it / Shop không thuộc về merchant này. Bạn không có quyền chuyển nó");
        }

        // EN: Verify new owner merchant exists and is active
        // VI: Xác minh merchant chủ mới tồn tại và đang hoạt động
        var newMerchant = await _merchantRepository.GetByIdAsync(request.NewMerchantId, cancellationToken);
        if (newMerchant == null)
        {
            throw new DomainException("New merchant not found / Không tìm thấy merchant mới");
        }

        if (newMerchant.StatusId != MerchantStatus.Active.Id)
        {
            throw new DomainException("New merchant must be active to receive shop transfer / Merchant mới phải đang hoạt động để nhận chuyển shop");
        }

        // EN: Transfer ownership via domain method
        // VI: Chuyển quyền sở hữu qua phương thức domain
        var previousMerchantId = shop.MerchantId;
        shop.TransferOwnership(request.NewMerchantId);
        _shopRepository.Update(shop);

        await _shopRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

        _logger.LogInformation(
            "EN: Shop {ShopId} transferred from merchant {PreviousMerchantId} to {NewMerchantId}. Reason: {Reason} / VI: Shop {ShopId} đã chuyển từ merchant {PreviousMerchantId} sang {NewMerchantId}. Lý do: {Reason}",
            shop.Id, previousMerchantId, request.NewMerchantId, request.Reason ?? "N/A");

        return new TransferShopResult(
            shop.Id,
            shop.Name,
            previousMerchantId,
            request.NewMerchantId,
            DateTime.UtcNow
        );
    }
}
