<?php

declare(strict_types=1);

namespace KupShop\OrderingBundle\Entity\Order;

use KupShop\KupShopBundle\Util\Price\PreRoundedPrice;
use KupShop\KupShopBundle\Util\Price\Price;

class OrderItem implements \ArrayAccess
{
    private $item;

    public function __construct(array $item)
    {
        $this->item = $item;
    }

    public function getItem(): array
    {
        return $this->item;
    }

    public function getId(): int
    {
        return (int) $this->item['id'];
    }

    public function getProductId(): ?int
    {
        return $this->item['id_product'] ? (int) $this->item['id_product'] : null;
    }

    public function getVariationId(): ?int
    {
        return $this->item['id_variation'] ? (int) $this->item['id_variation'] : null;
    }

    public function getPieces(): float
    {
        return (float) $this->item['pieces'];
    }

    public function getPiecesReserved(): float
    {
        return (float) $this->item['pieces_reserved'];
    }

    public function getEAN(): ?string
    {
        return !empty($this->item['ean']) ? formatEAN($this->item['ean']) : null;
    }

    public function getVariationTitle(): ?string
    {
        return $this->item['variation_title'];
    }

    public function getDescr(): string
    {
        return $this->item['descr'];
    }

    public function getPiecePrice(): Price
    {
        return new PreRoundedPrice($this->item['piece_price']['value_without_vat'], $this->item['piece_price']['currency_object'], $this->item['piece_price']['vat']);
    }

    public function getTotalPrice(): Price
    {
        return new PreRoundedPrice($this->item['total_price']['value_without_vat'], $this->item['total_price']['currency_object'], $this->item['total_price']['vat']);
    }

    public function getDiscount(): \Decimal
    {
        return $this->item['discount'];
    }

    public function getVat(): float
    {
        return (float) $this->item['vat'];
    }

    public function getNote(): array
    {
        return $this->item['note'] ?? [];
    }

    public function getInStore(): ?float
    {
        return (float) $this->item['in_store'];
    }

    public function getProducer(): ?string
    {
        return $this->item['producer'];
    }

    public function getProducerId(): ?int
    {
        return $this->item['id_producer'] ? (int) $this->item['id_producer'] : null;
    }

    public function getCampaign(): ?string
    {
        return $this->item['campaign'];
    }

    public function getSectionName(): ?string
    {
        return $this->item['section_name'];
    }

    public function getSectionId(): ?int
    {
        return $this->item['section_id'] ? (int) $this->item['section_id'] : null;
    }

    public function getCode(): ?string
    {
        return $this->item['code'];
    }

    public function getSuppliersCodes(): ?string
    {
        return $this->item['suppliers_codes'];
    }

    public function getWeight(): ?float
    {
        return $this->item['weight'] ? (float) $this->item['weight'] : ($this->item['product']['weight'] ?? null);
    }

    public function getProduct(): ?\Product
    {
        if ($this->item['product'] ?? false) {
            return $this->item['product'];
        }

        return null;
    }

    public function offsetMethod($offset): string
    {
        return 'get'.ucfirst($offset);
    }

    public function offsetSet($offset, $value): void
    {
        $this->item[$offset] = $value;
    }

    public function offsetExists($offset): bool
    {
        return isset($this->getItem()[$offset]) || method_exists($this, $this->offsetMethod($offset));
    }

    public function offsetUnset($offset): void
    {
        unset($this->item[$offset]);
    }

    public function offsetGet($offset): mixed
    {
        $method = $this->offsetMethod($offset);
        if (method_exists($this, $method)) {
            return call_user_func([$this, $method]);
        }

        if ($this->getItem()[$offset] ?? false) {
            return $this->getItem()[$offset];
        }

        return null;
    }
}
