<?php

namespace Autogedal\AutogedalHelper\Observer;

use Magento\Framework\Event\ObserverInterface;
use SmartBill\Integration\Model\ResourceModel\Invoice\CollectionFactory as InvoiceCollectionFactory;
use Magento\Sales\Model\Order\Email\Sender\InvoiceSender;

class OrderInvoiced implements \Magento\Framework\Event\ObserverInterface
{
    const SMS_ENABLED_KEY   = 'changeorderstatus/general/send_sms';
    const SMS_TEMPLATE_KEY  = 'changeorderstatus/general/sms_template';
    const SMS_API_KEY       = 'changeorderstatus/general/sms_apikey';
    const SMS_SECRET_KEY    = 'changeorderstatus/general/sms_secretkey';
    const SMS_SENDER_PHONE  = 'changeorderstatus/general/sms_sender_phone';

    public static $dependRegex = '/{{depend awbNumber}}(.*){{\/depend}}/m';

    protected $objectManager;
    protected $scopeConfig;
    protected $transportBuilder;
    protected $orderObj;
    protected $orderId;
    protected $invoiceFactory = null;
    protected $invoiceSender;
    protected $orderRespository;
    protected $invoiceCollectionFactory;
    protected $invoiceSerive;
    protected $transaction;
    protected $currency;

    public function __construct(
        InvoiceSender $invoiceSender,
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder,
        \Magento\Sales\Api\OrderRepositoryInterface $orderRespository,
        \SmartBill\Integration\Model\ResourceModel\Invoice\CollectionFactory $invoiceCollectionFactory,
        \Magento\Sales\Model\Service\InvoiceService $invoiceService,
        \Magento\Framework\DB\Transaction $transaction,
        \Magento\Directory\Model\Currency $currency
    )
    {
        $this->invoiceSender = $invoiceSender;
        $this->scopeConfig = $scopeConfig;
        $this->transportBuilder = $transportBuilder;
        $this->orderRespository = $orderRespository;
        $this->invoiceCollectionFactory = $invoiceCollectionFactory;
        $this->invoiceService = $invoiceService;
        $this->transaction = $transaction;
        $this->currency = $currency;
    }

    public function init()
    {
        $this->orderObj = $this->orderRespository->get($this->orderId);
        $invoiceCollectionFactoryResults = $this->invoiceCollectionFactory->create()->getItemByColumnValue('order_id', $this->orderId);
        if ($invoiceCollectionFactoryResults != null && $invoiceCollectionFactoryResults->getData('order_id') == $this->orderId) {
            $this->invoiceFactory = $invoiceCollectionFactoryResults;
        }
    }

    public function execute(
        \Magento\Framework\Event\Observer $observer
    ) {
        $orderId = (int)$observer->getData('orderId');
        $this->orderId = $orderId;

        $this->init();
        $this->sendSMSStatusNotifications();
        $this->createMagentoInvoice();
    }

    public function generateTemplate()
    {
        return $this->scopeConfig->getValue(self::SMS_TEMPLATE_KEY);
    }

    public function createMagentoInvoice()
    {
        if ($this->orderObj->canInvoice()) {
            // Create invoice for this order
            $invoice = $this->invoiceService->prepareInvoice($this->orderObj);

            // Make sure there is a qty on the invoice
            if (!$invoice->getTotalQty()) {
                throw new \Magento\Framework\Exception\LocalizedException(
                    __('You can\'t create an invoice without products.')
                );
            }

            // Register as invoice item
            $invoice->setRequestedCaptureCase(\Magento\Sales\Model\Order\Invoice::CAPTURE_OFFLINE);
            $invoice->register();
            $invoice->save();

            // Save the invoice to the order
            $transaction = $this->transaction
                ->addObject($invoice)
                ->addObject($invoice->getOrder());

            $transaction->save();

            $this->invoiceSender->send($invoice);

            $state = $this->orderObj->getState();
            $status = 'custom_facturat';
            $comment = 'Factura a fost emisa';
            $this->orderObj->setState($state);
            $this->orderObj->setStatus($status);
            $this->orderObj->addStatusToHistory($this->orderObj->getStatus(), $comment);
            $this->orderObj->save();
        }
        $magentoInvoiceId = $this->getInvoiceIdByOrderId();
        $this->invoiceFactory->setData('invoice_id', (int)$magentoInvoiceId);
    }

    public function getInvoiceIdByOrderId()
    {
        foreach ($this->orderObj->getInvoiceCollection() as $invoice)
        {
            return $invoice->getIncrementId();
        }
    }

    public function sendSMSStatusNotifications()
    {
        $sendSMSEnabled = $this->scopeConfig->getValue(self::SMS_ENABLED_KEY);

        if (!$sendSMSEnabled) {
            return false;
        }

        try {
            $recepientEmail = $this->orderObj->getCustomerEmail();
            $recepientName = $this->orderObj->getCustomerName();
            $recepientPhone = $this->orderObj->getShippingAddress()->getTelephone();
            $awbNumber = $this->orderObj->getData('awb_number');
            $carrierName = $this->orderObj->getData('carrier_name');

            $orderTotal = $this->currency->format($this->orderObj->getGrandTotal(), ['display'=>\Zend_Currency::NO_SYMBOL], false);

            $vars = array(
                '{{customerName}}' => $recepientName,
                '{{customerEmail}}' => $recepientEmail,
                '{{customerPhone}}' => $recepientPhone,
                '{{awbNumber}}' => $awbNumber,
                '{{carrierName}}' => $carrierName,
                '{{orderId}}' => $this->orderObj->getRealOrderId(),
                '{{orderTotal}}' => $orderTotal,
            );

            $smsTemplate = $this->replaceVars($vars, $this->generateTemplate());
            $smsSentFlag = $this->sendSMSApiCall($recepientPhone,$smsTemplate);

            // Save some history to the order
            if (!empty($smsSentFlag)) {
                $msg = 'Trimis SMS ' . $recepientPhone . " : " . $smsTemplate;
            } else {
                $msg = 'SMS-ul nu a fost trimis';
            }

            $state = $this->orderObj->getState();
            $status = 'complete';
            $this->orderObj->setState($state);
            $this->orderObj->setStatus($status);
            $this->orderObj->addStatusToHistory($this->orderObj->getStatus(), $msg);
            $this->orderObj->save();

        } catch (Exception $e) {
            Mage::logException($e);
        }

    }

    protected function sendSMSApiCall($customerPhone,$message)
    {
        if (empty($customerPhone) || empty($message)) {
            return false;
        }
        $smsApiKey = $this->scopeConfig->getValue(self::SMS_API_KEY);
        $smsSecretKey = $this->scopeConfig->getValue(self::SMS_SECRET_KEY);

        if (!$smsApiKey || !$smsSecretKey) {
            return false;
        }

        $apiKey = $smsApiKey;
        $secret = $smsSecretKey;
        $nonce = time();
        $method = "POST";
        $url = "/prepaid/message";
        $sender = $this->scopeConfig->getValue(self::SMS_SENDER_PHONE);
        $recipient = $customerPhone;
        $message = $message;
        $visibleMessage = "";
        $scheduleDate = ''; //Format timestamp
        $validityDate = ''; //Format timestamp
        $callbackUrl = '';
        $string = $apiKey . $nonce . $method . $url . $sender .
            $recipient . $message . $visibleMessage . $scheduleDate .
            $validityDate . $callbackUrl . $secret;

        $signature = hash('sha512', $string);
        $data = array(
            "apiKey" => $apiKey,
            "sender" => $sender,
            "recipient" => $recipient,
            "message" => $message,
            "scheduleDatetime" => $scheduleDate,
            "validityDatetime" => $validityDate,
            "callbackUrl" => $callbackUrl,
            "userData" => "",
            "visibleMessage" => $visibleMessage,
            "nonce" => $nonce);
        $curlurl = 'https://www.web2sms.ro/prepaid/message';
        $ch = curl_init($curlurl);
        curl_setopt($ch, CURLOPT_HEADER, true);
        curl_setopt($ch, CURLOPT_USERPWD, $apiKey . ":" . $signature);
        $header = array();
        $header[] = 'Content-type: application/json';
        $header[] = 'Content-length: ' . strlen(json_encode($data));

        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_FAILONERROR, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
        $postResult = curl_exec($ch);
        $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

        if ($postResult === false || $httpcode > 400)
        {
            return false;
        }
        return true;
    }

    protected function replaceVars($vars, $content)
    {
        $result = preg_replace(self::$dependRegex, '', $content);
        return str_replace(array_keys($vars), array_values($vars), $result);
    }
}
