<?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\Components;

use Doctrine\ORM\Query\Expr;
use Shopware\Bundle\AttributeBundle\Repository\SearchCriteria;
use Shopware\Bundle\AttributeBundle\Repository\Searcher\GenericSearcher;
use Shopware\Bundle\AttributeBundle\Repository\Searcher\SearcherInterface;
use Shopware\Bundle\AttributeBundle\Repository\Searcher\SearcherResult;
use Shopware\Components\Model\ModelManager;
use Shopware\Components\Model\SearchBuilder;
use Shopware\CustomModels\ViisonPickwareERP\StockLedger\StockItem;
use Shopware\CustomModels\ViisonPickwareERP\StockLedger\StockItemPropertyValue;
use Shopware\CustomModels\ViisonPickwareERP\StockLedger\StockLedgerEntry;
use Shopware\Models\Order\Order;

class OrderSearcherDecorator extends GenericSearcher
{
    private $decoratedInstance;

    /**
     * OrderSearcherDecorator constructor.
     *
     * @param $entity
     * @param ModelManager $entityManager
     * @param SearchBuilder|null $searchBuilder
     * @param SearcherInterface $decoratedInstance
     */
    public function __construct(
        SearcherInterface $decoratedInstance,
        $entity,
        ModelManager $entityManager,
        SearchBuilder $searchBuilder = null
    ) {
        $this->decoratedInstance = $decoratedInstance;

        parent::__construct($entity, $entityManager, $searchBuilder);
    }

    public function search(SearchCriteria $criteria)
    {
        $showpareSearchResult = $this->decoratedInstance->search($criteria);

        $propertyValueSearchResult = parent::search($criteria);

        $newSearcherResult = new SearcherResult(
            array_merge($showpareSearchResult->getIdentifiers(), $propertyValueSearchResult->getIdentifiers()),
            $showpareSearchResult->getCount() + $propertyValueSearchResult->getCount()
        );

        return $newSearcherResult;
    }

    /**
     * @param SearchCriteria $criteria
     *
     * @return \Doctrine\ORM\QueryBuilder|\Shopware\Components\Model\QueryBuilder
     */
    protected function createQuery(SearchCriteria $criteria)
    {
        $query = $this->entityManager->createQueryBuilder();
        $query->select($this->getIdentifierField());
        $query->from(Order::class, 'entity', $this->getIdentifierField());
        $query->leftJoin('entity.payment', 'payment');
        $query->leftJoin('entity.dispatch', 'dispatch');
        $query->leftJoin('entity.shop', 'shop');
        $query->leftJoin('entity.billing', 'billing');
        $query->leftJoin('entity.customer', 'customer');
        $query->leftJoin('entity.documents', 'document');
        $query->leftJoin('billing.country', 'billingCountry');
        $query->leftJoin('entity.details', 'details');
        $query->leftJoin(StockLedgerEntry::class, 'sle', Expr\Join::WITH, 'sle.orderDetailId = details.id');
        $query->leftJoin(StockItem::class, 'item', Expr\Join::WITH, 'item.stockLedgerEntryId = sle.id');
        $query->leftJoin(StockItemPropertyValue::class, 'propertyValue', Expr\Join::WITH, 'propertyValue.stockItemId = item.id');
        $query->setAlias('entity');

        return $query;
    }

    /**
     * @param SearchCriteria $criteria
     *
     * @return array|string[]
     */
    protected function getSearchFields(SearchCriteria $criteria)
    {
        return [
            'propertyValue.value^2',
        ];
    }
}
