// EN: Command to update an existing shop.
// VI: Command để cập nhật shop.

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 update an existing shop.
/// VI: Command để cập nhật shop.
/// </summary>
public record UpdateShopCommand : IRequest<bool>
{
    /// <summary>
    /// EN: User ID extracted from JWT claims by the controller.
    /// VI: User ID được lấy từ JWT claims bởi controller.
    /// </summary>
    public Guid UserId { get; init; }

    /// <summary>
    /// EN: Shop ID to update.
    /// VI: ID shop cần cập nhật.
    /// </summary>
    public Guid ShopId { get; init; }

    /// <summary>
    /// EN: Shop name.
    /// VI: Tên shop.
    /// </summary>
    public string Name { get; init; } = null!;

    /// <summary>
    /// EN: Shop description.
    /// VI: Mô tả shop.
    /// </summary>
    public string? Description { get; init; }

    /// <summary>
    /// EN: Phone number.
    /// VI: Số điện thoại.
    /// </summary>
    public string? Phone { get; init; }

    /// <summary>
    /// EN: Email address.
    /// VI: Địa chỉ email.
    /// </summary>
    public string? Email { get; init; }

    /// <summary>
    /// EN: Website URL.
    /// VI: URL website.
    /// </summary>
    public string? Website { get; init; }

    /// <summary>
    /// EN: Logo URL.
    /// VI: URL logo.
    /// </summary>
    public string? LogoUrl { get; init; }

    /// <summary>
    /// EN: Cover image URL.
    /// VI: URL ảnh bìa.
    /// </summary>
    public string? CoverImageUrl { get; init; }
}

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

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

    public async Task<bool> Handle(UpdateShopCommand 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)
            ?? throw new DomainException("Merchant not found");

        // EN: Get and validate shop ownership
        // VI: Lấy và kiểm tra quyền sở hữu shop
        var shop = await _shopRepository.GetByIdAsync(request.ShopId, cancellationToken)
            ?? throw new DomainException("Shop not found");

        if (shop.MerchantId != merchant.Id)
        {
            throw new DomainException("You do not have permission to update this shop");
        }

        // EN: Update shop information
        // VI: Cập nhật thông tin shop
        shop.UpdateInfo(request.Name, request.Description);

        // EN: Update contact info
        // VI: Cập nhật thông tin liên hệ
        shop.UpdateContactInfo(new ContactInfo
        {
            Phone = request.Phone ?? string.Empty,
            Email = request.Email,
            Website = request.Website
        });

        // EN: Update images
        // VI: Cập nhật hình ảnh
        shop.UpdateImages(request.LogoUrl, request.CoverImageUrl);

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

        _logger.LogInformation(
            "Shop updated: {ShopId} by merchant {MerchantId}",
            shop.Id, merchant.Id);

        return true;
    }
}
