<?php

namespace Lc\ShopBundle\Services\Order;


use Lc\ShopBundle\Context\OrderProductInterface;
use Lc\ShopBundle\Model\Product;
use Lc\ShopBundle\Model\ProductFamily;

trait OrderUtilsStockTrait
{
        public function deductAvailabilityProduct(\Lc\ShopBundle\Model\OrderShop $orderShop)
        {
                //TODO ne pas déduire des stocks les orderProduct marqué en relivraison

                foreach ($orderShop->getOrderProducts() as $orderProduct) {
                        switch ($orderProduct->getProduct()->getProductFamily()->getBehaviorCountStock()) {
                                case ProductFamily::BEHAVIOR_COUNT_STOCK_BY_MEASURE :

                                        //Disponibilité par unité de référence
                                        $oldAvailability = $orderProduct->getProduct()->getAvailableQuantityInherited();
                                        $newAvailability = $oldAvailability - ($orderProduct->getQuantityOrder() * ($orderProduct->getQuantityProduct() / $orderProduct->getUnit()->getCoefficient()));

                                        $productFamily = $orderProduct->getProduct()->getProductFamily();
                                        $productFamily->setAvailableQuantity($newAvailability);
                                        $productFamily->setUpdatedBy($orderShop->getUser());

                                        $this->em->persist($productFamily);

                                        break;
                                case ProductFamily::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY :

                                        $oldAvailability = $orderProduct->getProduct()->getAvailableQuantityInherited();
                                        $newAvailability = $oldAvailability - $orderProduct->getQuantityOrder();

                                        $productFamily = $orderProduct->getProduct()->getProductFamily();
                                        $productFamily->setAvailableQuantity($newAvailability);
                                        $productFamily->setUpdatedBy($orderShop->getUser());

                                        $this->em->persist($productFamily);

                                        break;
                                case ProductFamily::BEHAVIOR_COUNT_STOCK_BY_PRODUCT :
                                        $oldAvailability = $orderProduct->getProduct()->getAvailableQuantityInherited();
                                        $newAvailability = $oldAvailability - $orderProduct->getQuantityOrder();

                                        $product = $orderProduct->getProduct();
                                        $product->setAvailableQuantity($newAvailability);
                                        $product->setUpdatedBy($orderShop->getUser());

                                        $this->em->persist($product);

                                        break;
                        }

                        $this->em->flush();
                }
        }

        public function isProductAvailable(Product $product, $quantityOrder = 0, $checkCart = false, $orderShop = null)
        {
                if ($product->getStatus() != 1 || $product->getProductFamily()->getStatus() != 1) {
                        return false;
                }

                if (!$orderShop) {
                        $orderShop = $this->getCartCurrent();
                }
                $productFamily = $product->getProductFamily();
                $quantityAsked = $quantityOrder;

                if ($productFamily->getBehaviorCountStock() == ProductFamily::BEHAVIOR_COUNT_STOCK_BY_MEASURE) {
                        if (!$quantityOrder) {
                                $quantityAsked = $this->getQuantityOrderByProduct($orderShop, $product, true);
                        } else {
                                $quantityAsked = ($product->getQuantityInherited() / $product->getUnitInherited()->getCoefficient()) * $quantityOrder;
                        }

                        if ($checkCart) {
                                $quantityAsked += $this->getQuantityOrderByProduct($orderShop, $product, true);
                        }
                }

                if (($productFamily->getBehaviorCountStock() == ProductFamily::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY
                        || $productFamily->getBehaviorCountStock() == ProductFamily::BEHAVIOR_COUNT_STOCK_BY_PRODUCT)) {

                        if (!$quantityOrder) {
                                $quantityAsked = $this->getQuantityOrderByProduct($orderShop, $product);
                        }

                        if ($checkCart) {
                                $quantityAsked += $this->getQuantityOrderByProduct($orderShop, $product);
                        }
                }

                if ($product->getAvailableQuantityInherited() >= $quantityAsked
                        || $productFamily->getBehaviorCountStock() == ProductFamily::BEHAVIOR_COUNT_STOCK_UNLIMITED) {
                        return true;
                } else {
                        return false;
                }
        }

        public function isOneProductAvailableAddCart($products): bool
        {
                foreach ($products as $product) {
                        if ($this->isProductAvailable($product, 1, true)) {
                                return true;
                        }
                }

                return false;
        }

        public function isOrderProductAvailable(OrderProductInterface $orderProduct)
        {
                return $this->isProductAvailable($orderProduct->getProduct(), $orderProduct->getQuantityOrder());
        }

        public function isOrderProductAvailableAddCart(OrderProductInterface $orderProduct, $orderShop = null)
        {
                $product = $orderProduct->getProduct();
                return $this->isProductAvailable($product, $orderProduct->getQuantityOrder(), true, $orderShop);
        }

        public function getQuantityOrderByProduct($orderShop, $product, $byWeight = false)
        {
                $quantity = 0;
                $productFamily = $product->getProductFamily();
                $behaviorCountStock = $productFamily->getBehaviorCountStock();

                if ($orderShop) {
                        foreach ($orderShop->getOrderProducts() as $orderProduct) {
                                if ($orderProduct->getProduct()->getId() == $product->getId()
                                        || (($behaviorCountStock == ProductFamily::BEHAVIOR_COUNT_STOCK_BY_PRODUCT_FAMILY || $behaviorCountStock == ProductFamily::BEHAVIOR_COUNT_STOCK_BY_MEASURE)
                                                && $orderProduct->getProduct()->getProductFamily()->getId() == $productFamily->getId())) {

                                        if ($byWeight) {
                                                $quantity += $orderProduct->getQuantityOrder() * ($orderProduct->getQuantityProduct() / $orderProduct->getProduct()->getUnitInherited()->getCoefficient());
                                        } else {
                                                $quantity += $orderProduct->getQuantityOrder();
                                        }
                                }
                        }
                }

                return $quantity;
        }

        public function getProductQuantityMaxAddCart($product)
        {
                $orderShop = $this->getCartCurrent();
                $productFamily = $product->getProductFamily();

                $byWeight = false;
                if ($productFamily->getBehaviorCountStock() == ProductFamily::BEHAVIOR_COUNT_STOCK_BY_MEASURE) {
                        $byWeight = true;
                }

                return $product->getAvailableQuantityInherited() - $this->getQuantityOrderByProduct($orderShop, $product, $byWeight);
        }

        public function getProductQuantity($product)
        {

                $productFamily = $product->getProductFamily();

                if ($productFamily->getBehaviorCountStock() == ProductFamily::BEHAVIOR_COUNT_STOCK_BY_MEASURE) {
                        return $product->getQuantityInherited() / $product->getUnitInherited()->getCoefficient();
                } else {
                        return 1;
                }
        }
}