<?php

/**
 * Description of OrderSeller
 *
 * @author LENGY Gilles
 */

namespace ArtabanMarketplace\Actions;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Thelia\Core\Event\Order\OrderEvent;
use Thelia\Core\Event\TheliaEvents;
Use Thelia\Model\CartItemQuery;
Use Thelia\Model\CartQuery;
use ArtabanMarketplace\Model\AmpSellerProductQuery;
use ArtabanMarketplace\Model\AmpSellerOrderQuery;
use ArtabanMarketplace\Model\AmpSellerOrder;
use Propel\Runtime\Propel;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Thelia\Core\Event\Order\OrderAddressEvent;
use Thelia\Core\Event\Order\OrderManualEvent;
use Thelia\Core\Event\Order\OrderPaymentEvent;
use Thelia\Core\Event\Payment\ManageStockOnCreationEvent;
use Thelia\Core\Event\Product\VirtualProductOrderHandleEvent;
use Thelia\Core\Security\SecurityContext;
use Thelia\Core\Security\User\UserInterface;
use Thelia\Exception\TheliaProcessException;
use Thelia\Mailer\MailerFactory;
use Thelia\Model\AddressQuery;
use Thelia\Model\Cart as CartModel;
use Thelia\Model\ConfigQuery;
use Thelia\Model\Currency as CurrencyModel;
use Thelia\Model\Lang as LangModel;
use Thelia\Model\Map\OrderTableMap;
use Thelia\Model\ModuleQuery;
use Thelia\Model\Module;
use Thelia\Model\Order as ModelOrder;
use Thelia\Model\Order as OrderModel;
use Thelia\Model\OrderQuery;
use Thelia\Model\OrderProductQuery;
use Thelia\Model\OrderAddress;
use Thelia\Model\OrderAddressQuery;
use Thelia\Model\OrderProduct;
use Thelia\Model\OrderProductAttributeCombination;
use Thelia\Model\OrderProductTax;
use Thelia\Model\OrderStatusQuery;
use Thelia\Model\ProductI18n;
use Thelia\Model\ProductSaleElements;
use Thelia\Model\ProductSaleElementsQuery;
use Thelia\Model\ProductQuery;
use Thelia\Model\TaxRuleI18n;
use Thelia\Module\PaymentModuleInterface;
use Thelia\Tools\I18n;
use Symfony\Component\HttpFoundation\Session\Session;
use ArtabanMarketplaceColissimo\ArtabanMarketplaceColissimo;
use ArtabanMarketplace\Model\AmpSellerQuery;
use ArtabanMarketplace\Model\AmpSellerOrderOrderProductTaxQuery;
use ArtabanMarketplace\Model\Map\AmpSellerOrderTableMap;
use ArtabanMarketplace\Model\AmpSellerOrderAddress;
use ArtabanMarketplace\Model\AmpSellerOrderStatusQuery;
use ArtabanMarketplace\Model\AmpSellerProduct;
use ArtabanMarketplace\Model\AmpSellerOrderOrderProductTax;
use ArtabanMarketplace\Model\AmpSellerOrderOrderAttributeCombination;
use ArtabanMarketplace\Model\AmpSellerOrderProduct;
use ArtabanMarketplace\Model\AmpSellerOrder as SellerNotificationAmpSellerOrder;

class OrderSeller implements EventSubscriberInterface {

    /** @var RequestStack $request */
    protected $requestStack = null;
    protected $mailer;

    public function __construct(RequestStack $requestStack, MailerFactory $mailer) {
        $this->requestStack = $requestStack;
        $this->mailer = $mailer;
    }

    public function generateOrderSeller(OrderEvent $event) {

        $session = $this->requestStack->getCurrentRequest()->getSession();

        $con = Propel::getConnection(
                        OrderTableMap::DATABASE_NAME
        );

        $sellersIdArray = $this::generateArraySellerId($event);
        foreach ($sellersIdArray as $sellerId) {
            $this->createSellerOrder($event, $sellerId);
        }

        $orderGeneral = $event->getOrder();
        $sellerOrderQuery = new AmpSellerOrderQuery();
        $sellerOrders = $sellerOrderQuery->findByOrderId($orderGeneral->getId());
        $orderGeneralPostage = 0;
        foreach ($sellerOrders as $sellerOrder) {
            $sellerOrderQueryOrders = new AmpSellerOrderQuery();
            $sellerOrderObject = $sellerOrderQueryOrders->findOneById($sellerOrder->getId());
            $orderGeneralPostage += $sellerOrderObject->getPostage();
            $this->sendSellerNotificationEmail($sellerOrderObject);
        }
        $orderGeneral->setPostage($orderGeneralPostage);
        $orderGeneral->save();
        $con->commit();
    }

    protected function createSellerOrder(OrderEvent $event, int $sellerId) {

        $order = $event->getOrder();
        $orderSeller = new AmpSellerOrder();
        // Infos Order
        $orderSeller->setOrderId($order->getId());
        $orderSeller->setAmpSellerId($sellerId);
        $orderSeller->setCustomerId($order->getCustomerId());
        // Order products
        $cartId = $order->getCartID();
        $cartItems = CartItemQuery::create()->filterByCartId($cartId)->find();
        $orderProductsId = "";
        foreach ($cartItems as $cartItem) {
            $product = $cartItem->getProduct();
            $sellerProductExists = AmpSellerProductQuery::existsAmpSellerProduct($sellerId, $product->getId());
            if ($sellerProductExists) {
                $pse = $cartItem->getProductSaleElements();
                $pseId = $pse->getId();
                $orderProduct = OrderProductQuery::create()->filterByOrderId($order->getId())->findOneByProductSaleElementsId($pseId);
                $orderProductsId = $orderProductsId . "," . $orderProduct->getId();
            }
        }
        $orderProductsId = substr($orderProductsId, 1);
        $orderSeller->setOrderProductId($orderProductsId);
        // Infos Seller Order
        $orderSellerSeller = AmpSellerOrderQuery::create()->filterByAmpSellerId($sellerId)->orderByAmpSellerOrderCounter("DESC")->findOne();
        if ($orderSellerSeller) {
            $orderAmpSellerOrderCounter = $orderSellerSeller->getAmpSellerOrderCounter() + 1;
        } else {
            $orderAmpSellerOrderCounter = 1;
        }
        $orderSeller->setAmpSellerOrderCounter($orderAmpSellerOrderCounter);
        $orderSellerSellerRef = "000" . $sellerId;
        $orderSellerSellerRef = substr($orderSellerSellerRef, -3);
        $orderSellerOrderRef = "00000" . $orderAmpSellerOrderCounter;
        $orderSellerOrderRef = substr($orderSellerOrderRef, -5);
        $orderSellerRef = "ORD$orderSellerSellerRef-$orderSellerOrderRef";
        $orderSeller->setSellerOrderRef($orderSellerRef);
        $orderSeller->setStatusId(1);
        // Postage Seller Order
        $invoiceAddress = AddressQuery::create()->findPk($this->requestStack->getCurrentRequest()->getSession()->get("thelia.order")->getChoosenDeliveryAddress());
        $country = $invoiceAddress->getCountry();
        $artabanMarketplaceColissimo = new ArtabanMarketplaceColissimo;
        $areaId = $artabanMarketplaceColissimo->getAreaForCountry($country)->getId();
        $postageSellerOrder = $artabanMarketplaceColissimo->getPostageAmountSeller($sellerId, $areaId);
        $orderSeller->setPostage($postageSellerOrder);
        //SAVE
        $orderSeller->save();
    }

    public function assignOrderPostage(OrderEvent $event) {
        $session = $this->requestStack->getCurrentRequest()->getSession();

        $order = $event->getOrder();
        $invoiceAddress = AddressQuery::create()->findPk($this->requestStack->getCurrentRequest()->getSession()->get("thelia.order")->getChoosenDeliveryAddress());
        $country = $invoiceAddress->getCountry();
        $artabanMarketplaceColissimo = new ArtabanMarketplaceColissimo;
        $areaId = $artabanMarketplaceColissimo->getAreaForCountry($country)->getId();
        $postageTotal = 0;
        $cartId = $session->get("thelia.cart_id");
        $arraySellerId = $artabanMarketplaceColissimo->generateArraySellerIdFromCartId($cartId);
        foreach ($arraySellerId as $sellerId) {
            $postageSeller = $artabanMarketplaceColissimo->getPostageAmountSeller($sellerId, $areaId);
            $postageTotal = $postageTotal + $postageSeller;
        }
        $order->setPostage($postageTotal);
        $event->setOrder($order);
    }

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

        $cart_id = $event->getOrder()->getCartId();
        $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);
    }

    public function existsAmpSellerProduct($sellerId, $productId) {
        $objectAmpSellerProductFromSeller = AmpSellerProduct::findByAmpSellerId($sellerId);
        $objectAmpSellerProductFromProduct = AmpSellerProduct::findByfindByProductId($productId);



        $objectAmpSellerProductFromSellerArray = array();
        $objectAmpSellerProductFromSellerArray[] = $objectAmpSellerProductFromSeller;

        $objectAmpSellerProductFromProductArray = array();
        $objectAmpSellerProductFromProductArray[] = $objectAmpSellerProductFromProduct;

        $out = array_intersect($objectAmpSellerProductFromProductArray, $objectAmpSellerProductFromSellerArray);


        return null; //$objectAmpSellerProductFromSellerIdId === $objectAmpSellerProductFromProductIdId;
    }

    protected function getSession() {
        $session = $this->requestStack->getCurrentRequest()->getSession();
//        var_dump($session);
//        die();
        return $session;
    }

    /**
     * @param OrderEvent $event
     *
     * @throws \Exception if the message cannot be loaded.
     */
    public function sendSellerNotificationEmail(SellerNotificationAmpSellerOrder $sellerOrder) {

// Sending notification to sellers
        $ampSellerQuery = new AmpSellerQuery();
        $ampSeller = $ampSellerQuery->findOneById($sellerOrder->getAmpSellerId());

        $this->mailer->sendEmailMessage(
                'seller_order_notification', [ConfigQuery::getStoreEmail() => ConfigQuery::getStoreName()], [$ampSeller->getEmail() => $ampSeller->getTitle()], [
            'order_id' => $sellerOrder->getId(),
            'order_ref' => $sellerOrder->getSellerOrderRef()
                ]
        );
    }

    public static function getSubscribedEvents() {
        return array(
            //0 pour ne pas remplacer default action
            TheliaEvents::ORDER_SET_POSTAGE => array("assignOrderPostage", 0),
            //148 pour execution avant default action
            TheliaEvents::ORDER_BEFORE_PAYMENT => array("generateOrderSeller", 148),
        );
    }

}
