<?php

namespace KupShop\ProductsChargesBundle\EventListener;

use KupShop\KupShopBundle\Util\Price\Price;
use KupShop\OrderingBundle\Event\OrderItemEvent;
use KupShop\OrderingBundle\Util\Order\OrderItemInfo;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class OrderItemListener implements EventSubscriberInterface
{
    use \DatabaseCommunication;

    public static function getSubscribedEvents()
    {
        return [
            OrderItemEvent::ITEM_CREATED => [
                ['itemCharge', 200],
            ],
        ];
    }

    public function itemCharge(OrderItemEvent $event)
    {
        $product = $event->getProduct();
        $data = $event->getData();
        $items_table = $data['items_table'];
        $row = $data['row'];

        $note = $product->parseNote($row['note'] ?? false);

        // ----------------------------------------------------------------
        // kdyz je u zbozi příplatek, ktery nebyl jeste zapocitan v cene
        foreach ($product->fetchCharges($note['charges'] ?? []) as $charge) {
            if ($charge['included'] == 'N' && $charge['active']) {
                /** @var Price $price */
                $price = $charge['price'];

                $PiecePrice = $price->getPriceWithoutVat();

                if (($charge['data']['onetime'] ?? 'N') === 'Y') {
                    $chargePieces = \DecimalConstants::one();
                } else {
                    $chargePieces = toDecimal($row['pieces']);
                }

                $TotalPrice = $PiecePrice->mul($chargePieces);

                $itemData = [
                    'charge' => [
                        'id_product_charge' => $charge['id'],
                        'id_charge' => $charge['id_charge'],
                        'id_product' => $charge['id_product'],
                        'id_item_parent' => $row['id'],
                    ],
                    'item_type' => OrderItemInfo::TYPE_CHARGE,
                ];
                $productTitle = !empty($product->title) ? $product->title : $product->descr;
                $chargeTitle = !empty($charge['title']) ? $charge['title'] : $charge['admin_title'];
                if (!empty($charge['product']['code'])) {
                    $code = str_replace('%CODE', trim($charge['product']['code']), translate('code', 'order'));
                    $chargeTitle = "{$chargeTitle} {$code}";
                }
                $productTitle = "{$chargeTitle}: {$productTitle}";
                $charge_product = $charge['product'] ?? null;
                $id_product = ($charge_product ? $charge_product->id : null);
                $id_variation = ($charge_product ? $charge_product->variationId : null);
                // zapsat polozku do DB
                $this->insertSQL(
                    $items_table,
                    [
                        'id_order' => $row['id_order'],
                        'id_product' => $id_product,
                        'id_variation' => $id_variation,
                        'pieces' => $chargePieces,
                        'pieces_reserved' => $chargePieces,
                        'piece_price' => $PiecePrice,
                        'total_price' => $TotalPrice,
                        'descr' => $productTitle,
                        'tax' => $this->getChargeItemVat($product, $charge),
                        'note' => json_encode($itemData),
                    ]
                );
                if ($charge_product) {
                    $charge_product->sell($id_variation, $row['pieces']);
                }

                // total price of whole order
                $orderTotalPrice = $event->getPrice();
                $orderTotalPrice = $orderTotalPrice->add($TotalPrice->addVat($this->getChargeItemVat($product, $charge)));

                // update total price of order
                $event->setPrice($orderTotalPrice);
            }
        }
    }

    protected function getChargeItemVat(\Product $product, array $charge): float
    {
        return $charge['price']->getVat()->asFloat();
    }
}
