// EN: Handler for AddShopBranchCommand.
// VI: Handler cho AddShopBranchCommand.

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

namespace MerchantService.API.Application.Commands.Shops;

/// <summary>
/// EN: Handler for adding a branch to a shop.
/// VI: Handler để thêm chi nhánh vào shop.
/// </summary>
public class AddShopBranchCommandHandler : IRequestHandler<AddShopBranchCommand, AddShopBranchResult>
{
    private readonly IMerchantRepository _merchantRepository;
    private readonly IShopRepository _shopRepository;
    private readonly ILogger<AddShopBranchCommandHandler> _logger;

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

    public async Task<AddShopBranchResult> Handle(AddShopBranchCommand request, CancellationToken cancellationToken)
    {
        // EN: Use user ID passed from the controller
        // VI: Dùng user ID được truyền từ controller
        var userId = request.UserId;

        // EN: Get merchant by user ID
        // VI: Lấy merchant theo user ID
        var merchant = await _merchantRepository.GetByUserIdAsync(userId, cancellationToken);
        if (merchant == null)
        {
            throw new DomainException("Merchant not found");
        }

        // EN: Get shop and verify ownership
        // VI: Lấy shop và xác minh quyền sở hữu
        var shop = await _shopRepository.GetByIdWithBranchesAsync(request.ShopId, cancellationToken);
        if (shop == null)
        {
            throw new DomainException("Shop not found");
        }

        if (shop.MerchantId != merchant.Id)
        {
            throw new DomainException("You don't have permission to modify this shop");
        }

        // EN: Create address
        // VI: Tạo địa chỉ
        var address = new Address
        {
            Street = request.Street,
            Ward = request.Ward,
            District = request.District,
            City = request.City,
            Province = request.Province
        };

        // EN: Create geo location if provided
        // VI: Tạo vị trí địa lý nếu có
        GeoLocation? location = null;
        if (request.Latitude.HasValue && request.Longitude.HasValue)
        {
            location = new GeoLocation
            {
                Latitude = request.Latitude.Value,
                Longitude = request.Longitude.Value
            };
        }

        // EN: Add branch to shop
        // VI: Thêm chi nhánh vào shop
        var branch = shop.AddBranch(request.Name, address, location);
        
        // EN: Set phone if provided
        // VI: Đặt số điện thoại nếu có
        if (!string.IsNullOrWhiteSpace(request.Phone))
        {
            branch.SetPhone(request.Phone);
        }

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

        _logger.LogInformation(
            "Branch added: {BranchId} to shop {ShopId}",
            branch.Id, shop.Id);

        return new AddShopBranchResult(
            branch.Id,
            branch.Name,
            address.FullAddress
        );
    }
}
