<?php

/* * ********************************************************************************** */
/*      This file is part of the Thelia package.                                     */
/*                                                                                   */
/*      Copyright (c) OpenStudio                                                     */
/*      email : dev@thelia.net                                                       */
/*      web : http://www.thelia.net                                                  */
/*                                                                                   */
/*      For the full copyright and license information, please view the LICENSE.txt  */
/*      file that was distributed with this source code.                             */
/* * ********************************************************************************** */
/* * ********************************************************************************** */

namespace ArtabanMarketplaceColissimo;

use ArtabanMarketplaceColissimo\Model\Config\ColissimoConfigValue;
use Propel\Runtime\Connection\ConnectionInterface;
use Thelia\Core\Translation\Translator;
use Thelia\Install\Database;
use Thelia\Model\Country;
use Thelia\Module\AbstractDeliveryModule;
use Thelia\Module\Exception\DeliveryException;
use Thelia\Model\CartItemQuery;
use ArtabanMarketplace\Model\AmpSellerProductQuery;
use Symfony\Component\HttpFoundation\Session\Session;
use Thelia\Model\Cart;

class ArtabanMarketplaceColissimo extends AbstractDeliveryModule {

    protected $request;
    protected $dispatcher;
    private static $prices = null;

    const JSON_PRICE_RESOURCE = "/Config/prices.json";
    const DOMAIN_NAME = 'artabanmarketplacecolissimo';

    public static function getPrices() {
        if (null === self::$prices) {
            self::$prices = json_decode(ArtabanMarketplaceColissimo::getConfigValue(ColissimoConfigValue::PRICES, null), true);
        }

        return self::$prices;
    }

    public function postActivation(ConnectionInterface $con = null) {
        self::setConfigValue(ColissimoConfigValue::ENABLED, 1);

        $database = new Database($con);
        $database->insertSql(null, array(__DIR__ . '/Config/thelia.sql'));
    }

    public function isValidDelivery(Country $country) {

        if (0 == self::getConfigValue(ColissimoConfigValue::ENABLED, 1)) {
            return false;
        }
        if (null !== $area = $this->getAreaForCountry($country)) {

            $areaId = $area->getId();

            $prices = self::getPrices();

            $cartId = $this->getRequest()->getSession()->get("thelia.cart_id");

            $arraySellerId = self::generateArraySellerIdFromCartId($cartId);

            $cartItems = CartItemQuery::create()->filterByCartId($cartId)->find();


            /* Check if Colissimo delivers the area */
            if (isset($prices[$areaId]) && isset($prices[$areaId]["slices"])) {
                // Yes ! Check if the cart weight is below slice limit
                $areaPrices = $prices[$areaId]["slices"];
                ksort($areaPrices);
                //var_dump($areaPrices); // ARTABANMOUCHARD

                /* Check cart weight is below the maximum weight */
                end($areaPrices);
                $maxWeight = key($areaPrices);



                foreach ($arraySellerId as $sellerId) {
                    $sellerProductsWeight = 0;
                    foreach ($cartItems as $cartItem) {
                        $product = $cartItem->getProduct();
                        $sellerProductExists = AmpSellerProductQuery::existsAmpSellerProduct($sellerId, $product->getId());
                        if ($sellerProductExists) {
                            $productQuantity = $cartItem->getQuantity();
                            $productWeight = $cartItem->getProductSaleElements()->getWeight();
                            $productsWeight = $productQuantity * $productWeight;
                            $sellerProductsWeight = $sellerProductsWeight + $productsWeight;
                        }
                    }
                    if ($sellerProductsWeight > $maxWeight) {
                        return false;
                    }
                }
            }
        }

        return true;
    }

    /**
     * @param $areaId
     *
     * @return mixed
     * @throws \Thelia\Exception\OrderException
     */
    public static function getPostageAmount($areaId) {
        $freeshipping = ArtabanMarketplaceColissimo::getConfigValue(ColissimoConfigValue::FREE_SHIPPING);
        $postageTotal = 0;
        if (!$freeshipping) {
            $prices = self::getPrices();


            $areaPrices = $prices[$areaId]["slices"];
            ksort($areaPrices);

            /* Check cart weight is below the maximum weight */
            end($areaPrices);

            $session = new Session();

            $cartId = $session->get("thelia.cart_id");

            $arraySellerId = self::generateArraySellerIdFromCartId($cartId);

            $cartItems = CartItemQuery::create()->filterByCartId($cartId)->find();
            $maxWeight = key($areaPrices);

            foreach ($arraySellerId as $sellerId) {
                $postage = 0;
                $sellerProductsWeight = 0;
                foreach ($cartItems as $cartItem) {
                    $product = $cartItem->getProduct();
                    $sellerProductExists = AmpSellerProductQuery::existsAmpSellerProduct($sellerId, $product->getId());
                    if ($sellerProductExists) {
                        $productQuantity = $cartItem->getQuantity();
                        $productWeight = $cartItem->getProductSaleElements()->getWeight();
                        $productsWeight = $productQuantity * $productWeight;
                        $sellerProductsWeight = $sellerProductsWeight + $productsWeight;
                    }
                }
                if ($sellerProductsWeight > $maxWeight) {
                    throw new DeliveryException(
                    Translator::getInstance()->trans(
                            "Colissimo delivery unavailable for this cart weight (%weight kg)", array("%weight" => $weight), self::DOMAIN_NAME
                    )
                    );
                }

                $postage = current($areaPrices);

                while (prev($areaPrices)) {
                    if ($sellerProductsWeight > key($areaPrices)) {
                        break;
                    }

                    $postage = current($areaPrices);
                }
                $postageTotal = $postageTotal + $postage;
            }
        }
        return $postageTotal;
    }
    
    /**
     * @param $areaId
     * @param $sellerId
     *
     * @return mixed
     * @throws \Thelia\Exception\OrderException
     */
    public static function getPostageAmountSeller($sellerId,$areaId) {
        $freeshipping = ArtabanMarketplaceColissimo::getConfigValue(ColissimoConfigValue::FREE_SHIPPING);
        $postageTotal = 0;
        if (!$freeshipping) {
            $prices = self::getPrices();


            $areaPrices = $prices[$areaId]["slices"];
            ksort($areaPrices);

            /* Check cart weight is below the maximum weight */
            end($areaPrices);

            $session = new Session();

            $cartId = $session->get("thelia.cart_id");

            $arraySellerId = self::generateArraySellerIdFromCartId($cartId);

            $cartItems = CartItemQuery::create()->filterByCartId($cartId)->find();
            $maxWeight = key($areaPrices);

                $postage = 0;
                $sellerProductsWeight = 0;
                foreach ($cartItems as $cartItem) {
                    $product = $cartItem->getProduct();
                    $sellerProductExists = AmpSellerProductQuery::existsAmpSellerProduct($sellerId, $product->getId());
                    if ($sellerProductExists) {
                        $productQuantity = $cartItem->getQuantity();
                        $productWeight = $cartItem->getProductSaleElements()->getWeight();
                        $productsWeight = $productQuantity * $productWeight;
                        $sellerProductsWeight = $sellerProductsWeight + $productsWeight;
                    }
                }
                if ($sellerProductsWeight > $maxWeight) {
                    throw new DeliveryException(
                    Translator::getInstance()->trans(
                            "Colissimo delivery unavailable for this cart weight (%weight kg)", array("%weight" => $weight), self::DOMAIN_NAME
                    )
                    );
                }

                $postage = current($areaPrices);

                while (prev($areaPrices)) {
                    if ($sellerProductsWeight > key($areaPrices)) {
                        break;
                    }

                    $postage = current($areaPrices);
                }
                $postageTotal = $postageTotal + $postage;
            
        }
        return $postageTotal;
    }

    /**
     * @param $areaId
     * @param $weight
     *
     * @return mixed
     * @throws \Thelia\Exception\OrderException
     */
    public static function getPostageAmountWeight($areaId, $weight) {
        $freeshipping = ArtabanMarketplaceColissimo::getConfigValue(ColissimoConfigValue::FREE_SHIPPING);
        $postageTotal = 0;
        if (!$freeshipping) {
            $prices = self::getPrices();


            $areaPrices = $prices[$areaId]["slices"];
            ksort($areaPrices);

            /* Check cart weight is below the maximum weight */
            end($areaPrices);

            $maxWeight = key($areaPrices);


            if ($weight > $maxWeight) {
                throw new DeliveryException(
                Translator::getInstance()->trans(
                        "Colissimo delivery unavailable for this cart weight (%weight kg)", array("%weight" => $weight), self::DOMAIN_NAME
                )
                );
            }

            $postage = current($areaPrices);

            while (prev($areaPrices)) {
                if ($weight > key($areaPrices)) {
                    break;
                }

                $postage = current($areaPrices);
            }
            $postageTotal = $postageTotal + $postage;
        }
        return $postageTotal;
    }

    /**
     *
     * calculate and return delivery price
     *
     * @param Country $country
     * @return mixed
     * @throws \Thelia\Exception\OrderException
     */
    public function getPostage(Country $country) {

        $postage = self::getPostageAmount(
                        $this->getAreaForCountry($country)->getId()
        );

        return $postage;
    }

    public function update($currentVersion, $newVersion, ConnectionInterface $con = null) {
        $uploadDir = __DIR__ . '/Config/prices.json';

        $database = new Database($con);

        $tableExists = $database->execute("SHOW TABLES LIKE 'colissimo_freeshipping'")->rowCount();

        if (ArtabanMarketplaceColissimo::getConfigValue(ColissimoConfigValue::FREE_SHIPPING, null) == null && $tableExists) {
            $result = $database->execute('SELECT active FROM colissimo_freeshipping WHERE id=1')->fetch()["active"];
            Colissimo::setConfigValue(ColissimoConfigValue::FREE_SHIPPING, $result);
            $database->execute("DROP TABLE `colissimo_freeshipping`");
        }

        if (is_readable($uploadDir) && ArtabanMarketplaceColissimo::getConfigValue(ColissimoConfigValue::PRICES, null) == null) {
            ArtabanMarketplaceColissimo::setConfigValue(ColissimoConfigValue::PRICES, file_get_contents($uploadDir));
        }
    }

    /**
     * @param OrderEvent $event
     * @return Array of unique id seller extracted form the items cart
     */
    public function generateArraySellerIdFromCartId($cart_id) {

        $cart_items = CartItemQuery::create()->filterByCartId($cart_id)->find();
        $sellers_id_all_array = array();
        foreach ($cart_items as $item) {
            $seller_product = AmpSellerProductQuery::create()->findOneByProductId($item->getProductId());
            $sellers_id_all_array[] = $seller_product->getAmpSellerId();
        }
        return array_unique($sellers_id_all_array);
    }

}
