<?php
// Copyright (c) Pickware GmbH. All rights reserved.
// This file is part of software that is released under a proprietary license.
// You must not copy, modify, distribute, make publicly available, or execute
// its contents or parts thereof without express permission by the copyright
// holder, unless otherwise permitted by law.

namespace Shopware\Plugins\ViisonPickwareCommon\Subscribers\Backend;

use Doctrine\ORM\QueryBuilder;
use Shopware\CustomModels\ViisonPickwareERP\StockLedger\StockItemPropertyValue;
use Shopware\Plugins\ViisonCommon\Classes\Subscribers\Base as BaseSubscriber;

class Search extends BaseSubscriber
{
    /**
     * @return array
     */
    public static function getSubscribedEvents()
    {
        return [
            'Shopware\\Models\\Order\\Repository::searchInOrders::after' => 'afterSearchInOrders',
            'Shopware_Controllers_Backend_Search::getOrders::after' => 'afterGetOrders',
        ];
    }

    /**
     * Add the search results for StockItemPropertyValues to the normal order search result for the Backend Order search.
     *
     * @param \Enlight_Hook_HookArgs $args
     * @throws \Exception
     */
    public function afterSearchInOrders(\Enlight_Hook_HookArgs $args)
    {
        $searchResult = $args->getReturn();

        $searchTerm = $args->get('term');
        $result = $this->createStockItemPropertyValueQuery($searchTerm);

        foreach ($result as $stockItem) {
            $searchResult[] = $stockItem->getStockItem()->getStockLedgerEntry()->getOrderDetail()->getOrder()->getId();
        }

        $args->setReturn($searchResult);
    }

    /**
     * Add the search results for StockItemPropertyValues to the normal order search result for the Global Search in
     * SW < 5.5.
     *
     * @param \Enlight_Hook_HookArgs $args
     */
    public function afterGetOrders(\Enlight_Hook_HookArgs $args)
    {
        $searchResult = $args->getReturn();

        $searchTerm = $args->get('search');
        $result = $this->createStockItemPropertyValueQuery($searchTerm);

        foreach ($result as $stockItem) {
            /** @var \Shopware\Models\Order\Order $order */
            $order = $stockItem->getStockItem()->getStockLedgerEntry()->getOrderDetail()->getOrder();
            $description = sprintf(
                '%s %s, %s',
                $order->getBilling()->getFirstName(),
                $order->getBilling()->getLastName(),
                $order->getPayment()->getDescription()
            );
            $newOrder = [
                'id' => $order->getId(),
                'name' => $order->getNumber(),
                'userID' => $order->getCustomer()->getId(),
                'totalAmount' => $order->getInvoiceAmount(),
                'transactionID' => $order->getTransactionId(),
                'status' => $order->getOrderStatus()->getId(),
                'cleared' => $order->getPaymentStatus()->getId(),
                'type' => $order->getDocuments()->first()->getType(),
                'docID' => $order->getDocuments()->first()->getId(),
                'description' => $description,
            ];
            $searchResult[] = $newOrder;
        }

        $args->setReturn($searchResult);
    }

    /**
     * Create the search query for stockItemPropertyValue and return its result.
     *
     * @param $searchTerm
     * @return null|array
     */
    private function createStockItemPropertyValueQuery($searchTerm)
    {
        /** @var QueryBuilder $builder */
        $builder = $this->get('models')->createQueryBuilder();
        $builder
            ->select('property')
            ->from(StockItemPropertyValue::class, 'property')
            ->leftJoin('property.stockItem', 'stockItem')
            ->leftJoin('stockItem.stockLedgerEntry', 'stockEntry')
            ->where('property.value LIKE :value')
            ->andWhere('stockEntry.orderDetailId IS NOT NULL')
            ->setParameter('value', '%' . $searchTerm . '%');

        $query = $builder->getQuery();

        return $query->getResult();
    }
}
