// EN: Order item entity representing a line item in an order.
// VI: Entity OrderItem đại diện cho một dòng hàng trong đơn hàng.

using OrderService.Domain.Exceptions;
using OrderService.Domain.SeedWork;

namespace OrderService.Domain.AggregatesModel.OrderAggregate;

/// <summary>
/// EN: Order item entity - represents a line item in the order.
/// VI: Entity OrderItem - đại diện cho một dòng hàng trong đơn hàng.
/// </summary>
public class OrderItem : Entity
{
    private Guid _productId;
    private string _productName = null!;
    private string _productType = null!; // Physical, Service, PreparedFood
    private int _quantity;
    private decimal _unitPrice;
    private string _status = null!; // Pending, Completed, Failed
    private bool _trackInventory = true; // EN: Whether to auto-deduct inventory / VI: Có tự động trừ kho hay không
    private string? _metadata; // Additional data as JSON

    /// <summary>
    /// EN: Product ID from Catalog Service.
    /// VI: ID sản phẩm từ Catalog Service.
    /// </summary>
    public Guid ProductId => _productId;

    /// <summary>
    /// EN: Product name (snapshot at order time).
    /// VI: Tên sản phẩm (snapshot tại thời điểm đặt hàng).
    /// </summary>
    public string ProductName => _productName;

    /// <summary>
    /// EN: Product type for strategy routing.
    /// VI: Loại sản phẩm để định tuyến strategy.
    /// </summary>
    public string ProductType => _productType;

    /// <summary>
    /// EN: Quantity ordered.
    /// VI: Số lượng đặt hàng.
    /// </summary>
    public int Quantity => _quantity;

    /// <summary>
    /// EN: Unit price at order time.
    /// VI: Giá đơn vị tại thời điểm đặt hàng.
    /// </summary>
    public decimal UnitPrice => _unitPrice;

    /// <summary>
    /// EN: Total price for this line item.
    /// VI: Tổng giá cho dòng hàng này.
    /// </summary>
    public decimal TotalPrice => _quantity * _unitPrice;

    /// <summary>
    /// EN: Status of this line item.
    /// VI: Trạng thái của dòng hàng này.
    /// </summary>
    public string Status => _status;

    /// <summary>
    /// EN: Whether this item should auto-deduct inventory when ordered.
    /// VI: Có tự động trừ kho khi đặt hàng hay không.
    /// </summary>
    public bool TrackInventory => _trackInventory;

    /// <summary>
    /// EN: Additional metadata as JSON.
    /// VI: Metadata bổ sung dưới dạng JSON.
    /// </summary>
    public string? Metadata => _metadata;

    /// <summary>
    /// EN: Private constructor for EF Core.
    /// VI: Constructor private cho EF Core.
    /// </summary>
    protected OrderItem()
    {
    }

    /// <summary>
    /// EN: Create a new order item.
    /// VI: Tạo order item mới.
    /// </summary>
    public OrderItem(
        Guid productId,
        string productName,
        string productType,
        int quantity,
        decimal unitPrice,
        string? metadata = null,
        bool trackInventory = true)
    {
        if (productId == Guid.Empty)
            throw new DomainException("Product ID cannot be empty");
        if (string.IsNullOrWhiteSpace(productName))
            throw new DomainException("Product name cannot be empty");
        if (string.IsNullOrWhiteSpace(productType))
            throw new DomainException("Product type cannot be empty");
        if (quantity <= 0)
            throw new DomainException("Quantity must be greater than zero");
        if (unitPrice < 0)
            throw new DomainException("Unit price cannot be negative");

        Id = Guid.NewGuid();
        _productId = productId;
        _productName = productName.Trim();
        _productType = productType.Trim();
        _quantity = quantity;
        _unitPrice = unitPrice;
        _status = "Pending";
        _metadata = metadata;
        _trackInventory = trackInventory;
    }

    /// <summary>
    /// EN: Mark item as completed.
    /// VI: Đánh dấu item hoàn thành.
    /// </summary>
    public void MarkAsCompleted()
    {
        _status = "Completed";
    }

    /// <summary>
    /// EN: Mark item as failed.
    /// VI: Đánh dấu item thất bại.
    /// </summary>
    public void MarkAsFailed()
    {
        _status = "Failed";
    }
}
