<?php

namespace Paxy\Controller;

use DateTime;
use PrestaShop\PrestaShop\Adapter\Configuration;
use PrestaShop\PrestaShop\Adapter\Entity\Db;
use PrestaShop\PrestaShop\Adapter\Entity\DbQuery;
use PrestaShop\PrestaShop\Adapter\Entity\Order;
use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class PaxyController extends FrameworkBundleAdminController
{
    private $paxyApiUrl = 'https://api.paxy.pl';

    public function loadCarriers(Request $request)
    {
        $apiKey = $this->configuration->get('paxy_api_key');
        $apiSecret = $this->configuration->get('paxy_api_secret');
        $ch = curl_init();
        $endpoint = $this->paxyApiUrl . '/carrier/country/'.$request->get('countryId');
        $params = array('countryId' => $request->get('countryId'));
        $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) {
            $result = json_decode($apiResponse,true);
            return new JsonResponse(['carriers' => $result['carriers']]);
        }

        return new JsonResponse([], Response::HTTP_NOT_FOUND);
    }

    public function loadDimensions(Request $request)
    {
        $apiKey = $this->configuration->get('paxy_api_key');
        $apiSecret = $this->configuration->get('paxy_api_secret');
        $ch = curl_init();
        $endpoint = $this->paxyApiUrl . '/dimension/';
        $params = array(
            'countryId' => $request->get('countryId'),
            'carrierId' => $request->get('carrierId'),
        );
        $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) {
            $result = json_decode($apiResponse,true);
            $ret = [];
            foreach ($result['categories'] as $r) {
                $ret[] = [
                    'id' => $r['id'],
                    'name' => $r['label']
                ];
            }
            return new JsonResponse(['dimensions' => $ret]);
        }

        return new JsonResponse([], Response::HTTP_NOT_FOUND);
    }

    public function createPackage(Request $request)
    {
        $idOrderCarrier = $request->get('id_order_carrier');
        $sql = new DbQuery();
        $sql->select('oc.id_order_carrier, oc.id_order, carrier.*');
        $sql->from('order_carrier', 'oc');
        $sql->innerJoin('carrier', 'carrier', 'carrier.id_carrier = oc.id_carrier');
        $sql->where('oc.id_order_carrier = '.$idOrderCarrier);
        $package = Db::getInstance()->executeS($sql);
        $idOrder = $package[0]['id_order'];

        $countryId = (int) $package[0]['czechlogistic_country'];
        $carrierId = (int) $package[0]['czechlogistic_carrier'];
        $category = $package[0]['czechlogistic_type'];

        $countryDetails = $this->loadCountryDetails($countryId);
        $book = $this->createBook($countryDetails['name']);
        $bookNumber = $book->ksiazka->nr;
        $packageData = $this->createPackageData($idOrder, $idOrderCarrier);
        $carrier = $this->loadCarrierDetails($carrierId)['carrier'];
        $carrierCode = $carrier['apiCode'];
        $shouldRegainNumber = strtolower($carrier['apiCode']) === 'poczta';


        $order = new Order($idOrder);
        $quantity = (int) $request->get('quantity', 1);
        $parcel = $this->createParcel($packageData, $bookNumber, $category, $carrierCode, $order, $quantity);
        if (isset($parcel->przesylka->nr)) {
            $date = new DateTime();
            DB::getInstance()->update('order_carrier', [
                'czechlogistic_parcel_number' => $parcel->przesylka->nr,
                'czechlogistic_created' => $date->format('Y-m-d H:i:s')
            ], 'id_order_carrier = '.$idOrderCarrier);
            if ($shouldRegainNumber) {
                DB::getInstance()->update('order_carrier', [
                    'czechlogistic_should_regain_number' => $date->format('Y-m-d H:i:s')
                ], 'id_order_carrier = '.$idOrderCarrier);
            }
            $_SESSION["error_czechlogistic_parcel_created"] = $parcel->przesylka->nr;
        }   elseif (isset($parcel->message)) {
            $_SESSION["error_czechlogistic_parcel"] = $parcel->message;
        }
        $link = $this->getAdminLink('AdminOrders', [
            'vieworder' => 1,
            'id_order' => $idOrder,
            'token' => $request->get('token')
        ]);
        return $this->redirect($link);
    }

    public function downloadLabel(Request $request)
    {
        $idOrderCarrier = $request->get('id_order_carrier');
        $sql = new DbQuery();
        $sql->select('oc.id_order_carrier, oc.id_order, oc.czechlogistic_parcel_number, carrier.*');
        $sql->from('order_carrier', 'oc');
        $sql->innerJoin('carrier', 'carrier', 'carrier.id_carrier = oc.id_carrier');
        $sql->where('oc.id_order_carrier = '.$idOrderCarrier);
        $package = Db::getInstance()->executeS($sql);
        $parcelNumber = $package[0]['czechlogistic_parcel_number'];

        $apiKey = $this->configuration->get('paxy_api_key');
        $apiSecret = $this->configuration->get('paxy_api_secret');
        $ch = curl_init();
        $endpoint = $this->paxyApiUrl . '/etykieta/drukuj';
        $params = array(
            'nr_przesylki' => $parcelNumber
        );
        $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_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_AUTOREFERER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        $result = curl_exec($ch);
        header('Cache-Control: public');
        header('Content-type: application/pdf');
        header('Content-Disposition: attachment; filename="etykieta.pdf"');
        header('Content-Length: '.strlen($result));
        echo $result;

    }

    private function createPackageData($idOrder, $idOrderCarrier)
    {
        $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_carrier = '.$idOrderCarrier);
        $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);
        $address = $order[0];
        $ret['address'] = $address;
        return $ret;
    }

    private function loadCountryDetails($countryId)
    {
        $apiKey = $this->configuration->get('paxy_api_key');
        $apiSecret = $this->configuration->get('paxy_api_secret');
        $ch = curl_init();
        $endpoint = $this->paxyApiUrl . '/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 = $this->configuration->get('paxy_api_key');
        $apiSecret = $this->configuration->get('paxy_api_secret');
        $ch = curl_init();
        $fields = array( 'kraj' => $countryName);
        $postvars = '';
        foreach($fields as $key=>$value) {
            $postvars .= $key . "=" . $value . "&";
        }
        $url = $this->paxyApiUrl . '/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 createParcel($parcelData, $bookNumber, $category, $carrierCode, $order, $quantity)
    {
        $apiKey = $this->configuration->get('paxy_api_key');
        $apiSecret = $this->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'],
            'email' => '',
            'nrtelefonu' => $parcelData['address']['phone'],
            'waga' => round(($parcelData['weight']/$quantity), 1),
            'przewoznik' => $carrierCode,
            'doc_wz' => $order->id,
            'referencje' => $order->id,
            'ilosc' => $quantity
        );

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

        $postvars = '';
        foreach($fields as $key=>$value) {
            $postvars .= $key . "=" . $value . "&";
        }
        $url = $this->paxyApiUrl . '/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 loadCarrierDetails($carrierId)
    {
        $apiKey = $this->configuration->get('paxy_api_key');
        $apiSecret = $this->configuration->get('paxy_api_secret');
        $ch = curl_init();
        $endpoint = $this->paxyApiUrl . '/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 [];
    }
}
