<?php
/*
* 2007-2016 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
*  @author PrestaShop SA <contact@prestashop.com>
*  @copyright  2007-2016 PrestaShop SA
*  @license    http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
*  International Registered Trademark & Property of PrestaShop SA
*/


/**
 * @since 1.6.0
 */
class AdminPaxyprestacreateparcelController extends ModuleAdminController
{
    public function __construct()
    {
        parent::__construct();
    }

    public function postProcess()
    {
        $idPaxyPoint = $_POST['paxy_order_point_id'];

        $sql2 = new DbQuery();
        $sql2->from('paxy_order_point', 'po');
        $sql2->where('po.id = '.$idPaxyPoint);
        $paxyOrderData = Db::getInstance()->executeS($sql2)[0];

        $idOrder = $paxyOrderData['order_id'];
        $countryId = (int) $paxyOrderData['id_paxy_country'];
        $carrierId = (int) $paxyOrderData['id_paxy_courier'];
        $category = $paxyOrderData['paxy_parcel_type'];

        $countryDetails = $this->loadCountryDetails($countryId);

        $book = $this->createBook($countryDetails['name']);
        $bookNumber = $book->ksiazka->nr;

        $packageData = $this->createPackageData($idOrder);
        $carrier = $this->loadCarrierDetails($carrierId)['carrier'];

        $carrierCode = $carrier['apiCode'];
        $quantity = 1;
        if (!empty($_POST['quantity'])) {
            $quantity = (int) $_POST['quantity'];
        }

        $order = new Order($idOrder);
        $customWeight = null;
        if (isset($_POST['weight'])) {
            $customWeight = $_POST['weight'];
            $customWeight = str_replace(",", ".", $customWeight);
            $customWeight = round($customWeight, 1);
            if ($customWeight == 0) {
                $_SESSION["error_czechlogistic_parcel"] = 'Waga nie może wynosić 0...';
                $link = $this->context->link->getAdminLink('AdminOrders', true, [
                    'vieworder' => 1,
                    'id_order' => $idOrder
                ]);
                Tools::redirectAdmin($link);
            }
        }

        $parcel = $this->createParcel($packageData, $bookNumber, $category, $carrierCode, $order, $quantity, $customWeight, $paxyOrderData);
        if (isset($parcel->przesylka->nr)) {
            $date = new DateTime();
            DB::getInstance()->update('paxy_order_point', [
                'paxy_parcel_number' => $parcel->przesylka->nr,
                'paxy_parcel_created' => $date->format('Y-m-d H:i:s')
            ], 'id = '.$idPaxyPoint);
            $_SESSION["error_czechlogistic_parcel_created"] = $parcel->przesylka->nr;
        }   elseif (isset($parcel->message)) {
            $_SESSION["error_czechlogistic_parcel"] = $parcel->message;
        }

        $link = $this->context->link->getAdminLink('AdminOrders', true, [
            'vieworder' => 1,
            'id_order' => $idOrder
        ]);
        Tools::redirectAdmin($link);
    }

    private function loadCountryDetails($countryId)
    {
        $apiKey = Configuration::get('paxy_api_key');
        $apiSecret = Configuration::get('paxy_api_secret');
        $ch = curl_init();
        $endpoint = _PAXY_API_URL . '/country/'.$countryId;
        $params = array();
        $url = $endpoint . '?' . http_build_query($params);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            "CL-API-KEY: $apiKey",
            "CL-API-TOKEN: $apiSecret",
            'Accept: application/json'
        ]);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $apiResponse = curl_exec($ch);
        curl_close($ch);
        if ($apiResponse) {
            $apiResponse = json_decode($apiResponse,true);
            return $apiResponse['country'];
        }

        return [];
    }

    private function createBook($countryName)
    {
        $apiKey = Configuration::get('paxy_api_key');
        $apiSecret = Configuration::get('paxy_api_secret');
        $ch = curl_init();
        $fields = array( 'kraj' => $countryName);
        $postvars = '';
        foreach($fields as $key=>$value) {
            $postvars .= $key . "=" . $value . "&";
        }
        $url = _PAXY_API_URL . '/ksiazka/utworz';
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            "CL-API-KEY: $apiKey",
            "CL-API-TOKEN: $apiSecret"
        ]);
        curl_setopt($ch,CURLOPT_URL,$url);
        curl_setopt($ch,CURLOPT_POST, 1);                //0 for a get request
        curl_setopt($ch,CURLOPT_POSTFIELDS,$postvars);
        curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch,CURLOPT_CONNECTTIMEOUT ,3);
        curl_setopt($ch,CURLOPT_TIMEOUT, 20);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        $response = curl_exec($ch);

        return json_decode($response);
    }

    private function loadPickupPointDetails($carrier, $pointId)
    {
        $apiKey = Configuration::get('paxy_widget_api_key');
        $ch = curl_init(_PAXY_WIDGET_API_URL . "/paxyWidget/points/$carrier/$pointId");
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            "token: $apiKey",
            'Accept: application/json'
        ]);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $apiResponse = curl_exec($ch);
        curl_close($ch);
        if ($apiResponse) {
            $response = json_decode($apiResponse, true);
            $data = [];
            $data[] = null;
            $data = array_merge($data, $response['body']);
            return $data;
        }

        return [];
    }

    private function createPackageData($idOrder)
    {
        $ret = [];

        $sql = new DbQuery();
        $sql->select('d.product_quantity');
        $sql->from('order_detail', 'd');
        $sql->where('d.id_order = '.$idOrder);
        $details = Db::getInstance()->executeS($sql);
        $quantity = $details[0]['product_quantity'];
        $ret['quantity'] = $quantity;

        $sql = new DbQuery();
        $sql->select('d.weight');
        $sql->from('order_carrier', 'd');
        $sql->where('d.id_order = '.$idOrder);
        $details = Db::getInstance()->executeS($sql);
        $weight = $details[0]['weight'];
        $ret['weight'] = round((float) $weight, 1);

        $sql = new DbQuery();
        $sql->select('a.*');
        $sql->from('orders', 'o');
        $sql->innerJoin('address', 'a', 'a.id_address = o.id_address_delivery');
        $sql->where('o.id_order = '.$idOrder);
        $order = Db::getInstance()->executeS($sql);


        $sql = new DbQuery();
        $sql->select('c.email');
        $sql->from('customer', 'c');
        $sql->innerJoin('orders', 'o', 'o.id_customer = c.id_customer');
        $sql->where('o.id_order = '.$idOrder);
        $customer = Db::getInstance()->executeS($sql);
        if (!empty($customer[0]['email'])) {
            $customerEmail = $customer[0]['email'];
            $ret['email'] = $customerEmail;
        }

        $address = $order[0];
        $ret['address'] = $address;

        return $ret;
    }

    private function loadCarrierDetails($carrierId)
    {
        $apiKey = Configuration::get('paxy_api_key');
        $apiSecret = Configuration::get('paxy_api_secret');
        $ch = curl_init();
        $endpoint = _PAXY_API_URL . '/carrier/'.$carrierId;
        $params = array();
        $url = $endpoint . '?' . http_build_query($params);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            "CL-API-KEY: $apiKey",
            "CL-API-TOKEN: $apiSecret",
            'Accept: application/json'
        ]);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $apiResponse = curl_exec($ch);
        curl_close($ch);
        if ($apiResponse) {
            return json_decode($apiResponse,true);
        }

        return [];
    }

    private function createParcel($parcelData, $bookNumber, $category, $carrierCode, $order, $quantity, $customWeight, $paxyOrderData)
    {
        $apiKey = Configuration::get('paxy_api_key');
        $apiSecret = Configuration::get('paxy_api_secret');
        $ch = curl_init();

        $fields = array(
            'nr_ksiazki' => $bookNumber,
            'rodzaj' => $category,
            'kodpocztowy' => $parcelData['address']['postcode'],
            'nazwaodbiorcy' => $parcelData['address']['company'] . ' ' . $parcelData['address']['firstname'] . ' ' . $parcelData['address']['lastname'],
            'ulica' => $parcelData['address']['address1'] . ' ' . $parcelData['address']['address2'],
            'nrbudynku' => '',
            'miejscowosc' => $parcelData['address']['city'],
            'nrtelefonu' => !empty($parcelData['address']['phone_mobile']) ? $parcelData['address']['phone_mobile'] : $parcelData['address']['phone'],
            'waga' => (string) round(($parcelData['weight']/$quantity), 1),
            'przewoznik' => $carrierCode,
            'doc_wz' => $order->id,
            'referencje' => $order->id,
            'ilosc' => $quantity
        );

        $pointDetails = null;
        if (!empty($paxyOrderData['pickup_point_id'])) {
            $pointDetails = $this->loadPickupPointDetails($paxyOrderData['widget_pickup_point'], $paxyOrderData['pickup_point_id']);
        }

        if (!empty($parcelData['email'])) {
            $fields['email'] = $parcelData['email'];
        }

        if ($order->module === 'cashondelivery') {
            $fields['pobranie'] = round((float) $order->total_paid, 2);
        }

        if ($customWeight !== null) {
            $fields['waga'] = (string) round(($customWeight/$quantity), 1);
        }

        if (!empty($paxyOrderData['pickup_point_id'])) {
            if (strpos($paxyOrderData['pickup_point_id'], 'cp_balikovna') !== false) {
                if (!empty($pointDetails)) {
                    $fields['miejscowosc'] = $pointDetails['city'];
                    $tmpPointId = str_replace('cp_balikovna', '', $paxyOrderData['pickup_point_id']);
                    $fields['kodpocztowy'] = $tmpPointId;
                }
            } elseif (strpos($paxyOrderData['pickup_point_id'], 'cp_napostu') !== false) {
                if (!empty($pointDetails)) {
                    $fields['miejscowosc'] = $pointDetails['city'];
                    $tmpPointId = str_replace('cp_napostu', '', $paxyOrderData['pickup_point_id']);
                    $fields['kodpocztowy'] = $tmpPointId;
                }
            }
        }

        if (!empty($paxyOrderData['pickup_point_id'])) {
            $parsedPointData = $this->parsePointId($paxyOrderData['pickup_point_id']);
            if (!empty($parsedPointData) && !empty($parsedPointData['body'])) {
                $pointType = $parsedPointData['body']['pointType'];
                $parsedPointId = $parsedPointData['body']['id'];
                $fields['rodzaj'] = $pointType;
                if ($pointType === 'office') {
                    $fields['point_id'] = null;
                    $fields['office_id'] = $parsedPointId;
                }   else {
                    $fields['point_id'] = $parsedPointId;
                    $fields['office_id'] = null;
                }
            }
        }


        $postvars = '';
        foreach($fields as $key=>$value) {
            $postvars .= $key . "=" . $value . "&";
        }
        $url = _PAXY_API_URL . '/przesylki/dodaj';
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            "CL-API-KEY: $apiKey",
            "CL-API-TOKEN: $apiSecret"
        ]);
        curl_setopt($ch,CURLOPT_URL,$url);
        curl_setopt($ch,CURLOPT_POST, 1);                //0 for a get request
        curl_setopt($ch,CURLOPT_POSTFIELDS,$postvars);
        curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch,CURLOPT_CONNECTTIMEOUT ,3);
        curl_setopt($ch,CURLOPT_TIMEOUT, 20);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        $response = curl_exec($ch);
        return json_decode($response);
    }

    private function parsePointId($pointId)
    {
        $apiKey = Configuration::get('paxy_widget_api_key');
        $ch = curl_init(_PAXY_WIDGET_API_URL . "/paxyWidget/parsePointId");
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            "token: $apiKey",
            'Accept: application/json'
        ]);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $data_string = json_encode(array("id"=>$pointId));
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
        $apiResponse = curl_exec($ch);
        curl_close($ch);
        if ($apiResponse) {
            return json_decode($apiResponse,true);
        }

        return [];
    }



}
