<?php

namespace KupShop\ComponentsBundle\Twig\Components\Account;

use KupShop\KupShopBundle\Util\Price\Price;
use KupShop\OrderingBundle\Util\Order\OrderInfo;
use Query\Operator;
use Symfony\Contracts\Service\Attribute\Required;
use Symfony\Contracts\Translation\TranslatorInterface;

trait OrderTemplateTrait
{
    protected int $editable;
    protected string $securityCode;
    protected ?\DeliveryType $deliveryType = null;

    #[Required]
    public TranslatorInterface $translatorInterface;

    public function getOrderNo(): string
    {
        return $this->order->getOrderNo();
    }

    public function getStatus(): int
    {
        $order = $this->order->getObject();
        if ($order instanceof \Order) {
            return $this->order->getObject()->status_storno == 1 ? -1 : $this->order->getStatus();
        }

        return $this->order->getStatus();
    }

    public function getStatusText(): string
    {
        if ($this->isEditable() > 1) {
            return $this->translatorInterface->trans('process.order.stopped', [], 'orders');
        }

        return $this->order->getStatusText();
    }

    public function isEditable(): int
    {
        if (!isset($this->editable)) {
            $this->editable = $this->order->isEditable();
        }

        return $this->editable;
    }

    public function getDateCreated(): ?\DateTimeInterface
    {
        return $this->order->getDateCreated();
    }

    public function getNote(): ?string
    {
        $order = $this->order->getObject();
        if (!($order instanceof \Order)) {
            return null;
        }

        return $order->note_user;
    }

    public function isShowInvoice(): bool
    {
        $order = $this->order->getObject();
        if (!($order instanceof \Order)) {
            return false;
        }

        $show_invoice = findModule('orders', 'show_invoice', 'Y');

        return ($show_invoice == 'Y') && !empty($order->date_handle);
    }

    public function getTitle(): string
    {
        return $this->order->getTitle();
    }

    public function getTotalPrice(bool $withVat = true): Price
    {
        $totalPrice = $this->order->getTotalPrice();
        if ($withVat) {
            $price = $totalPrice->getPriceWithVat();
        } else {
            $price = $totalPrice->getPriceWithoutVat();
        }

        return new Price($price, $totalPrice->getCurrency(), toDecimal(0));
    }

    public function hasDeliveryType(): bool
    {
        $order = $this->order->getObject();
        if (!($order instanceof \Order)) {
            return false;
        }

        return $order->getDeliveryId() > 0;
    }

    protected function getDeliveryType(): ?\DeliveryType
    {
        $order = $this->order->getObject();
        if (!($order instanceof \Order)) {
            return null;
        }

        if (!isset($this->deliveryType)) {
            $deliveryId = $order->getDeliveryId();
            if ($deliveryId > 0) {
                $this->deliveryType = $order->getDeliveryType($deliveryId);
            }
        }

        return $this->deliveryType;
    }

    public function getDeliveryTypeName(): ?string
    {
        $order = $this->order->getObject();
        if (!($order instanceof \Order)) {
            return null;
        }

        if ($this->getDeliveryType()) {
            $name = [$this->deliveryType->delivery, $this->deliveryType->payment];

            return join(', ', array_filter($name));
        }

        return null;
    }

    public function getTrackAndTraceLink(): ?string
    {
        $order = $this->order->getObject();
        if (!($order instanceof \Order)) {
            return null;
        }
        if ($this->getDeliveryType() && !empty($order->package_id)) {
            return $this->deliveryType->getDelivery()->getTrackAndTraceLink($order->package_id, $order);
        }

        return null;
    }

    public function getUrl(): string
    {
        return $this->order->getUrl();
    }

    public function getEditUrl(): string
    {
        return $this->order->getEditUrl();
    }

    protected function getSecurityCode(): string
    {
        assert($this->order->getObject() instanceof \Order);

        if (!isset($this->securityCode)) {
            $this->securityCode = $this->order->getObject()->getSecurityCode();
        }

        return $this->securityCode;
    }

    public function getReorderUrl(): ?string
    {
        if (!($this->order->getObject() instanceof \Order)) {
            return null;
        }

        if ($this->order->getSource() === OrderInfo::ORDER_SOURCE_RETURNS) {
            return null;
        }

        if (!$this->order->hasProducts()) {
            return null;
        }

        return path('kupshop_content_orders_orderreorder', [
            'id' => $this->order->getId(),
            'cf' => $this->getSecurityCode(),
        ]);
    }

    public function getInvoiceUrl(): string
    {
        return path('kupshop_orderingbundle_pdfinvoice', [
            'id_order' => $this->order->getId(),
            'cf' => $this->getSecurityCode(),
        ]);
    }

    public function getReturnUrl(): ?string
    {
        $order = $this->order->getObject();
        if (!findModule(\Modules::RETURNS) || !($order instanceof \Order)) {
            return null;
        }

        if (!isset($this->returnUrl)) {
            if (!$order->status_storno
                && in_array($order->status, getStatuses('handled'))
                && ($order->source != OrderInfo::ORDER_SOURCE_RETURNS)
                && $this->order->hasProducts()
                && sqlQueryBuilder()->select('NOW() < date_return_to')
                    ->from('order_returns_info')
                    ->where(Operator::equals(['id_order' => $order->id]))
                    ->execute()->fetchOne()
            ) {
                return path('kupshop_returns_returns_createreturn',
                    ['id_order' => $order->id, 'cf' => $order->getSecurityCode()]);
            }

            return null;
        }

        return $this->returnUrl;
    }

    public function getReclamationUrl(): ?string
    {
        $order = $this->order->getObject();
        if (!findModule(\Modules::RECLAMATIONS) || !($order instanceof \Order)) {
            return null;
        }

        if (!isset($this->reclamationUrl)) {
            if (!$order->status_storno
                && in_array($order->status, getStatuses('handled'))
                && ($order->source != OrderInfo::ORDER_SOURCE_RETURNS)
                && $this->order->hasProducts()
            ) {
                return path('kupshop_reclamations_reclamations_createreclamation',
                    ['id_order' => $order->id, 'cf' => $order->getSecurityCode()]);
            }

            return null;
        }

        return $this->reclamationUrl;
    }
}
