<?php
/******************************************************************************
 *   ______                                                                   *
 *  /       \                                                                 *
 * /$$$$$$  | ________  __    __   ______    ______                           *
 * $$ |__$$ |/        |/  |  /  | /      \  /      \                          *
 * $$    $$ |$$$$$$$$/ $$ |  $$ |/$$$$$$  |/$$$$$$  |                         *
 * $$$$$$$$ |  /  $$/  $$ |  $$ |$$ |  $$/ $$    $$ |                         *
 * $$ |  $$ | /$$$$/__ $$ \__$$ |$$ |      $$$$$$$$/                          *
 * $$ |  $$ |/$$      |$$    $$/ $$ |      $$       |                         *
 * $$/   $$/ $$$$$$$$/  $$$$$$/  $$/        $$$$$$$/                          *
 *                                                                            *
 * @PROJECT    : 3D Preview Extension [Magetop.com]                           *
 * @AUTHOR     : Azure - Developer                                            *
 * @COPYRIGHT  : © 2019  Magetop.com                                          *
 * @LINK       : https://Magetop.com                                          *
 * @CREATED    :  10/01/2022                                                  *
 ******************************************************************************/

namespace Magetop\Advancepreview\Controller\Checkout;

use Magento\Framework\App\Action;

class CreateOrderFromWishlist extends Action\Action
{
    const TAKE_ADMIN_EMAIL = 'takecare/setting/admin_email';
    const TAKE_APPROVE_EMAIL = 'takecare/setting/approve_email';
    protected $jsonFactory;
    protected $wishlistFactory;
    protected $wishlistItemFactory;
    protected $stockItemRepository;
    protected $httpContext;
    protected $storeManager;
    protected $customerSession;
    protected $customerFactory;
    protected $addressFactory;
    protected $orderHelper;
    protected $takeHelper;
    protected $emailHelper;
    protected $cart;
    protected $dailyShippingFactory;
    /**
     * @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;
    protected $wishlistProviderInterface;
    /**
     * @var \Magetop\Advancepreview\Model\PreviewOrderItemsFactory
    */
    protected $previewOrderItemsFactory;
    /**
     * @var \Magetop\Advancepreview\Model\ResourceModel\PreviewOrderItemsFactory
     */
    protected $resPreviewOrderItemsFactory;
    protected $registry;
    public function __construct(
        Action\Context $context,
        \Magento\Framework\Controller\Result\JsonFactory $jsonFactory,
        \Magento\Framework\App\Http\Context $httpContext,
        \Magento\Framework\Registry $registry,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Wishlist\Model\WishlistFactory $wishlistFactory,
        \Magento\Wishlist\Model\ItemFactory $wishlistItemFactory,
        \Magento\CatalogInventory\Model\Stock\StockItemRepository $stockItemRepository,
        \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,
        \Magento\Wishlist\Controller\WishlistProviderInterface $wishlistProviderInterface,
        \Magetop\Advancepreview\Model\ResourceModel\PreviewDailyShipping\CollectionFactory $dailyShippingFactory,
        \Magetop\Advancepreview\Model\PreviewOrderItemsFactory $previewOrderItemsFactory,
        \Magetop\Advancepreview\Model\ResourceModel\PreviewOrderItemsFactory $resPreviewOrderItemsFactory
    )
    {
        parent::__construct($context);
        $this->jsonFactory = $jsonFactory;
        $this->registry = $registry;
        $this->wishlistFactory = $wishlistFactory;
        $this->wishlistItemFactory = $wishlistItemFactory;
        $this->stockItemRepository = $stockItemRepository;
        $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->wishlistProviderInterface = $wishlistProviderInterface;
        $this->dailyShippingFactory = $dailyShippingFactory;
        $this->colPreviewAdditionalFactory = $colPreviewAdditionalFactory;
        $this->previewOrderItemsFactory = $previewOrderItemsFactory;
        $this->resPreviewOrderItemsFactory = $resPreviewOrderItemsFactory;
    }

    public function execute()
    {

        $response = [
            'status'=>'error',
            'message_title'=>__('Error'),
            'message'=>__('It is not possible to create order, The offer is no longer up to date'),
        ];
        $wishlistId = $this->getRequest()->getParam('item_id',0);
        $item = $this->getWishlistById($wishlistId);
        $productId = $this->getRequest()->getParam('product_id',0);
        $infoRequest = $this->getRequest()->getParam('info_request',[]);
        $priceTests = [];
        $requestOptions = [];
        if($item && $item->getId() && count($infoRequest)) {
            $requestOption = $infoRequest;
            $requestOptions[] = $requestOption;
            $qty = (int)$item->getData('qty');
            $tierPrice = $this->getTierPriceByProductId($productId);
            $_product = $this->getProductById($productId);
            $productName = $_product ? $_product->getData('name') : '';
            $tierQtyPrice = $this->getTierPriceItemByQty($tierPrice, $qty);
            $ourPrice = $this->getCustomTierOurPrice($tierQtyPrice, $productId);
            $ourPriceRow = $ourPrice * $qty;
            $customDiscounts = $this->getPreviewDiscounts($productId);

            $isVailidatePrice =  $this->validateUpdatePrice($productId,$customDiscounts, $requestOption);
            $isVerifyTierPrice = $this->checkTierPriceChange($requestOption, $tierQtyPrice, $qty);
            if(!$isVailidatePrice || !$isVerifyTierPrice) {
                $response['message'] = __('It is not possible to create an order. The offer is no longer up to date');
                return $this->jsonFactory->create()->setData($response);
            }else{
                $response['status'] = 'success';
            }            
            if($response['status'] == 'success') {
                $wishlist = $this->wishlistProviderInterface->getWishlist($item->getWishlistId());
                $response['total_wishlist'] = $wishlist->getItemsCount();
                $response['message_title'] = __('Success');
            }
            else {
                $response['message'] = __('It is not possible to create order, the offer is no longer up to date');
            }
        }
        return $this->jsonFactory->create()->setData($response);

    }
    
    protected function getWishlistById($wishlistId) {
        return $this->wishlistItemFactory->create()->load($wishlistId);
    }
    public function getStockItem($productId)
    {
        return $this->stockItemRepository->get($productId);
    }    
    protected function validateUpdatePrice($productId,$customDiscounts,$requestOption) {
        $itcPriceDiscounts = isset($requestOption['ict_discounts_price']) ? $requestOption['ict_discounts_price'] : [];
        $itcPriceAdditional = isset($requestOption['ict_addition_price']) ? $requestOption['ict_addition_price'] : [];
        $itcPriceDailies = isset($requestOption['ict_daily_price']) ? $requestOption['ict_daily_price'] : [];
        $itcProductPrice = isset($requestOption['ict_product_price']) ? $requestOption['ict_product_price'] : 0;
        $itcDiscount = isset($requestOption['txt_pcto_discount']) ? $requestOption['txt_pcto_discount'] : 0;
        $isPriceDiscoutVaild = $this->validatePriceDiscount($customDiscounts, $itcPriceDiscounts);
        $isPriceAdditonalVaild = $this->validatePriceAddiontional($productId, $itcPriceAdditional);
        $isPriceDailiVaild = $this->validatePriceDailies($productId, $itcPriceDailies);
        $isVaild = true;
        $_product = $this->getProductById($productId);
        if($_product && $itcProductPrice == $_product->getFinalPrice() && $itcDiscount == $_product->getData('pcto_discount')) {
            // $isVaild = true;
        }
        else {
            $isVaild = false;
        }
        if(!$isPriceDiscoutVaild  || !$isPriceAdditonalVaild || !$isPriceDailiVaild) {
            $isVaild = false;
        }
        return $isVaild;
    }
    protected function checkTierPriceChange($requestOption, $newTierPrice, $qty) {
        //
        $itemTiers = isset($requestOption['txt_preview_tiers_price']) ? $requestOption['txt_preview_tiers_price'] : '';
        if($itemTiers != '') {
            $itemTiers = (array)json_decode($itemTiers);
        }
        else {
            $itemTiers = [];
        }
        $isOK = false;
        if(count($itemTiers)) {          
            $requestTierPrice = $this->getTierPriceItemByQtyPro($itemTiers, $qty);
            if($requestTierPrice == $newTierPrice) {
                $isOK = true;
            }
        }
        return $isOK;
    }
    protected function validatePriceDiscount($discounts, $paramsDiscounts) {
        $isOK = true;
        if($discounts) {
            foreach ($discounts as $key => $value) {
               if(!array_key_exists($value->getId(),$paramsDiscounts)) {
                $isOK = false;
                break;
               }
               $txtPrice = $paramsDiscounts[$value->getId()];
               if($value->getData('discount_price') != $txtPrice) {
                    $isOK = false;
                    break;
               }
            }
        }
        return $isOK;
    }
    protected function validatePriceAddiontional($productId, $params) {
        $isOK = true;
        $collection = $this->getPreviewAdditionalOptions($productId);
        if($collection) {
            foreach ($collection as $key => $value) {
               if(!array_key_exists($value->getId(),$params)) {
                $isOK = false;
                break;
               }
               $txtPrice = $params[$value->getId()];
               if($value->getData('price') != $txtPrice) {
                    $isOK = false;
                    break;
               }
            }
        }
        return $isOK;
    }
    protected function validatePriceDailies($productId, $params) {
        $isOK = true;
        $collection = $this->getDailyShippingByProductId($productId);
        if($collection) {
            foreach ($collection as $key => $value) {
               if(!array_key_exists($value->getId(),$params)) {
                $isOK = false;
                break;
               }
               $txtPrice = $params[$value->getId()];
               if($value->getData('amount') != $txtPrice) {
                    $isOK = false;
                    break;
               }
            }
        }
        return $isOK;
    }
    /**
     * @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 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) {
        if(!$this->registry->registry('preview_request_offer_product')) {
            $product = $this->productFactory->create();
            $this->resProductFactory->create()->load($product, $productId);
            $this->registry->register('preview_request_offer_product',$product);
        }
        else {
            $product = $this->registry->registry('preview_request_offer_product');
        }
        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 getTierPriceItemByQtyPro($tierPriecs = [], $qty = 0) {
        $price = 0;
        $lastIndex = count($tierPriecs) ? count($tierPriecs) - 1 : 0;
        $lastItem = isset($tierPriecs[$lastIndex]) ? (array)$tierPriecs[$lastIndex] : [];
        if($lastIndex > 0 && isset($lastItem['price_qty']) && $qty >= $lastItem['price_qty']) {
            $price = $lastItem['price'];
        }
        else {
            for($i = 0; $i < count($tierPriecs); $i++) {
                $firesItem = (array)$tierPriecs[0];
                if($i == 0 && $qty < $firesItem['price_qty']) {
                    $tierPriceItem = (array)$tierPriecs[0];
                    $price = $tierPriceItem['price'];
                    break;
                }
                if($i + 1 < count($tierPriecs)) {
                    $currentTeir = (array)$tierPriecs[$i];
                    $nextTier = (array)$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;
    }
    protected function getCurrentCurrency() {
        return $this->storeManager->getStore()->getCurrentCurrency()->getCode();
    }
    public function getDailyShippingById($dailyId = 0) {
        if($dailyId > 0) {
            $collection = $this->dailyShippingFactory->create()
                ->addFieldToSelect(array('amount'))
                ->addFieldToFilter('daily_shipping_id',$dailyId);
            return $collection && $collection->getSize() > 0 ? $collection->getFirstItem() : null;
        }
        return  null;
    }
    public function getDailyShippingByProductId($productId = 0) {
        $collection = $this->dailyShippingFactory->create()
                ->addFieldToSelect(array('amount'))
                ->addFieldToFilter('product_id',$productId);
        return  $collection;
    }
}
