<?php

namespace Myfitmix\CustomImport\Observer;

use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Myfitmix\CustomImport\Model\AdditionalOptionFactory;
use Myfitmix\CustomImport\Model\CustomDiscountFactory;
use Myfitmix\CustomImport\Model\DailyShippingFactory;
use Myfitmix\CustomImport\Model\ThreeDListFactory;
use Magento\Catalog\Model\Product\Action as ProductAction;

class Update implements ObserverInterface
{
    protected $messageManager;
    protected $logger;
    protected $additionalOptionFactory;
    protected $customDiscountFactory;
    protected $_resource;
    protected $csv;
    private $productRepository;
    public $_storeManager;
    protected $_searchCriteriaBuilder;
    protected $_scopeConfig;
    protected  $connection;
    private $productAction;
    private $storeManager;
    protected $_productRepository;
    protected $currentDate;
    protected $dailyShippingFactory;
    protected $threeDListFactory;
    protected $failedSkus = [];

    public function __construct(
        \Magento\Framework\Message\ManagerInterface $messageManager,
        AdditionalOptionFactory $additionalOptionFactory,
        CustomDiscountFactory $customDiscountFactory,
        \Magento\Framework\File\Csv $csv,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        \Psr\Log\LoggerInterface $logger,
        \Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
        \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder,
        \Magento\Framework\App\ResourceConnection $resource,
        \Magento\Catalog\Model\ProductRepository $_productRepository,
        ProductAction $action,
        DailyShippingFactory $dailyShippingFactory,
        ThreeDListFactory $threeDListFactory,
        \Magento\Catalog\Model\ProductFactory $productFactory
    ) {
        $this->messageManager = $messageManager;
        $this->additionalOptionFactory = $additionalOptionFactory;
        $this->customDiscountFactory = $customDiscountFactory;
        $this->productRepository = $productRepository;
        $this->csv = $csv;
        $this->_storeManager = $storeManager;
        $this->_scopeConfig = $scopeConfig;
        $this->logger = $logger;
        $this->_searchCriteriaBuilder = $searchCriteriaBuilder;
        $this->_resource = $resource;
        $this->productAction = $action;
        $this->storeManager = $storeManager;
        $this->_productRepository = $productRepository;
        $this->dailyShippingFactory = $dailyShippingFactory;
        $this->threeDListFactory = $threeDListFactory;
        $this->productFactory = $productFactory;
    }

    /**,
     * Below is the method that will fire whenever the event runs!
     *
     * @param Observer $observer
     */
    public function execute(Observer $observer)
    {
        $this->currentDate = date('y-m-d h:i:s');
        try {
            $storeScope = \Magento\Store\Model\ScopeInterface::SCOPE_STORES;
            $uploadedCsvFilePath = $this->_scopeConfig->getValue("customimport/general/file_upload", $storeScope);
            $pubMediaUrl = $this->_storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA);
            $uploadedCsv = $pubMediaUrl . "csvfilemedia/" . $uploadedCsvFilePath;

            if ($uploadedCsvFilePath != '') {
                $handle = fopen($uploadedCsv, "r");
                $csv = array_map("str_getcsv", file($uploadedCsv));
                $headers = array_shift($csv);
                $columns = [];
                foreach ($headers as $key => $value) {
                    $columns[$value] = $key;
                }
                $storeIds = array_keys($this->storeManager->getStores());
                foreach ($csv as $i => $row) {
                    // $sku = $row[$columns['sku']];
                    $sku = $row[0];
                    $product = $this->getProductBySku($sku);
                    if ($product === null) {
                        continue;
                    }
                    $product_id = $product->getEntityId();

                    //magetop_3d_lists 
                    $dataValue = array(
                        // 'sku'=> $row[$columns['sku']],
                        'product_id' => $product_id,
                        'title' =>  $row[$columns["3d_preview_title"]],
                        'is_default' => $row[$columns["3d_preview_is_default"]],
                        'filename' => $row[$columns["3d_preview_model_file_name"]],
                        'file_preview' => $row[$columns["3d_preview_model_file_preview"]],
                        'preview_light' => $row[$columns["3d_preview_model_light"]],
                        'preview_zoom' => $row[$columns["3d_preview_model_zoom"]],
                        'position' => $row[$columns["3d_preview_model_position"]],
                        'thumbnail' => $row[$columns["3d_preview_thumbnail_file"]],
                        'texture' => $row[$columns["3d_preview_texture"]],
                        'texture_width' => $row[$columns["3d_preview_texture_width"]],
                        'texture_height' => $row[$columns["3d_preview_texture_height"]],
                        'folder_preview' => $product_id

                    );
                    if (
                        !empty($dataValue['title'])
                        && !empty($dataValue['file_preview'])
                    ) {
                        $this->insertOrUpdate3dList($dataValue);
                    }

                    //magetop_preview_custom_discount
                    $customDiscountData = array(
                        'product_id' => $product_id,
                        'discount_title' => "Our Price",
                        'discount_price' => empty($row[$columns["our_price"]]) ? 0 : $row[$columns["our_price"]],
                    );


                    if (!empty($customDiscountData['discount_title'])) {
                        $this->insertOrUpdateCustomDiscount($customDiscountData);
                    }

                    $customDiscountData = array(
                        'product_id' => $product_id,
                        'discount_title' => "Additional options",
                        'discount_price' => empty($row[$columns["additional_options"]]) ? 0 : $row[$columns["additional_options"]],
                    );

                    if (!empty($customDiscountData['discount_title'])) {
                        $this->insertOrUpdateCustomDiscount($customDiscountData);
                    }
                    $customDiscountData = array(
                        'product_id' => $product_id,
                        'discount_title' => "Processing & Finishing",
                        'discount_price' => empty($row[$columns["processing_and_finishing"]]) ? 0 : $row[$columns["processing_and_finishing"]],
                    );

                    if (!empty($customDiscountData['discount_title'])) {
                        $this->insertOrUpdateCustomDiscount($customDiscountData);
                    }
                    $customDiscountData = array(
                        'product_id' => $product_id,
                        'discount_title' => "Shipping",
                        'discount_price' => empty($row[$columns["shipping"]]) ? 0 : $row[$columns["shipping"]],
                    );

                    if (!empty($customDiscountData['discount_title'])) {
                        $this->insertOrUpdateCustomDiscount($customDiscountData);
                    }

                    //magetop_preview_additional_option
                    $additionalOptionData = array(
                        'product_id' => $product_id,
                        'title' => "5C transparent",
                        'description' => $row[$columns["5c_transparent_tooltip"]],
                        'price' => empty($row[$columns["5c_transparent_percentage"]]) ? 0 : $row[$columns["5c_transparent_percentage"]]
                    );

                    if (!empty($additionalOptionData['title'])) {
                        $this->insertOrUpdateAdditionalOptions($additionalOptionData);
                    }

                    $additionalOptionData = array(
                        'product_id' => $product_id,
                        'title' => "Quality check",
                        'description' => $row[$columns["quality_check_tooltip"]],
                        'price' => empty($row[$columns["quality_check"]]) ? 0 : $row[$columns["quality_check"]]

                    );

                    if (!empty($additionalOptionData['title'])) {
                        $this->insertOrUpdateAdditionalOptions($additionalOptionData);
                    }

                    $additionalOptionData = array(
                        'product_id' => $product_id,
                        'title' => "Design service",
                        'description' => $row[$columns["design_service_tooltip"]],
                        'price' => empty($row[$columns["design_service"]]) ? 0 : $row[$columns["design_service"]]
                    );

                    if (!empty($additionalOptionData['title'])) {
                        $this->insertOrUpdateAdditionalOptions($additionalOptionData);
                    }

                    //magetop_preview_daily_shipping
                    $dailyShippingData = array(
                        'product_id' => $product_id,
                        'delivery_type' => "Standard",
                        'delivery_days' => empty($row[$columns["standard_days"]]) ? 0 : $row[$columns["standard_days"]],
                        'amount' => empty($row[$columns["standard_percentage"]]) ? 0 : $row[$columns["standard_percentage"]]

                    );
                    if (!empty($dailyShippingData['delivery_type'])) {
                        $this->insertOrUpdateShipping($dailyShippingData);
                    }
                    $dailyShippingData = array(
                        'product_id' => $product_id,
                        'delivery_type' => "Priority",
                        'delivery_days' => empty($row[$columns["priority_days"]]) ? 0 : $row[$columns["priority_days"]],
                        'amount' => empty($row[$columns["priority_percentage"]]) ? 0 : $row[$columns["priority_percentage"]]
                    );

                    if (!empty($dailyShippingData['delivery_type'])) {
                        $this->insertOrUpdateShipping($dailyShippingData);
                    }

                    $dailyShippingData = array(
                        'product_id' => $product_id,
                        'delivery_type' => "Express",
                        'delivery_days' => empty($row[$columns["express_days"]]) ? 0 : $row[$columns["express_days"]],
                        'amount' => empty($row[$columns["express_percentage"]]) ? 0 : $row[$columns["express_percentage"]]
                    );

                    if (!empty($dailyShippingData['delivery_type'])) {
                        $this->insertOrUpdateShipping($dailyShippingData);
                    }

                    //attribute

                    // $updateAttribute = array(
                    //         'pcto_is_3d'=> strtolower($row[$columns["is_3d_model"]])=='yes' ? 1:0,
                    //         'pcto_discount' => $row[27], 
                    //         'pdf_product_description' => $row[28], 
                    //         'pdf_ingredients' => $row[29],
                    //         'pdf_delivery_time' => $row[30], 
                    //         'pdf_packaging' => $row[31], 
                    //         'pdf_best_before' => $row[32], 
                    //         'pdf_customs_tariff_number' => $row[33]
                    //     );
                    //     $this->logger->info("kkk:" . json_encode($updateAttribute));
                    //     foreach ($storeIds as $storeId) {
                    //         $this->productAction->updateAttributes([$product_id], $updateAttribute, $storeId);
                    //     }
                }
            }
        } catch (Exception $e) {

            $writer = new \Zend\Log\Writer\Stream(BP . '/var/log/importlog.log');
            $logger = new \Zend\Log\Logger();
            $logger->addWriter($writer);
            $error_message = "Unable to read csv file. Error: " . $e->getMessage() . '. See exception.log for full error log.';

            $this->messageManager->addError($error_message);
            $this->logger->info($e);
        }
        if (count($this->failedSkus) > 0) {
            $this->messageManager->addError(
                "Import Failed for the SKUs: <b>" . join(", ", $this->failedSkus) . "</b>"
            );
        }
    }
    public function insertOrUpdateShipping($data)
    {
        $fact =  $this->dailyShippingFactory->create();
        $collection = $fact
            ->getCollection()
            ->addFieldToSelect('*')
            ->addFieldToFilter('product_id', ['eq' => $data["product_id"]])
            ->addFieldToFilter('delivery_type', ['eq' => $data["delivery_type"]]);
        if ($collection->getSize()) {
            $extData = $collection->getFirstItem()->getData();
            $extData["delivery_days"] =  $data["delivery_days"];
            $extData["amount"] =  $data["amount"];
            $extData['created_at'] =  $this->currentDate;
            $extData['updated_at'] = $this->currentDate;
            $fact
                ->setData($extData)
                ->save();
        } else {
            $fact
                ->addData($data)
                ->save();
        }
    }
    public function insertOrUpdateAdditionalOptions($data)
    {
        $fact =  $this->additionalOptionFactory->create();
        $collection = $fact
            ->getCollection()
            ->addFieldToSelect('*')
            ->addFieldToFilter('product_id', ['eq' => $data["product_id"]])
            ->addFieldToFilter('title', ['eq' => $data["title"]]);
        if ($collection->getSize()) {
            $extData = $collection->getFirstItem()->getData();
            $extData["description"] =  $data["description"];
            $extData["price"] = $data["price"];
            $extData['created_at'] =  $this->currentDate;
            $extData['updated_at'] = $this->currentDate;
            $fact
                ->setData($extData)
                ->save();
        } else {
            $fact
                ->addData($data)
                ->save();
        }
    }

    public function insertOrUpdate3dList($data)
    {
        $fact =  $this->threeDListFactory->create();
        $collection = $fact
            ->getCollection()
            ->addFieldToSelect('*')
            ->addFieldToFilter('product_id', ['eq' => $data["product_id"]])
            ->addFieldToFilter('title', ['eq' => $data["title"]])
            ->addFieldToFilter('file_preview', ['eq' => $data["file_preview"]]);
        if ($collection->getSize()) {
            $extData = $collection->getFirstItem()->getData();
            $extData["is_default"] =  $data["is_default"];
            $extData["filename"] =  $data["filename"];
            $extData["file_preview"] =  $data["file_preview"];
            $extData["position"] =  $data["position"];
            $extData["preview_light"] =  $data["preview_light"];
            $extData["preview_zoom"] =  $data["preview_zoom"];
            $extData["thumbnail"] =  $data["thumbnail"];
            $extData["texture"] =  $data["texture"];
            $extData["texture_width"] =  $data["texture_width"];
            $extData["texture_height"] =  $data["texture_height"];
            $extData["folder_preview"] =  $data["folder_preview"];
            $extData['created_at'] =  $this->currentDate;
            $extData['updated_at'] = $this->currentDate;
            $fact
                ->setData($extData)
                ->save();
        } else {
            $data['created_at'] = $this->currentDate;
            $fact
                ->addData($data)
                ->save();
        }
    }
    public function insertOrUpdateCustomDiscount($data)
    {
        $fact =  $this->customDiscountFactory->create();
        $collection = $fact
            ->getCollection()
            ->addFieldToSelect('*')
            ->addFieldToFilter('product_id', ['eq' => $data["product_id"]])
            ->addFieldToFilter('discount_title', ['eq' => $data["discount_title"]]);
        if ($collection->getSize()) {
            $extData = $collection->getFirstItem()->getData();
            $extData["discount_price"] =  $data["discount_price"];
            $extData['created_at'] =  $this->currentDate;
            $extData['updated_at'] = $this->currentDate;
            $fact
                ->setData($extData)
                ->save();
        } else {
            $data['created_at'] = $this->currentDate;
            $fact
                ->addData($data)
                ->save();
        }
    }
    public function getProductBySku($sku)
    {
        try {
            return $this->_productRepository->get($sku);
        } catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
            $this->logger->info($e);
            $message = "Sku <b>" . $sku . "</b> is not matching.";
            array_push($this->failedSkus, $sku);
            return null;
        } catch (Exception $e) {
            $this->logger->info($e);
            array_push($this->failedSkus, $sku);
            return null;
        }
    }
}
