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

class StockBasedFilterConfiguration
{
    /**
     * The mode identifier used for the 'don't filter by stock' order filter mode. Configuring the profile with this
     * mode effectively skips the stock based order filter.
     */
    const FILTER_MODE_OFF = 0;

    /**
     * The mode identifier used for the 'all released items have all required stock' order filter mode. Configuring the
     * profile with this mode only those orders are considerd, which satisfy the following condition: if a contained
     * item is already released and it is not yet shipped it must have all required stock
     * (stock value >= ordered (non-shipped) amount). The stock values of non-released items are not checked.
     */
    const FILTER_MODE_ALL_RELEASED_ITEMS_HAVE_ALL_REQUIRED_STOCK = 1;

    /**
     * The mode identifier used for the 'at least one item has all required stock' order filter mode. Configuring the
     * profile with this mode only those orders are considered, which satisfy the following condition: among the
     * contained and not yet shipped items is at least one item, which has all required stock
     * (stock value >= ordered (non-shipped) amount).
     */
    const FILTER_MODE_AT_LEAST_ONE_ITEM_HAS_SUFFICIENT_STOCK = 2;

    /**
     * The mode identifier used for the 'at least one item has stock' order filter mode. Configuring the profile with
     * this mode only those orders are considered, which satisfy the following condition: among the contained and not
     * yet shipped items is at least one item, which has stock (stock value > 0).
     */
    const FILTER_MODE_AT_LEAST_ONE_ITEM_HAS_SOME_STOCK = 3;

    /**
     * The mode identifier used for the 'all items have all required stock' order filter mode. Configuring the profile
     ** with this mode only those orders are considerd, which satisfy the following condition: all contained and not yet
     * shipped items (including non-released items!) have all required stock
     * (stock value >= ordered (non-shipped) amount).
     */
    const FILTER_MODE_ALL_ITEMS_HAVE_ALL_REQUIRED_STOCK = 4;

    /**
     * An array containing all valid stock based order filter modes. You might use this to validate a filter mode before
     * using it.
     */
    const VALID_FILTER_MODES = [
        self::FILTER_MODE_OFF,
        self::FILTER_MODE_ALL_RELEASED_ITEMS_HAVE_ALL_REQUIRED_STOCK,
        self::FILTER_MODE_AT_LEAST_ONE_ITEM_HAS_SUFFICIENT_STOCK,
        self::FILTER_MODE_AT_LEAST_ONE_ITEM_HAS_SOME_STOCK,
        self::FILTER_MODE_ALL_ITEMS_HAVE_ALL_REQUIRED_STOCK,
    ];

    /**
     * @var int
     */
    protected $filterMode;

    /**
     * @var int[]
     */
    protected $exemptDispatchMethodIds = [];

    /**
     * @param int $filterMode
     * @param int[] $exemptDispatchMethodIds (optional)
     */
    public function __construct($filterMode, array $exemptDispatchMethodIds = [])
    {
        $this->filterMode = $filterMode;
        $this->exemptDispatchMethodIds = $exemptDispatchMethodIds;
    }

    /**
     * @return int The configured filter mode.
     */
    public function getFilterMode()
    {
        return $this->filterMode;
    }

    /**
     * @return bool true, iff the configured filter mode is any other than 'off'.
     */
    public function isStockBasedFilterEnabled()
    {
        return $this->filterMode !== self::FILTER_MODE_OFF;
    }

    /**
     * @return bool true, iff the 'at least one item has some stock' filter mode is configured.
     */
    public function isModeAtLeastOneItemMustHaveSomeStock()
    {
        return $this->filterMode === self::FILTER_MODE_AT_LEAST_ONE_ITEM_HAS_SOME_STOCK;
    }

    /**
     * @return bool true, iff the 'all items have all required stock' filter mode is configured.
     */
    public function isModeAllItemsMustHaveAllRequiredStock()
    {
        return $this->filterMode === self::FILTER_MODE_ALL_ITEMS_HAVE_ALL_REQUIRED_STOCK;
    }

    /**
     * @return bool true, iff the 'all released items have all required stock' filter mode is configured.
     */
    public function isModeAllReleasedItemsMustHaveAllRequiredStock()
    {
        return $this->filterMode === self::FILTER_MODE_ALL_RELEASED_ITEMS_HAVE_ALL_REQUIRED_STOCK;
    }

    /**
     * @return bool true, iff a filter mode is configured, which requires at least one item of an order to fulfill its
     *     stock based condition.
     */
    public function isModeOfTypeAtLeastOneItemMustFulfillStockCondition()
    {
        return in_array(
            $this->filterMode,
            [
                self::FILTER_MODE_AT_LEAST_ONE_ITEM_HAS_SUFFICIENT_STOCK,
                self::FILTER_MODE_AT_LEAST_ONE_ITEM_HAS_SOME_STOCK,
            ]
        );
    }

    /**
     * @return bool true, iff a filter mode is configured, which requires all items of an order to filfull their stock
     *     based condition.
     */
    public function isModeOfTypeAllItemsMustFulfillStockCondition()
    {
        return in_array(
            $this->filterMode,
            [
                self::FILTER_MODE_ALL_RELEASED_ITEMS_HAVE_ALL_REQUIRED_STOCK,
                self::FILTER_MODE_ALL_ITEMS_HAVE_ALL_REQUIRED_STOCK,
            ]
        );
    }

    /**
     * @return int[] The IDs of all dispatch methods, whose respective orders are exempt from the stock based filter.
     */
    public function getExemptDispatchMethodIds()
    {
        return $this->exemptDispatchMethodIds;
    }
}
