<?php
/**
 * 2016 Eengine Sp. z o.o.
 *
 * NOTICE OF LICENSE
 *
 */
if (!defined('_PS_VERSION_')) {
    exit;
}

class InpostLabels extends Module
{
    public $name = 'inpost';
    public $keys = ['date_label_generation', 'order_id', 'parcel_no', 'label_no', 'label_downloaded'];
    const FILE = 'inpostlabels';
    public function __construct()
    {
        parent::__construct();
    }

    private function initSession()
    {
        if(!isset($_SESSION)) {
            session_start();
        }

        return true;
    }

    private function prepareFilters($data, $pushDataToPost = true)
    {
        if (!isset($data['submitResetinpostLabels']) || !$data['submitResetinpostLabels']) {
            if (isset($data['submitFilterinpostLabels'])) {
                $this->saveFiltersInSession($data);
            } else {
                if ($dataFromSession = $this->getFiltersFromSession()) {
                    $data = $dataFromSession;
                }
            }
        } else {
            $this->removeFiltersFromSession();
        }

        if($pushDataToPost) {
            foreach($data as $key => $value) {
                $_POST[$key] = $value;
            }
        }

        return $data;
    }

    private function saveFiltersInSession($data)
    {
        $this->initSession();

        $this->removeFiltersFromSession();

        $excludes = array(
            'submitResetinpost_packages',
            'submitFilterinpost_packages',

            'submitFilterinpostLabels',
            'submitResetinpostLabels'
        );

        foreach($data as $key => $value) {
            if(!in_array($key, $excludes)) {
                $_SESSION['ee_inpost_labels_filter'][$key] = $value;
            }
        }

        return true;
    }

    private function getFiltersFromSession()
    {
        $this->initSession();
        return isset($_SESSION['ee_inpost_labels_filter']) ? $_SESSION['ee_inpost_labels_filter'] : null;
    }

    private function removeFiltersFromSession()
    {
        $this->initSession();
        unset($_SESSION['ee_inpost_labels_filter']);

        return true;
    }

    public function generateTableLabels()
    {
        $this->fields_list = array(
            'date_label_generation' => array(
                'title' => $this->l('Label date generated', self::FILE),
                'type' => 'datetime',
            ),
            'order_id' => array(
                'title' => $this->l('Order No.', self::FILE)
            ),
            'package_id' => array(
                'title' => $this->l('Parcel No.', self::FILE),
                'type' => 'text',
            ),
            'label_downloaded' => array(
                'title' => $this->l('Label downloaded', self::FILE),
                'type' => 'bool',
                'active' => 'label_downloaded',
                'class' => 'text-center'
            ),
            'label_send' => array(
                'title' => $this->l('Show sent', self::FILE),
                'type' => 'bool',
                'active' => 'label_send',
                'class' => 'text-center'
            ),
        );

        $helper = new HelperList();

        $helper->orderBy = Tools::getValue('inpostLabelsOrderby');
        $helper->orderWay = Tools::strtoupper(Tools::getValue('inpostLabelsOrderway'));

        $helper->identifier = 'package_id';
        $helper->show_toolbar = false;
        $helper->title = 'Labels';
        $helper->table = $this->name.'Labels';
        $helper->shopLinkType = '';
        $helper->token = Tools::getAdminTokenLite('AdminModules');
        $helper->actions = [''];
        $helper->currentIndex = AdminController::$currentIndex.'&configure='.$this->name.'&labels';



        $this->resetFilters();
        $this->defaultSelectedFilters();

        if (version_compare(_PS_VERSION_, '1.6', '<')) {
            $page = (int)Tools::getValue('submitFilterLabels');
        } else {
            $page = (int)Tools::getValue('submitFilterinpostLabels');
        }

        if (!$page) {
            $page = 1;
        }
        $pagination = (int)Tools::getValue('inpostLabels_pagination', 50);

        if (!$page) {
            $page = 1;
        }

        $start = ($pagination * $page) - $pagination;


        $content = $this->getListContent($helper->orderBy, $helper->orderWay, $pagination, $start);

        $helper->listTotal= $this->getLabelsCount();
        $this->context->smarty->assign(array(
            'total' => $helper->listTotal
        ));

        if ($helper->listTotal > 0) {
            $helper->bulk_actions = array(
                'download_labels' => array('text' => $this->l('Download selected labels', self::FILE))
            );
        }
        return $helper->generateList($content, $this->fields_list);
    }

    public function getLabelsCount()
    {
        $sql = "SELECT COUNT(parcel_no) FROM "._DB_PREFIX_."inpost_labels iil LEFT JOIN "._DB_PREFIX_."inpost_packages iip on iil.package_id=iip.parcel_no";

        $this->resetFilters();
        $this->defaultSelectedFilters();
        $filtersLabels = $this->filterLabels(false);

        if ($filtersLabels) {
            $sql .= ' '.$filtersLabels;
        }

        $total = Db::getInstance()->getValue($sql);
        return $total;
    }

    public function getListContent($orderBy = '', $orderWay = 'ASC', $limit = 50, $start = 0)
    {
        $sql = "SELECT iil.*, iip.status, iip.tracking_number FROM "._DB_PREFIX_."inpost_labels iil LEFT JOIN "._DB_PREFIX_."inpost_packages iip on iil.package_id=iip.parcel_no";

        $filtersLabels = $this->filterLabels();

        if ($filtersLabels) {
            $sql .= ' '.$filtersLabels;
        }

        if ($orderBy) {
            $sql.= ' order by '.$orderBy;
        }
        if ($orderWay) {
            $sql.= ' '.$orderWay;
        }
        if ($limit) {
            $sql .= ' LIMIT '.$limit;
        }
        if ($start) {
            $sql .= ' OFFSET '.$start;
        }

        $labels = Db::getInstance()->executeS($sql);

        foreach ($labels as &$label) {
            $status = Db::getInstance()->getRow('SELECT iip.status, iil.courier_id FROM '._DB_PREFIX_.'inpost_packages iip LEFT JOIN '._DB_PREFIX_.'inpost_labels iil ON iip.parcel_no=iil.package_id  WHERE parcel_no = "'.$label['package_id'].'"');

            if ($status['status'] !== 'prepared' || $status['courier_id'] != null) {
                $label['label_send'] = true;
            } else {
                $label['label_send'] = false;
            }
            if ($label['tracking_number']) {
                $label['package_id'] = $label['tracking_number'];
            }
        }
        return $labels;
    }

    public function filterLabels($pushDataToPost = true)
    {
        $data = $this->prepareFilters($_POST, $pushDataToPost);

        $filters = [];
        if (isset($data['inpostLabelsFilter_order_id']) && (int)$data['inpostLabelsFilter_order_id']) {
            $filters[] = 'iip.order_id= '.pSQL($data['inpostLabelsFilter_order_id']);
        }

        if (isset($data['inpostLabelsFilter_parcel_no']) && $data['inpostLabelsFilter_parcel_no']) {
            $filters[] = 'parcel_no= '.pSQL($data['inpostLabelsFilter_parcel_no']);
        }

        if (isset($data['inpostLabelsFilter_label_no']) && (int)$data['inpostLabelsFilter_label_no']) {
            $filters[] = 'label_no= '.pSQL($data['inpostLabelsFilter_label_no']);
        }

        if(isset($data['inpostLabelsFilter_label_downloaded'])) {
            if ($data['inpostLabelsFilter_label_downloaded'] === "0") {
                $filters[] = 'label_downloaded = '.pSQL($data['inpostLabelsFilter_label_downloaded']);
            } elseif ($data['inpostLabelsFilter_label_downloaded'] === "1") {
                $filters[] = 'label_downloaded = 1';
            }
        }
        if (isset($data['inpostLabelsFilter_package_id']) && (int)$data['inpostLabelsFilter_package_id']) {
            $filters[] = 'package_id like  "%'.pSQL($data['inpostLabelsFilter_package_id']).'%"';
        }
        if (isset($data['inpostLabelsFilter_date_label_generation'][0]) && $data['inpostLabelsFilter_date_label_generation'][0]) {
            $filters[] = 'date_label_generation >= "'.pSQL($data['inpostLabelsFilter_date_label_generation'][0]).' 00:00:01"';
        }
        if (isset($data['inpostLabelsFilter_date_label_generation'][1]) && $data['inpostLabelsFilter_date_label_generation'][1]) {
            $filters[] = 'date_label_generation <= "'.pSQL($data['inpostLabelsFilter_date_label_generation'][1]).' 23:59:59"';
        }

        if(isset($data['inpostLabelsFilter_label_send'])) {
            if ($data['inpostLabelsFilter_label_send'] === "1") {
                $filters[] = '(iip.status != "prepared" OR iil.courier_id IS NOT NULL)';
            } elseif ($data['inpostLabelsFilter_label_send'] === "0") {
                $filters[] = 'iip.status = "prepared" AND iil.courier_id IS NULL';
            }
        }

        if ($filters) {
            return ' WHERE '.implode(' AND ', $filters);
        }
        return false;
    }

    public function renderLabelsActions()
    {
        $this->context->smarty->assign(
            array(
                'label_send' => (int)Tools::getValue('inpostLabelsFilter_label_send')
            )
        );
        if (version_compare(_PS_VERSION_, '1.6', '<')) {
            return $this->context->smarty->fetch(INPOST_TPL_DIR.'admin/1.5/labels_actions.tpl');
        } else {
            return $this->context->smarty->fetch(INPOST_TPL_DIR.'admin/labels_actions.tpl');
        }
    }

    public function pagination($pagination_helper)
    {
        $pagination = 50;
        if (in_array((int)Tools::getValue('inpostLabels_pagination'), $pagination_helper)) {
            $pagination = (int)Tools::getValue('inpostLabels_pagination');
        } elseif (isset($this->context->cookie->inpostLabels_pagination) && $this->context->cookie->inpostLabels_pagination) {
            $pagination = $this->context->cookie->inpostLabels_pagination;
        }
        return $pagination;
    }

    public function resetFilters()
    {
        if (Tools::isSubmit('submitResetinpostLabels')) {
            $_POST['inpostLabelsFilter_date_label_generation'][0] = '';
            $_POST['inpostLabelsFilter_date_label_generation'][1] = '';
            $_POST['inpostLabelsFilter_order_id'] = '';
            $_POST['inpostLabelsFilter_parcel_no'] = '';
//            $_POST['inpostLabelsFilter_label_no'] = '';
            $_POST['inpostLabelsFilter_label_downloaded'] = '';
            $_POST['inpostLabelsFilter_package_id'] = '';
            $_POST['inpostLabelsFilter_label_send'] = '';
            $this->context->cookie->inpostLabelsFilter_label_downloaded = 0;
            $this->context->cookie->inpostLabelsFilter_order_id = null;
            $this->context->cookie->inpostLabelsFilter_parcel_no = null;
            $this->context->cookie->inpostLabelsFilter_label_no = null;
            $this->context->cookie->inpostLabelsFilter_label_downloaded = null;

            $this->removeFiltersFromSession();
        }
    }
    public function downloadStickers($data = false)
    {
        $api = new InpostConnector();
        $x_api = new CrossBorderConnector();
        if (!$data) {
            $data = $_POST;
        }

        if (!isset($data['inpostLabelsBox'])) {
            return false;
        }
        require_once(_INPOST_TOOLS_DIR_.'pdf_merge/PDFMerger.php');
        $pdf = new PDFMerger();
        $file = false;


        foreach ($data['inpostLabelsBox'] as $label) {
            if (!$label) {
                continue;
            }

            if (file_exists(_PS_MODULE_DIR_."inpost/pdf/$label.pdf") && (int)filesize(_PS_MODULE_DIR_."inpost/pdf/$label.pdf") > 0) {
                $pdf->addPDF(_PS_MODULE_DIR_."inpost/pdf/$label.pdf");
                InpostModel::updateLabel($label);
                $idPackageX = Db::getInstance()->getValue("SELECT parcel_no FROM "._DB_PREFIX_."inpost_packages WHERE tracking_number = '".$label."'");

               if ($idPackageX) {
                 InpostModel::updateLabel($idPackageX);
               }

                $file = true;
            } else {
                $a = $api->createSticker($label);
                if ($a && !isset($a['error'])) {
                  $pdf->addPDF(_PS_MODULE_DIR_."inpost/pdf/$label.pdf");
                  InpostModel::updateLabel($label);
                  $file = true;
                } else {
                  $idLabelX = Db::getInstance()->getValue("SELECT parcel_no FROM "._DB_PREFIX_."inpost_packages WHERE tracking_number = '".$label."'");
                  $labelX = $x_api->getLabelPdf($label);
                  if (!$labelX) {
                    $labelX = $x_api->getLabelPdf($idLabelX);
                  }
                  if ($labelX) {
                    $x_file = $x_api->createSticker($labelX, $label);
                    if ($x_file) {
                      $pdf->addPDF(_PS_MODULE_DIR_."inpost/pdf/$label.pdf");

                      $file = true;
                    }
                  }
                }
            }
        }

        if ($file) {
            $pdf->merge('download', 'InPost' . date('Y-m-d-H-i') . '.pdf');
            exit;

        }
        return false;

    }
    public function defaultSelectedFilters()
    {
//        if (!Tools::getValue('inpostLabelsFilter_label_send'))
//        {
//            $_POST['inpostLabelsFilter_label_send'] = "0";
//            $_POST['submitFilter'] = '';
//        }
//
//
//        if (Tools::getValue('inpostLabelsFilter_label_downloaded') !== '' && Tools::getValue('inpostLabelsFilter_label_downloaded') !== '1')
//        {

        if (!Tools::getValue('inpostLabelsFilter_date_label_generation') && !$this->getFiltersFromSession()) {
            $_POST['inpostLabelsFilter_date_label_generation'][0] = date('Y-m-d'); //show not downloaded label defaultowo
            $_POST['inpostLabelsFilter_date_label_generation'][1] = ''; //show not downloaded label defaultowo
            $_POST['submitFilter'] = '';
        }
    }

    public function generateSticker()
    {
        $api = new InpostConnector();
        $x_api = new CrossBorderConnector();

        $data = $_POST;
        $returns = [];
        if (isset($data['inpost_packagesBox'])) {
            foreach ($data['inpost_packagesBox'] as $package) {
                $packageD = InpostModel::findPackageByPackageId($package);
                $apiPackage = $api->getParcel($package);

                if (!$packageD['x_border'] && $apiPackage->status == 'cancelled') {
                    return ['error' => 1, 0 => sprintf($this->l('Packages: %s have a status cancelled.', self::FILE), $apiPackage->id)];
                }
            }

            foreach ($data['inpost_packagesBox'] as $package) {
                $packageD = InpostModel::findPackageByPackageId($package);
                $apiPackageX = $x_api->getShipment($packageD['parcel_no']);

                if ((int)$packageD['x_border'] === 1 || $apiPackageX) {
                    InpostModel::addTrackingNumberToShipment($packageD['parcel_no'], $apiPackageX->tracking_number);
                    $label = $x_api->getLabelPdf($packageD['parcel_no']);

                    if ($label[0]->pdf_url !== null) {
                        $createSticker = $x_api->createSticker($label, $apiPackageX->tracking_number);

                        InpostModel::saveSticker($apiPackageX, $packageD['order_id'], false);
                        $returns[] = [
                            'package_id' => $apiPackageX->tracking_number,
                            'order_id' => $packageD['order_id']
                        ];
                    } elseif ($apiPackageX->status->code == 'Rejected') {
                        return ['error' => 1, 0 => sprintf($this->l('Packages: %s have a status rejected', self::FILE), $apiPackageX->id)];
                    } else {
                        return ['error' => 1, 0 => sprintf($this->l('Label for packages: %s is not ready', self::FILE), $apiPackageX->id)];
                    }

                } else {
                    $apiPackage = $api->getParcel($package);

                    if ($apiPackage->status !== 'cancelled') {
                        $api->payForParcel($package);
                        $createSticker = $api->createSticker($package);
                        if (isset($createSticker['error'])) {
                            return $createSticker;
                        }
                        $package = $api->getParcel($package);
                        InpostPackages::changeParcelStatus($package->id, $package->status);
                        InpostModel::saveSticker($apiPackage, $packageD['order_id'], false);
                        $returns[] = [
                            'package_id' => $apiPackage->id,
                            'order_id' => $packageD['order_id']
                        ];
                    }
                }
            }
        }
        return $returns;
    }

    public static function updateCourierId($parcels, $courier_id)
    {
        return Db::getInstance()->update('inpost_labels', array(
                'courier_id' => $courier_id
            ), 'package_id IN("'.implode('","', $parcels).'")');
    }
    public static function getCourierLabels($courier_id)
    {
        return Db::getInstance()->executeS("SELECT * FROM "._DB_PREFIX_."inpost_labels WHERE courier_id =".$courier_id);
    }
}
