<?php
/**
 * Copyright © 2018 EaDesign by Eco Active S.R.L. All rights reserved.
 * See LICENSE for license details.
 */

namespace Eadesigndev\DPD\Model;

use Eadesigndev\Urgent\Api\Data\GenerateAwbInterface;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Filesystem\DirectoryList;
use Magento\Framework\Model\Context;
use Magento\Framework\Model\AbstractModel;
use Magento\Framework\HTTP\ClientInterface;
use Eadesigndev\Awb\Model\AwbRepository;
use Magento\Sales\Api\OrderRepositoryInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;

#[\AllowDynamicProperties]
class GenerateAwb extends AbstractModel implements GenerateAwbInterface
{
    const DPD_CONFIG_KEY_URL = "carriers/dpd/url_feed";
    const DPD_CONFIG_KEY_USERNAME = "carriers/dpd/user_account_urgent";
    const DPD_CONFIG_KEY_PASSWORD = "carriers/dpd/user_password_urgent";

    const DPD_API_CREATE = "shipment";

    const DPD_CONTENTS_TRIM = 100;
    const DPD_WHO_PAY_RECIPIENT = "RECIPIENT";
    const DPD_WHO_PAY_SENDER = "SENDER";
    const DPD_PACKAGE_DEFAULT = "BOX";

    const DPD_USERNAME = "200900393";
    const DPD_PASSWORD = "4163945965";

    protected $_client;
    protected $_awbRepository;
    protected $_orderRepository;

    public function __construct(
        Context $context,
        \Magento\Framework\Registry $registry,
        \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
        \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
        array $data = [],
        ClientInterface $client = null,
        AwbRepository $awbRepository = null,
        OrderRepositoryInterface $orderRepository = null,
        ScopeConfigInterface $scopeConfig = null,
        DirectoryList $dir = null
    )
    {
        $this->_orderRepository = $orderRepository ?? ObjectManager::getInstance()->get(OrderRepositoryInterface::class);
        $this->_awbRepository = $awbRepository ?? ObjectManager::getInstance()->get(AwbRepository::class);
        $this->_client = $client ?? ObjectManager::getInstance()->get(ClientInterface::class);
        $this->_scopeConfig = $scopeConfig ?? ObjectManager::getInstance()->get(ScopeConfigInterface::class);
        $this->dir = $dir ?? ObjectManager::getInstance()->get(DirectoryList::class);
        parent::__construct($context, $registry, $resource, $resourceCollection, $data);
    }

    public function getApiUrl()
    {
        return $this->_scopeConfig->getValue(self::DPD_CONFIG_KEY_URL);
    }

    public function getApiUsername()
    {
        return $this->_scopeConfig->getValue(self::DPD_CONFIG_KEY_USERNAME);
    }

    public function getApiPassword()
    {
        return $this->_scopeConfig->getValue(self::DPD_CONFIG_KEY_PASSWORD);
    }

    protected function replaceDiacritics($string)
    {
        if ($string) {
            $keywords = [
                'Ă' => 'A', 'ă' => 'a', 'Â' => 'A', 'â' => 'a', 'Î' => 'I', 'î' => 'i', 'Ș' => 'S', 'ş' => 's', 'ș' => 's', 'Ț' => 'T', 'ț' => 't',
                'Š' => 'S', 'š' => 's', 'Ž' => 'Z', 'ž' => 'z', 'À' => 'A', 'Á' => 'A', 'Â' => 'A', 'Ã' => 'A', 'Ä' => 'A', 'Å' => 'A', 'Æ' => 'A', 'Ç' => 'C', 'È' => 'E', 'É' => 'E',
                'Ê' => 'E', 'Ë' => 'E', 'Ì' => 'I', 'Í' => 'I', 'Î' => 'I', 'Ï' => 'I', 'Ñ' => 'N', 'Ò' => 'O', 'Ó' => 'O', 'Ô' => 'O', 'Õ' => 'O', 'Ö' => 'O', 'Ø' => 'O', 'Ù' => 'U',
                'Ú' => 'U', 'Û' => 'U', 'Ü' => 'U', 'Ý' => 'Y', 'Þ' => 'B', 'ß' => 'Ss', 'à' => 'a', 'á' => 'a', 'â' => 'a', 'ã' => 'a', 'ä' => 'a', 'å' => 'a', 'æ' => 'a', 'ç' => 'c',
                'è' => 'e', 'é' => 'e', 'ê' => 'e', 'ë' => 'e', 'ì' => 'i', 'í' => 'i', 'î' => 'i', 'ï' => 'i', 'ð' => 'o', 'ñ' => 'n', 'ò' => 'o', 'ó' => 'o', 'ô' => 'o', 'õ' => 'o',
                'ö' => 'o', 'ø' => 'o', 'ù' => 'u', 'ú' => 'u', 'û' => 'u', 'ý' => 'y', 'þ' => 'b', 'ÿ' => 'y'
            ];
            $string = strtr($string, $keywords);
            $string = trim($string);
        }
        return $string;
    }

    public function generateAwb($awbId)
    {
	$logger = \Magento\Framework\App\ObjectManager::getInstance()->get(\Psr\Log\LoggerInterface::class);
        $model = $this->_awbRepository->getById($awbId);

        $this->_client->setHeaders([
            'Content-Type' => 'application/json'
        ]);

        $data = [
            "userName" => $this->getApiUsername(),
            "password" => $this->getApiPassword()
        ];

        $data["service"] = [
            "serviceId" => $model->getData('tariff_plan'),
            "autoAdjustPickupDate" => true
        ];

        $data["content"] = [
            "parcelsCount" => ($model->getData('packages') ?? 0) + ($model->getData('envelopes') ?? 0),
            "totalWeight" => $model->getData('weight'),
            "contents" => substr($model->getData('content'), 0, (self::DPD_CONTENTS_TRIM - 1)),
            "package" => self::DPD_PACKAGE_DEFAULT
        ];

        $data["payment"] = [
            "courierServicePayer" => $model->getData('delivery_payment') ? $model->getData('delivery_payment') : self::DPD_WHO_PAY_SENDER
        ];

	$siteId = $this->getSiteId(
            $model->getData('city'),
            $model->getData('region_id')
        );

        $streetName = $this->replaceDiacritics($model->getData('street'));
        $data["recipient"] = [
            "phone1" => [
                "number" => $model->getData('telephone')
            ],

            "clientName" => $model->getData('recipient'),
            "email" => $model->getData('customer_email'),
            "address" => [
                    "siteName" => $model->getData('city'),
                    "streetType" => $model->getData('street_type'),
                    "streetName" => substr($streetName, 0, 50),
                    "streetNo"  => '-',
                    "postcode" => $model->getData('postcode')
            ]
        ];
	//$logger->info(print_r($model->getData(),true));
	if($siteId) {
            unset($data["recipient"]["address"]["siteName"]);
            $data["recipient"]["address"]["siteId"] = $siteId;
        }

        $data["shipmentNote"] = $model->getData('comments');

        if ($model->getData('repayment_value') > 0) {
            $codSettings = [
                "amount" => $model->getData('repayment_value')
            ];
            if ($model->getData('payment_method') != "CARD") {
                $codSettings["processingType"] = $model->getData('payment_method');
            }
            $data["service"]["additionalServices"]["cod"] = $codSettings;
        }

        if ($model->getData('delivery_saturday')) {
            $data["service"]["saturdayDelivery"] = true;
        }

        if ($model->getData('open_package')) {
            $data["service"]["additionalServices"]["obpd"] = [
                "option" => "OPEN",
                "returnShipmentServiceId" => $model->getData('tariff_plan'),
                "returnShipmentPayer" => "SENDER"
            ];
        }

        if (!empty($model->getData('order_id'))) {
            $orderObject = $this->_orderRepository->get((int)$model->getData('order_id'));
            if (!empty($orderObject->getData('company'))) {
                $data["recipient"]["privatePerson"] = true;
            } else {
                $data["recipient"]["privatePerson"] = false;
                $data["recipient"]["contactName"] = $model->getData('recipient');
            }
        } else {
            $data["recipient"]["privatePerson"] = true;
        }

        $data["sender"]["clientId"] = $model->getData('awb_pickup_id');
	
	$logger->info(print_r($data, true));

        $this->_client->post($this->getCreateShipmentRequestUrl(), json_encode($data));
        $response = $this->_client->getBody();

        if (empty($response)) {
            return false;
        }

        $responseDecoded = json_decode($response, true);
        if (!empty($responseDecoded["error"])) {
            throw new \Exception($responseDecoded["error"]["message"]);
        }

        return $responseDecoded["id"];
    }

    private function demoData()
    {
        return '{
            "userName": self::,
            "password": "4163945965",
            "service": {
                "serviceId": 2002,
                "additionalServices": {
                    "declaredValue": {
                        "amount": 100
                    },
                    "returns": {
                        "rod": {
                            "enabled": true
                        },
                        "returnReceipt": {
                            "enabled": true
                        },
                        "swap": {
                            "serviceId": 2002,
                            "parcelsCount": 1
                        }
                    }
                }
            },
            "content": {
                "parcelsCount": 1,
                "totalWeight": 20,
                "contents": "FURNITURE",
                "package": "BOX"
            },
            "payment": {
                "courierServicePayer": "SENDER"
            },
            "recipient": {
                "phone1": {
                    "number": "0999123321"
                },
                "privatePerson": true,
                "clientName": "TEST",
                "contactName": "TEST",
                "email": "a@b.c",
                "address": {
                    "siteName": "Sibiu",
                    "streetType": "str.",
                    "streetName": "ACILIU",
                    "streetNo": "3"
                }
            },
            "shipmentNote": "Test note",
            "ref1": "R1",
            "ref2": "R2"
        }';
    }

    public function getCreateShipmentRequestUrl()
    {
        return $this->getApiUrl() . self::DPD_API_CREATE;
    }

    public function deleteAwb($awbNumber)
    {
        $request = new \Zend\Http\Request();

        $header = [
            'Content-type: application/json;'
        ];

        $httpHeaders = new \Zend\Http\Headers();
        $httpHeaders->addHeaders(
            $header
        );

        $request->setHeaders($httpHeaders);

        $params = new \Zend\Stdlib\Parameters([
            "userName" => $this->getApiUsername(),
            "password" => $this->getApiPassword(),
            "shipmentId" => $awbNumber,
            "comment" => __('Canceled by admin')
        ]);
        $request->setQuery($params);

        $url = $this->getApiUrl() . self::DPD_API_CREATE;

        $request->setUri($url);
        $request->setMethod(\Zend\Http\Request::METHOD_DELETE);

        $client = new \Zend\Http\Client();
        $response = $client->send($request);

        return $response->getStatusCode() >= 200 && $response->getStatusCode() < 300;
    }

    public function getPunctRidicare()
    {
        // TODO: Implement getPunctRidicare() method.
    }

    public function setGenerateAwb($awbId)
    {
        // TODO: Implement setGenerateAwb() method.
    }
	
    public function getSiteId($city, $region) {
        if ($region == 'Satu-Mare') {
            $region = 'SATU MARE';
        }
	$logger = \Magento\Framework\App\ObjectManager::getInstance()->get(\Psr\Log\LoggerInterface::class);
	//$logger->info('getSiteId');
        //TODO to fix this
        //$csvFile = '/var/www/html/autogedal_upgrade/642.csv';
        $csvFile = $this->dir->getRoot() . '/' . '642.csv';
        $csv = $this->csvToArray($csvFile);

	foreach($csv as $key => $item) {
		//$logger->info("city: " . $city);
		//$logger->info("region: " . $region);	
		if(isset($item[5]) && isset($item[9]) && strtoupper($city) == strtoupper($item[5]) && strtoupper($region) == strtoupper($item[9])) {
        	//$logger->info(print_r($item, true));
                return $item[0];
            }
        }
        return false;
    }

    public function csvToArray($csvFile){
        $file_to_read = fopen($csvFile, 'r');
        while (!feof($file_to_read) ) {
            $lines[] = fgetcsv($file_to_read, 1000, ',');
        }
        fclose($file_to_read);
        return $lines;
    }
}
