<?php


namespace Magetop\Advancepreview\Controller\Checkout;

use Magento\Customer\Model\Customer;
use Magento\Customer\Model\CustomerFactory;
use Magento\Framework\App\Action;

class BuyWithout extends Action\Action
{
    const TAKE_ADMIN_EMAIL = 'takecare/setting/admin_email';
    const TAKE_APPROVE_EMAIL = 'takecare/setting/approve_email';
    protected $jsonFactory;
    protected $httpContext;
    protected $storeManager;
    protected $customerSession;
    protected $customerFactory;
    protected $addressFactory;
    protected $orderHelper;
    protected $takeHelper;
    protected $emailHelper;
    protected $cart;
    /**
     * @var \Magento\Catalog\Model\ProductFactory
     */
    protected $productFactory;
    /**
     * @var \Magento\Catalog\Model\ResourceModel\ProductFactory
     */
    protected $resProductFactory;
    /**
     * @var \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory
     */
    protected $colProductFactory;
    /**
     * @var \Magetop\Advancepreview\Model\ResourceModel\PreviewDiscount\CollectionFactory
     */
    protected $colPreviewDiscountFactory;
    /**
     * @var \Magetop\Advancepreview\Model\ResourceModel\PreviewAdditional\CollectionFactory
     */
    protected $colPreviewAdditionalFactory;
      /**
     * @var \Magetop\Advancepreview\Model\PreviewOrderItemsFactory
     */
    protected $previewOrderItemsFactory;
    /**
     * @var \Magetop\Advancepreview\Model\ResourceModel\PreviewOrderItemsFactory
     */
    protected $resPreviewOrderItemsFactory;
    public function __construct(
        Action\Context $context,
        \Magento\Framework\Controller\Result\JsonFactory $jsonFactory,
        \Magento\Framework\App\Http\Context $httpContext,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Customer\Model\Session $customerSession,
        \Magento\Customer\Model\CustomerFactory $customerFactory,
        \Magento\Customer\Model\AddressFactory $addressFactory,
        \Magento\Checkout\Model\Cart $cart,
        \Magetop\Advancepreview\Helper\OrderHelper $orderHelper,
        \Magetop\Advancepreview\Helper\Data $takeHelper,
        \Magetop\Advancepreview\Helper\Email $emailHelper,
        \Magento\Catalog\Model\ProductFactory $productFactory,
        \Magento\Catalog\Model\ResourceModel\ProductFactory $resProductFactory,
        \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $colProductFactory,
        \Magetop\Advancepreview\Model\ResourceModel\PreviewDiscount\CollectionFactory $colPreviewDiscountFactory,
        \Magetop\Advancepreview\Model\ResourceModel\PreviewAdditional\CollectionFactory $colPreviewAdditionalFactory,
        \Magetop\Advancepreview\Model\PreviewOrderItemsFactory $previewOrderItemsFactory,
        \Magetop\Advancepreview\Model\ResourceModel\PreviewOrderItemsFactory $resPreviewOrderItemsFactory
    )
    {
        parent::__construct($context);
        $this->jsonFactory = $jsonFactory;
        $this->httpContext = $httpContext;
        $this->customerSession = $customerSession;
        $this->storeManager = $storeManager;
        $this->customerFactory = $customerFactory;
        $this->addressFactory = $addressFactory;
        $this->orderHelper = $orderHelper;
        $this->takeHelper = $takeHelper;
        $this->emailHelper = $emailHelper;
        $this->cart = $cart;
        $this->productFactory = $productFactory;
        $this->resProductFactory = $resProductFactory;
        $this->colProductFactory = $colProductFactory;
        $this->colPreviewDiscountFactory = $colPreviewDiscountFactory;
        $this->colPreviewAdditionalFactory = $colPreviewAdditionalFactory;
        $this->previewOrderItemsFactory = $previewOrderItemsFactory;
        $this->resPreviewOrderItemsFactory = $resPreviewOrderItemsFactory;
    }

    public function execute()
    {
        $response = [
            'status'=>'error',
            'message'=>'Can not place order',
        ];

        $customerData = $this->getCustomerData();
        $items = $this->getAllItemInCart();
        $customItems = [];
        $requestOptions = [];
        foreach ($items as $item) {
            /** @var \Magento\Quote\Model\Quote\Item $item*/
            $productId = $item->getProduct()->getId();
            $requestOption = $this->getItemInforestion($item);
            $tierPrice = $this->getTierPriceByProductId($productId);
            $tierQtyPrice = $this->getTierPriceItemByQty($tierPrice, $item->getQty());
            $ourPrice = $this->getCustomTierOurPrice($tierQtyPrice, $productId);
            $ourPriceRow = $ourPrice * $item->getQty();
            $customDiscounts = $this->getPreviewDiscounts($productId);
            $designType = isset($requestOption['txt_custom_preview_design_type']) ? $requestOption['txt_custom_preview_design_type'] : 0;
            $i = 0;

            foreach ($customDiscounts as $customDiscount) {
                if($i == 0) { $i++; continue; }
                $priceDiscountItem = $customDiscount->getData('discount_price');
                if($designType == 1 && $i == 1) {
                    $paramAdditionalOptions = isset($requestOption['preview_additional_options']) ? $requestOption['preview_additional_options'] : [];
                    $priceDiscountItem += $this->getAdditionalOptionPrice($paramAdditionalOptions, $productId);
                }
                $priceAfterDiscount = $this->getAddDiscountAdditionAllPrice($priceDiscountItem, $productId);
                $ourPriceRow += $priceAfterDiscount;
                $i++;
            }
            $itemPrice = $ourPriceRow / $item->getQty();
            $requestOptions[] = $requestOption;
            $customItems[] = [
                'product_id'=>$productId,
                'item_params'=>$requestOption,
                'price'=>$itemPrice
            ];
        }
        $tempOrder=[
            'currency_id'  => 'EUR',
            'email'        => $customerData['email'], //buyer email id
            'shipping_address' =>$customerData['shipping_address'],
            'billing_address' =>$customerData['billing_address'],
            'items'=>$customItems
        ];
        $orderReponse = $this->orderHelper->createMageOrder($tempOrder);
        if($orderReponse['status'] == 'success') {
//           $this->messageManager->addSuccessMessage(__('Order placed successfully'));
            $order = isset($orderReponse['order']) ? $orderReponse['order'] : null;
//            $this->savePreviewOrderItems($order,$requestOptions);
            $this->customerSession->setPlacePreviewOrderSuccess(1);
             $this->cart->truncate();
             $this->cart->saveQuote();
        }
        return $this->jsonFactory->create()->setData($orderReponse);
    }
    protected function savePreviewOrderItems($order, $params) {
        if($order != null) {
            $items = $order->getAllItems();
            $date = Date('Y-m-d H:i:s');
            if(count($items))
            {
                $i = 0;
                foreach ($items as $item)
                {
                    $status = 'new';
                    $previewData = [
                        'order_id'=>$order->getId(),
                        'item_id'=>$item->getId(),
                        'product_id'=>$item->getProductId(),
                        'status'=>$status,
                        'info_request'=>'',
                        'created_at'=>$date,
                        'updated_at'=>$date,
                    ];
                    if(isset($params[$i])) {
                        $param = $params[$i];
                        $txtProductId = isset($param['product']) ? $param['product'] : 0;
                        if($txtProductId == $item->getProductId()) {
                            $previewData['info_request'] = json_encode($param);
                        }
                    }
                    $i++;
                    $this->savePreviewOrderItem($previewData);
                }
            }
        }

    }
    protected function savePreviewOrderItem($previewData = []) {
        $model = $this->previewOrderItemsFactory->create();
        $model->setData($previewData);
        $id = 0;
        try {
            $this->resPreviewOrderItemsFactory->create()->save($model);
            $id =  $model->getId();
        }
        catch (\Exception $exception) {

        }
        return $id;

    }

    public function getAllItemInCart() {
        $items = null;
        if($this->cart->getItems()) {
            $items = $this->cart->getItems();
        }
        return $items;
    }
    protected function getCustomerData() {
        $customerData = array();
        $isLoggedIn = $this->httpContext->getValue(\Magento\Customer\Model\Context::CONTEXT_AUTH);

        if($isLoggedIn) {
            $customerId = $this->customerSession->getCustomer()->getId();
            $customer = $this->customerFactory->create()->load($customerId);
            // shipping
            $shippingAddressId = $customer->getDefaultShipping();
             $shippingAddress = $this->addressFactory->create()->load($shippingAddressId);
             // billing
            $billingAddressId = $customer->getDefaultBilling();
            $billingAddress = $this->addressFactory->create()->load($billingAddressId);
             if($shippingAddress) {
                 $customerData = [
                   'email'=>$customer->getEmail(),
                     'shipping_address'=>[
                         'firstname'    => $shippingAddress->getFirstname(), //address Details
                         'lastname'     => $shippingAddress->getLastname(),
                         'street' => $shippingAddress->getStreet(),
                         'city' => $shippingAddress->getCity(),
                         'country_id' => $shippingAddress->getCountryId(),
                         'region' => $shippingAddress->getRegion(),
                         'postcode' => $shippingAddress->getPostcode(),
                         'telephone' => $shippingAddress->getTelephone(),
                         'fax' => $shippingAddress->getFax(),
                         'save_in_address_book' => 0
                     ],
                     'billing_address'=> [
                         'firstname'    => $billingAddress->getFirstname(), //address Details
                         'lastname'     => $billingAddress->getLastname(),
                         'street' => $billingAddress->getStreet(),
                         'city' => $billingAddress->getCity(),
                         'country_id' => $billingAddress->getCountryId(),
                         'region' => $billingAddress->getRegion(),
                         'postcode' => $billingAddress->getPostcode(),
                         'telephone' => $billingAddress->getTelephone(),
                         'fax' => $billingAddress->getFax(),
                     ]
                 ];
             }
        }
        return $customerData;
    }
    /**
     * @param int $productId
     * @return \Magetop\Advancepreview\Model\ResourceModel\PreviewDiscount\Collection
     */
    public function getPreviewDiscounts($productId = 0) {
        $collection = $this->colPreviewDiscountFactory->create()
            ->addFieldToSelect(array('*'))
            ->addFieldToFilter('product_id',$productId);
        return $collection;
    }

    /**
     * @param \Magento\Quote\Model\Quote\Item $item
     * @return array
     */
    public function getItemInforestion($item) {
        $customOptionsRequest = [];
        if($item) {
            $customOptions = $item->getProduct()->getTypeInstance(true)->getOrderOptions($item->getProduct());
            if(isset($customOptions['info_buyRequest'])) {
                $customOptionsRequest = $customOptions['info_buyRequest'];
            }
        }
        $writer = new \Zend\Log\Writer\Stream(BP . '/var/log/test_option.log');
        $logger = new \Zend\Log\Logger();
        $logger->addWriter($writer);
        $logger->info(json_encode($customOptionsRequest));
        return $customOptionsRequest;
    }

    /**
     * @param int $price
     * @param int $productId
     * @return float|int
     */
    public function getCustomTierOurPrice($price = 0, $productId = 0) {

        $customerGroup = $this->getCustomerGroup();
        if($customerGroup > 1) {
            $product = $this->getProductById($productId);
            if($product) {
                $discount = $product->getData('pcto_discount');
                if($discount > 0) {
                    $price -= ($price * $discount) / 100;
                }
            }
        }
        return $price;

    }

    /**
     * @param $price
     * @param $productId
     * @return float|int
     */
    public function getAddDiscountAdditionAllPrice($price, $productId) {
        $product = $this->getProductById($productId);
        $priceDiscount = $price;
        $customerGroup = $this->getCustomerGroup();
        if($customerGroup > 1) {
            if($product) {
                $discount = $product->getData('pcto_discount');
                if($discount > 0) {
                    $priceDiscount -= ($price * $discount) / 100;
                }
            }
        }

        return $priceDiscount;
    }

    /**
     * @param array $parmaOptions
     * @param int $productId
     * @return int
     */
    public function getAdditionalOptionPrice($parmaOptions = [], $productId = 0) {
        $collection = $this->getPreviewAdditionalOptions($productId);
        $price = 0;
        if($collection && $collection->getSize() > 0) {
            foreach ($collection as $item) {
                if(in_array($item->getId(), $parmaOptions)) {
                    $price += $item->getData('price');
                }
            }
        }

        return  $price;
    }

    /**
     * @param int $productId
     * @return \Magento\Catalog\Model\Product
     */
    public function getProductById($productId = 0) {
        $product = $this->productFactory->create();
        $this->resProductFactory->create()->load($product, $productId);
        return $product;
    }

    /**
     * @param int $productId
     * @return \Magetop\Advancepreview\Model\ResourceModel\PreviewAdditional\Collection
     */
    public function getPreviewAdditionalOptions($productId = 0) {
        return $this->colPreviewAdditionalFactory->create()
            ->addFieldToSelect(array('*'))
            ->addFieldToFilter('product_id',$productId);
    }

    /**
     * @return int
     */
    public function getCustomerGroup() {
        $group = 0;
        if($this->checkIsLogin()) {
            $customerId =  $this->customerSession->getCustomerId();
            $customer = $this->customerFactory->create()->load($customerId);
            $group = $customer->getGroupId();

        }
        return $group;
    }
    public function getTierPriceItemByQty($tierPriecs = [], $qty = 0) {
        $price = 0;
        $lastIndex = count($tierPriecs) ? count($tierPriecs) - 1 : 0;
        $lastItem = isset($tierPriecs[$lastIndex]) ? $tierPriecs[$lastIndex] : [];
        if($lastIndex > 0 && isset($lastItem['price_qty']) && $qty >= $lastItem['price_qty']) {
            $price = $lastItem['price'];
        }
        else {
            for($i = 0; $i < count($tierPriecs); $i++) {
                if($i == 0 && $qty < $tierPriecs[0]['price_qty']) {
                    $price = $tierPriecs[0]['price'];
                    break;
                }
                if($i + 1 < count($tierPriecs)) {
                    $currentTeir = $tierPriecs[$i];
                    $nextTier = $tierPriecs[$i + 1];
                    if($qty >= $currentTeir['price_qty'] && $qty < $nextTier['price_qty']) {
                        $price = $currentTeir['price'];
                        break;
                    }
                }
            }
        }

        return $price;
    }
    public function getTierPriceByProductId($productId) {
        $tierPrices = [];
        $_product = $this->getProductById($productId);
        if($_product != null) {
            $tierPrices = $_product->getTierPrice();
        }
        return $tierPrices;
    }


    /**
     * @return bool
     */
    protected function checkIsLogin() {
        $isLogin = false;
        if($this->httpContext->getValue(\Magento\Customer\Model\Context::CONTEXT_AUTH)) {
            $isLogin = true;
        }
        return $isLogin;
    }
}
