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

using System.Text.Json;
using MediatR;
using CatalogService.Domain.AggregatesModel.ProductAggregate;
using CatalogService.Domain.Exceptions;

namespace CatalogService.API.Application.Commands;

/// <summary>
/// EN: Handler for updating a product.
/// VI: Handler cập nhật sản phẩm.
/// </summary>
public class UpdateProductCommandHandler : IRequestHandler<UpdateProductCommand, bool>
{
    private readonly IProductRepository _productRepository;

    public UpdateProductCommandHandler(IProductRepository productRepository)
    {
        _productRepository = productRepository ?? throw new ArgumentNullException(nameof(productRepository));
    }

    public async Task<bool> Handle(UpdateProductCommand request, CancellationToken cancellationToken)
    {
        // EN: Retrieve product aggregate
        // VI: Lấy product aggregate
        var product = await _productRepository.GetByIdAsync(request.ProductId, cancellationToken);
        
        if (product == null)
        {
            throw new DomainException($"Product with ID {request.ProductId} not found");
        }

        // EN: Update basic information
        // VI: Cập nhật thông tin cơ bản
        product.UpdateInfo(request.Name, request.Description, request.Price);

        // EN: Update category
        // VI: Cập nhật danh mục
        product.SetCategory(request.CategoryId);

        // EN: Update attributes if provided
        // VI: Cập nhật attributes nếu được cung cấp
        if (request.Attributes != null)
        {
            var json = JsonSerializer.Serialize(request.Attributes);
            var attributesJson = JsonDocument.Parse(json);
            product.UpdateAttributes(attributesJson);
        }

        // EN: Update image if provided
        // VI: Cập nhật image nếu được cung cấp
        if (request.ImageUrl != null)
        {
            product.UpdateImage(request.ImageUrl);
        }

        // EN: Update repository and save
        // VI: Cập nhật repository và lưu
        _productRepository.Update(product);
        await _productRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

        return true;
    }
}
