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

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

namespace CatalogService.API.Application.Commands;

/// <summary>
/// EN: Handler for creating a new product.
/// VI: Handler để tạo sản phẩm mới.
/// </summary>
public class CreateProductCommandHandler : IRequestHandler<CreateProductCommand, Guid>
{
    private readonly IProductRepository _productRepository;

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

    public async Task<Guid> Handle(CreateProductCommand request, CancellationToken cancellationToken)
    {
        // EN: Get ProductType enumeration
        // VI: Lấy ProductType enumeration
        var productType = Enumeration.FromDisplayName<ProductType>(request.Type);

        // EN: Convert attributes dictionary to JsonDocument
        // VI: Chuyển attributes dictionary sang JsonDocument
        JsonDocument? attributesJson = null;
        if (request.Attributes != null)
        {
            var json = JsonSerializer.Serialize(request.Attributes);
            attributesJson = JsonDocument.Parse(json);
        }

        // EN: Create product aggregate
        // VI: Tạo product aggregate
        var product = new Product(
            shopId: request.ShopId,
            name: request.Name,
            price: request.Price,
            type: productType,
            description: request.Description,
            attributes: attributesJson,
            sku: request.Sku);

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

        // EN: Add to repository and save
        // VI: Thêm vào repository và lưu
        _productRepository.Add(product);
        await _productRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

        return product.Id;
    }
}
