<?php


namespace Shop\Application\Shopping\CreateProviderOrdersFromCustomerOrderItem;


use Shop\Application\Shopping\CreateProviderOrder\CreateProviderOrderCommand;
use Shop\Config\Main;
use Shop\Domain\ProviderOrder\ProviderOrderCollection;
use Shop\Repositories\OrderItem\OrderItemRepository;
use spaceonfire\CommandBus\CommandBus;

class CreateProviderOrdersFromCustomerOrderItemHandler
{
    protected $itemRepository;
    protected $mainConf;
    protected $commandBus;

    /**
     * CreateProviderOrdersFromCustomerOrderItemHandler constructor.
     * @param OrderItemRepository $itemRepository
     * @param CommandBus $commandBus
     * @param Main $mainConf
     */
    public function __construct(OrderItemRepository $itemRepository,
                                CommandBus $commandBus,
                                Main $mainConf)
    {
        $this->itemRepository = $itemRepository;
        $this->mainConf = $mainConf;
        $this->commandBus = $commandBus;
    }

    public function handle(CreateProviderOrdersFromCustomerOrderItemCommand $command): void
    {

        $ids = $command->getIds();

        //проход по позициям, группировка по поставщикам
        $contractors = $errorsFound = $errorsContractor = $errorStates = [];
        /**
         * @var OrderItem $item
         */
        foreach ($ids as $id) {

            if (!$item = $this->itemRepository->findById($id)) {
                $errorsFound[] = $id;
                continue;
            }

            if (in_array($item->getStateId(), [$this->mainConf->getStateProviderDefault(),
                $this->mainConf->getStateProviderSend()
            ], true)) {
                $errorStates [] = $id;
                continue;
            }

            $providerContractorId = $item->getProvider()->getContractorId();

            if (!$providerContractorId) {
                $errorsContractor[] = $id;
                continue;
            }

            $contractors[$item->getOrder()->getContractorId()][$providerContractorId][] = $item;
        }


        $providerOrderCollections = new ProviderOrderCollection();


        //проход по поставщикам, создание заказов
        foreach ($contractors as $contractorId => $providers) {

            foreach ($providers as $contractorProviderId => $items) {

                $deliveryAddress = '';
                $requestItems = [];

                foreach ($items as $item) {

                    $requestItems [] = (new ProviderOrderItemRequest())
                        ->setCustomerOrderItemId($item->getId())
                        ->setName($item->getName())
                        ->setDesc($item->getDesc())
                        ->setPrice($item->getPrice())
                        ->setAmount($item->getAmount())
                        ->setArticle($item->getArticle())
                        ->setBrand($item->getBrand())
                        ->setCurrencyId($item->getCurrencyId())
                        ->setManagerComment($item->getmenagerComment())
                        ->setProviderId($item->getProviderId())
                        ->setDestination($item->getDestination())
                        ->setRefId($item->getRefId());

                    if (!$deliveryAddress) {
                        $deliveryAddress = $item->getOrder()->getContractor()->getFullAddress();
                    }
                }

                $orderRequest = (new \Shop\Application\Shopping\CreateProviderOrder\OrderRequest())
                    ->setItems($requestItems)
                    ->setClientId($contractorId)
                    ->setContractorId($contractorProviderId)
                    ->setDeliveryAddress($deliveryAddress)
                    //@todo платежа тип должна идти по умолчанию от клиента
                    ->setPaymentId(1);

                //создаем заказ поставщику
                $result = new \Shop\Application\Shopping\CreateProviderOrder\Result();
                $this->commandBus->handle(new CreateProviderOrderCommand($orderRequest,$result));

                $providerOrder = $result->getOrder();

                //добавляем коллекцию новых заказов
                $providerOrderCollections->push($providerOrder);
            }
        }

        if (count($errorsFound) || count($errorsContractor) || count($errorStates)) {
            throw new CreateProviderOrdersException(
                $providerOrderCollections,
                $errorsFound,
                $errorsContractor,
                $errorStates
            );
        }

        $command->getResult()->setProviderOrderCollection($providerOrderCollections);

    }

}