<?php 
 
namespace Whater\Domain\Product\Model; 
 
use Ramsey\Uuid\Uuid; 
use Whater\Domain\Common\Exception\InvalidUUIDException; 
use Whater\Domain\Product\Exception\InvalidOrderItemUpdateException; 
 
/** 
 * Class CartOrderItem 
 * 
 * @package Whater\Domain\Product\Model 
 */ 
class CartOrderItem 
{ 
 
    /** 
     * @var string 
     */ 
    private $uuid; 
 
    /** 
     * @var CartOrder 
     */ 
    private $cartOrder; 
 
    /** 
     * @var CartOrderPackage 
     */ 
    private $cartOrderPackage; 
 
    /** 
     * @var Product 
     */ 
    private $product; 
 
    /** 
     * @var string 
     */ 
    private $itemDescription; 
 
    /** 
     * @var float 
     */ 
    private $pricePerUnit; 
 
    /** 
     * @var float 
     */ 
    private $taxesPercent; 
 
    /** 
     * @var int 
     */ 
    private $units; 
 
    /** 
     * @var array 
     */ 
    private $meta; 
 
    /** 
     * @var int 
     */ 
    private $lineOrder; 
 
    /** 
     * @var ProductVariation 
     */ 
    private $productVariation; 
 
    /** 
     * @var ProductValoration 
     */ 
    private $productValoration; 
 
    /** 
     * @var \DateTime 
     */ 
    private $createdAt; 
 
    /** 
     * @var null|\DateTime 
     */ 
    private $updatedAt; 
 
    /** 
     * OrderItem constructor. 
     */ 
    public function __construct( 
        ?string $cartOrderItemId = null, 
        CartOrder $cartOrder, 
        Product $product, 
        float $pricePerUnit, 
        float $taxesPercent, 
        int $units, 
        ?string $itemDescription = null, 
        int $lineOrder = 1, 
        ?ProductVariation $productVariation = null 
    ) { 
        try { 
            $this->uuid = Uuid::fromString($cartOrderItemId ?: Uuid::uuid4())->toString(); 
        } catch (\InvalidArgumentException $e) { 
            throw new InvalidUUIDException(); 
        } 
 
        $this->cartOrder = $cartOrder; 
        $this->product = $product; 
        $this->pricePerUnit = $pricePerUnit; 
        $this->taxesPercent = $taxesPercent; 
        $this->units = $units; 
        $this->lineOrder = $lineOrder; 
        $this->itemDescription = $itemDescription; 
        $this->meta = []; 
        $this->productVariation = $productVariation; 
        $this->createdAt = new \DateTime(); 
        $this->updatedAt = new \DateTime(); 
    } 
 
    public function updatePrice( 
        float $pricePerUnit, 
        float $taxesPercent, 
        int $units 
    ) { 
        if ($this->cartOrder()->status() == CartOrder::ORDER_STATUS_PENDING) { 
            $this->pricePerUnit = $pricePerUnit; 
            $this->taxesPercent = $taxesPercent; 
            $this->units = $units; 
            $this->updatedAt = new \DateTime(); 
        } else { 
            throw new InvalidOrderItemUpdateException(); 
        } 
        return $this; 
    } 
 
    public function updateMeta( 
        array $meta 
    ) { 
        $this->meta = $meta; 
        $this->updatedAt = new \DateTime(); 
    } 
 
    public function updateDescription( 
        ?string $itemDescription = null 
    ) { 
        $this->itemDescription = $itemDescription; 
        $this->updatedAt = new \DateTime(); 
        return $this; 
    } 
 
    public function updateCartOrderPackage( 
        ?CartOrderPackage $cartOrderPackage = null 
    ) { 
        $this->cartOrderPackage = $cartOrderPackage; 
    } 
 
    /** 
     * @return string 
     */ 
    public function id(): string 
    { 
        return $this->uuid; 
    } 
 
    /** 
     * @return CartOrder 
     */ 
    public function cartOrder(): CartOrder 
    { 
        return $this->cartOrder; 
    } 
 
    /** 
     * @return Product 
     */ 
    public function product(): Product 
    { 
        return $this->product; 
    } 
 
    /** 
     * @return ProductValoration 
     */ 
    public function productValoration(): ?ProductValoration 
    { 
        return $this->productValoration; 
    } 
 
    /** 
     * @return CartOrderPackage 
     */ 
    public function cartOrderPackage(): CartOrderPackage 
    { 
        return $this->cartOrderPackage; 
    } 
 
    /** 
     * @return float 
     */ 
    public function pricePerUnit(): float 
    { 
        return $this->pricePerUnit; 
    } 
 
    /** 
     * @return float 
     */ 
    public function taxesPercent(): float 
    { 
        return $this->taxesPercent; 
    } 
 
    /** 
     * @return float 
     */ 
    public function itemDescription(): string 
    { 
        return $this->itemDescription; 
    } 
 
    /** 
     * @return int 
     */ 
    public function lineOrder(): int 
    { 
        return $this->lineOrder; 
    } 
 
    /** 
     * @return int 
     */ 
    public function units(): int 
    { 
        return $this->units; 
    } 
 
    /** 
     * @return array 
     */ 
    public function meta(): ?array 
    { 
        return $this->meta; 
    } 
 
    /** 
     * @return ProductVariation 
     */ 
    public function productVariation(): ?ProductVariation 
    { 
        return $this->productVariation; 
    } 
 
    /** 
     * @return \DateTime 
     */ 
    public function createdAt(): \DateTime 
    { 
        return $this->createdAt; 
    } 
 
    /** 
     * @return \DateTime|null 
     */ 
    public function updatedAt() 
    { 
        return $this->updatedAt; 
    } 
 
    /** 
     * @return bool 
     */ 
    public function equals(CartOrderItem $cartOrderItem) 
    { 
        return $this->id() === $cartOrderItem->id(); 
    } 
}