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

use Shopware\CustomModels\ViisonPickwareERP\Warehouse\Warehouse;
use Shopware\CustomModels\ViisonPickwareMobile\PickProfile\PickProfile;
use Shopware\CustomModels\ViisonPickwareMobile\PickProfile\PickProfileStockBasedOrderFilterExemptDispatchMethod;
use Shopware\Plugins\ViisonPickwareMobile\Components\PickingOrderFilter\OrderFilterConditionQueryComponent\OrderFilterConditionQueryComponentFactoryService;
use Shopware\Plugins\ViisonPickwareMobile\Components\PickingOrderFilter\PickingOrderFilterService;
use Shopware\Plugins\ViisonPickwareMobile\Components\PickingOrderFilter\StockBasedFilterConfiguration;

class PickProfileOrderFilterService
{
    /**
     * @var PickingOrderFilterService
     */
    protected $pickingOrderFilterService;

    /**
     * @var OrderFilterConditionQueryComponentFactoryService
     */
    protected $orderFilterConditionQueryComponentFactoryService;

    /**
     * @param PickingOrderFilterService $pickingOrderFilterService
     * @param OrderFilterConditionQueryComponentFactoryService $orderFilterConditionQueryComponentFactoryService
     */
    public function __construct(
        PickingOrderFilterService $pickingOrderFilterService,
        OrderFilterConditionQueryComponentFactoryService $orderFilterConditionQueryComponentFactoryService
    ) {
        $this->orderFilterConditionQueryComponentFactoryService = $orderFilterConditionQueryComponentFactoryService;
        $this->pickingOrderFilterService = $pickingOrderFilterService;
    }

    /**
     * Returns an array containing the IDs of all orders that pass the picking order filter configured using the passed
     * `$pickProfile` and `$warehouse`.
     *
     * @param PickProfile $pickProfile
     * @param Warehouse $warehouse
     * @return int[]
     */
    public function getIdsOfOrdersPassingFilterOfPickProfile(PickProfile $pickProfile, Warehouse $warehouse)
    {
        return $this->pickingOrderFilterService->getIdsOfOrdersPassingFilter(
            $warehouse,
            self::createStockBasedFilterConfig($pickProfile),
            $pickProfile->getEarliestReleaseDateForPreOrderedItems(),
            $this->getOrderFilterConditionQueryComponentOfPickProfile($pickProfile)
        );
    }

    /**
     * Returns an array containing the IDs of all orders that are 'waiting' for stock considering the configuration of
     * the passed `$pickProfile` and `$warehouse`.
     */
    public function getIdsOfOrdersWaitingWithStockForFilterOfPickProfile(
        PickProfile $pickProfile,
        Warehouse $warehouse
    ) {
        return $this->pickingOrderFilterService->getIdsOfOrdersWaitingForStock(
            $warehouse,
            self::createStockBasedFilterConfig($pickProfile)
        );
    }

    /**
     * Evaluates the picking order filter for the orders with the passed `$orderIds` using the `$pickProfile` and
     * `$warehouse`. The returned result of the evaluation contains all unfulfilled conditions of the orders and their
     * items.
     */
    public function getUnfulfilledConditionsForFilterOfPickProfile(
        PickProfile $pickProfile,
        Warehouse $warehouse,
        array $orderIds
    ) {
        return $this->pickingOrderFilterService->getUnfulfilledFilterConditions(
            $orderIds,
            $warehouse,
            self::createStockBasedFilterConfig($pickProfile),
            $pickProfile->getEarliestReleaseDateForPreOrderedItems(),
            $this->getOrderFilterConditionQueryComponentOfPickProfile($pickProfile)
        );
    }

    /**
     * @param PickProfile $pickProfile
     * @return StockBasedFilterConfiguration
     */
    protected static function createStockBasedFilterConfig(PickProfile $pickProfile)
    {
        return new StockBasedFilterConfiguration(
            $pickProfile->getStockBasedOrderFilterMode(),
            $pickProfile->getStockBasedOrderFilterExemptDispatchMethods()->map(
                function (PickProfileStockBasedOrderFilterExemptDispatchMethod $exemptDispatchMethod) {
                    return $exemptDispatchMethod->getDispatchMethod()->getId();
                }
            )->toArray()
        );
    }

    /**
     * @param PickProfile $pickProfile
     * @return OrderFilterConditionQueryComponent|null
     */
    protected function getOrderFilterConditionQueryComponentOfPickProfile(PickProfile $pickProfile)
    {
        $encodedQueryComponent = $pickProfile->getOrderFilterQueryConditions();
        if (!isset($encodedQueryComponent['type'])) {
            return null;
        }

        return $this->orderFilterConditionQueryComponentFactoryService->createWithArrayEncodedQueryComponent(
            $encodedQueryComponent
        );
    }
}
