<?php
/*
 * Copyright (c) 2023. RTM Business
 */

namespace WordpressModels\ORM\WooCommerceEntity;

use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\DiscriminatorColumn;
use Doctrine\ORM\Mapping\DiscriminatorMap;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\GeneratedValue;
use Doctrine\ORM\Mapping\Id;
use Doctrine\ORM\Mapping\InheritanceType;
use Doctrine\ORM\Mapping\JoinColumn;
use Doctrine\ORM\Mapping\ManyToOne;
use Doctrine\ORM\Mapping\MappedSuperclass;
use Doctrine\ORM\Mapping\OneToMany;
use Doctrine\ORM\Mapping\Table;
use Symfony\Component\Serializer\Attribute\Context;
use Symfony\Component\Serializer\Attribute\Groups;
use WordpressModels\ORM\Entity\GetMetaValueTrait;
use WordpressModels\ORM\WooCommerceEntity\OrderItem\CouponItem;
use WordpressModels\ORM\WooCommerceEntity\OrderItem\FeeItem;
use WordpressModels\ORM\WooCommerceEntity\OrderItem\LineItem;
use WordpressModels\ORM\WooCommerceEntity\OrderItem\ShippingItem;
use WordpressModels\ORM\WooCommerceEntity\PostType\ShopOrder;
use WordpressModels\Serialization\TreeDepthObjectNormalizer;

#[Entity]
#[Table(name: 'order_items')]
#[
    MappedSuperclass,
    InheritanceType('SINGLE_TABLE'),
    DiscriminatorColumn('order_item_type', type: Types::STRING, length: 200, options: ['default' => 'line_item']),
    DiscriminatorMap([
        'line_item' => LineItem::class,
        'fee' => FeeItem::class,
        'shipping' => ShippingItem::class,
        'coupon' => CouponItem::class
    ])
]
class OrderItem
{

    /**
     * @use GetMetaValueTrait<OrderItemMeta>
     */
    use GetMetaValueTrait;

    #[Id]
    #[GeneratedValue(strategy: 'IDENTITY')]
    #[Column('order_item_id', type: Types::BIGINT, options: ['unsigned' => true])]
    #[Groups(['read_order_item', 'read_order_item_simple'])]
    private ?int $id;

    #[Column('order_item_name', type: Types::STRING, nullable: true)]
    #[Groups(['read_order_item', 'read_order_item_simple'])]
    private ?string $name;

    #[ManyToOne(targetEntity: Order::class, inversedBy: 'items')]
    #[JoinColumn(name: 'order_id', referencedColumnName: 'id')]
    #[Groups(['read_order_item'])]
    #[Context(
        normalizationContext: [
            TreeDepthObjectNormalizer::ENABLE_MAX_TREE_DEPTH => true,
            TreeDepthObjectNormalizer::TREE_DEPTH_LIMIT => 1,
            'groups' => ['read_order']
        ]
    )]
    private Order $order;

    /**
     * @var Collection<OrderItemMeta>
     */
    #[OneToMany(mappedBy: 'orderItem', targetEntity: OrderItemMeta::class, indexBy: 'key')]
    #[JoinColumn(name: 'order_item_id', referencedColumnName: 'order_item_id')]
    #[Groups(['read_order_item', 'read_order_item_simple'])]
    private Collection $meta;

    /**
     * @return int|null
     */
    public function getId(): ?int
    {
        return $this->id;
    }

    /**
     * @param int|null $id
     * @return OrderItem
     */
    public function setId(?int $id): OrderItem
    {
        $this->id = $id;
        return $this;
    }

    /**
     * @return string|null
     */
    public function getName(): ?string
    {
        return $this->name;
    }

    /**
     * @param string|null $name
     * @return OrderItem
     */
    public function setName(?string $name): OrderItem
    {
        $this->name = $name;
        return $this;
    }

    /**
     * @return Order
     */
    public function getOrder(): Order
    {
        return $this->order;
    }

    /**
     * @param Order $order
     * @return OrderItem
     */
    public function setOrder(Order $order): OrderItem
    {
        $this->order = $order;
        return $this;
    }

    /**
     * @return Collection
     */
    public function getMeta(): Collection
    {
        return $this->meta;
    }

    /**
     * @param Collection $meta
     * @return OrderItem
     */
    public function setMeta(Collection $meta): OrderItem
    {
        $this->meta = $meta;
        return $this;
    }

}