// EN: Command to set a shop as the default/primary shop for a merchant.
// VI: Command để đặt shop làm shop mặc định/chính cho merchant.

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 set a shop as the default/primary shop for a merchant.
/// VI: Command để đặt shop làm shop mặc định/chính cho merchant.
/// </summary>
public record SetDefaultShopCommand(
    Guid MerchantId,
    Guid ShopId
) : IRequest<SetDefaultShopResult>;

/// <summary>
/// EN: Result of setting a default shop.
/// VI: Kết quả đặt shop mặc định.
/// </summary>
public record SetDefaultShopResult(
    Guid ShopId,
    string ShopName,
    bool IsDefault
);

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

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

    public async Task<SetDefaultShopResult> Handle(SetDefaultShopCommand request, CancellationToken cancellationToken)
    {
        // EN: Verify merchant exists
        // VI: Xác minh merchant tồn tại
        var merchant = await _merchantRepository.GetByIdAsync(request.MerchantId, cancellationToken);
        if (merchant == null)
        {
            throw new DomainException("Merchant not found / Không tìm thấy merchant");
        }

        // EN: Verify shop exists and belongs to merchant
        // VI: Xác minh shop tồn tại và thuộc về merchant
        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 / Shop không thuộc về merchant này");
        }

        // EN: Clear current default shop if exists
        // VI: Xóa shop mặc định hiện tại nếu có
        var currentDefault = await _shopRepository.GetDefaultByMerchantIdAsync(request.MerchantId, cancellationToken);
        if (currentDefault != null && currentDefault.Id != request.ShopId)
        {
            currentDefault.ClearDefault();
            _shopRepository.Update(currentDefault);
        }

        // EN: Set new default shop
        // VI: Đặt shop mặc định mới
        shop.SetAsDefault();
        _shopRepository.Update(shop);

        await _shopRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

        _logger.LogInformation(
            "EN: Shop {ShopId} set as default for merchant {MerchantId} / VI: Shop {ShopId} được đặt làm mặc định cho merchant {MerchantId}",
            shop.Id, request.MerchantId);

        return new SetDefaultShopResult(shop.Id, shop.Name, true);
    }
}
