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

class InpostPackages extends Module
{

    public $name = 'inpost';
    const FILE = 'inpostpackages';

    public function __construct()
    {
        parent::__construct();
    }

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

        return true;
    }

    private function prepareFilters($data, $pushDataToPost = true)
    {
        if (!isset($data['submitResetinpost_packages']) || !$data['submitResetinpost_packages']) {
            if (isset($data['submitFilterinpost_packages'])) {
                $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_packages_filter'][$key] = $value;
            }
        }

        return true;
    }

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

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

        return true;
    }

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

        $this->resetFilters();
        $this->defaultSelectedFilters();
        $filtersPackage = $this->filterPackages(false);
        if ($filtersPackage) {
            $sql .= ' WHERE '.$filtersPackage;
        }
        $total = Db::getInstance()->getValue($sql);
        return $total;
    }

    public function getListContent($orderBy, $orderWay, $data, $limit, $start = 0)
    {

        $sql = 'SELECT iiplo.x_border, iico.name as country, iip.*, iil.package_id, iil.label_downloaded, iil.date_label_generation FROM '._DB_PREFIX_.'inpost_packages iip LEFT JOIN '._DB_PREFIX_.'country_lang iico on iico.id_country=iip.receiver_country  LEFT JOIN '._DB_PREFIX_.'inpost_labels iil on iip.parcel_no=iil.package_id LEFT JOIN '._DB_PREFIX_.'inpost_parcel_lockers_orders iiplo on iip.order_id=iiplo.order_id WHERE id_lang ='.Context::getContext()->language->id;

        $filtersPackage = $this->filterPackages($data);

        if ($filtersPackage) {
            $sql .= ' AND '. $filtersPackage;
        }
        $sql.= ' GROUP BY iip.parcel_no ';
        if ($orderBy) {
            if ($orderBy == 'receiver') {
                $orderBy = 'receiver_firstname';
            } elseif ($orderBy == 'address') {
				$orderBy = "receiver_street $orderWay, receiver_building_no $orderWay, receiver_flat_no ";
			} elseif ($orderBy == 'label_generated') {
				$orderBy = 'iil.package_id IS NOT NULL';
			}
            $sql.= ' order by '.$orderBy;
        }
        if ($orderWay) {
            $sql.= ' '.$orderWay;
        }

        if ($limit) {
            $sql .= ' LIMIT '.$limit;
        }
        if ($start) {
            $sql .= ' OFFSET '.$start;
        }

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

        foreach ($packages as &$package) {

            if ((int)$package['x_border'] === 1) {
              $package['parcel_no_for_show'] = $package['tracking_number'];
            }
            $package['receiver'] = $package['receiver_firstname'].' '.$package['receiver_lastname'];
            $package['label_generated'] = $package['date_label_generation'] ? true : false;
            $package['date_parcel_generation'] = $package['created_at'];
            $package['postcode'] = $package['receiver_post_code'];
            $package['city'] = $package['receiver_city'];
            $package['country'] = InpostModel::getCountryNameById($package['receiver_country']);
            $package['address'] = $package['receiver_street'].' '.$package['receiver_building_no'].' '.$package['receiver_flat_no'];
        }

        return $packages;

    }


    public function generateTablePackages()
    {

        $helper = new HelperList();

        $helper->actions = array('edit');
        $helper->orderBy = Tools::getValue('inpost_packagesOrderby');

        $helper->orderWay = Tools::strtoupper(Tools::getValue('inpost_packagesOrderway'));
        $helper->simple_header = false;
        $helper->identifier = 'parcel_no';
        $helper->show_toolbar = true;
        $helper->title = 'Packages';
        $helper->table = $this->name.'_packages';
        $helper->shopLinkType = '';
        $helper->token = Tools::getAdminTokenLite('AdminModules');
        $helper->currentIndex = AdminController::$currentIndex.'&configure='.$this->name.'&packages';

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

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

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

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

        $content = $this->getListContent($helper->orderBy, $helper->orderWay, $_POST, $pagination, $start);
        $helper->listTotal= $this->getPackagesCount();
        $this->context->smarty->assign(array(
            'total' => $helper->listTotal
        ));

        if ($helper->listTotal > 0) {
            $helper->bulk_actions = array(
                'delete' => array(
                    'text' => $this->l('Cancel selected', self::FILE),
                    'confirm' => $this->l('Cancel selected packages?', self::FILE),
                    'icon' => 'icon-trash'
                )
            );
        }
        return $helper->generateList($content, $this->renderList());
    }

    public function renderList()
    {
        return array(
            'created_at' => array(
                'title' => $this->l('Parcel creation date', self::FILE),
                'width' => 'auto',
                'type' => 'datetime',
                'ajax' => true,

            ),
            'order_id' => array(
                'title' => $this->l('Order No.', self::FILE),
            ),
//            'parcel_no_for_show' => array(
//                'title' => $this->l('Parcel No.', self::FILE),
//                'type' => 'text',
//                'havingFilter' => true,
//            ),
            'parcel_no' => array(
                'title' => $this->l('Parcel No.', self::FILE),
                'type' => 'text',
                'havingFilter' => true,
                'class' => 'to_hide'
            ),
            'receiver' => array(
                'title' => $this->l('Receiver', self::FILE),
                'type' => 'text',
            ),
            'country' => array(
                'title' => $this->l('Country', self::FILE),
                'type' => 'text'
            ),
            'receiver_post_code' => array(
                'title' => $this->l('Postal code', self::FILE),
                'type' => 'text'
            ),
            'receiver_city' => array(
                'title' => $this->l('City', self::FILE),
                'type' => 'text'
            ),
            'address' => array(
                'title' => $this->l('Address', self::FILE),
                'type' => 'text'
            ),
            'label_generated' => array(
                'title' => $this->l('Label generated', self::FILE),
                'type' => 'bool',
                'active' => 'label_generated',
                'class' => 'label_generated_class',
                'align' => 'center'

            ),
        );
    }
    public function resetFilters()
    {
        if (Tools::isSubmit('submitResetinpost_packages')) {
            $_POST['inpost_packagesFilter_date_parcel_generation'][0] = '';
            $_POST['inpost_packagesFilter_date_parcel_generation'][1] = '';
            $_POST['inpost_packagesFilter_created_at'][0] = '';
            $_POST['inpost_packagesFilter_created_at'][1] = '';
            $_POST['inpost_packagesFilter_label_generated'] = '';
            $_POST['inpost_packagesFilter_parcel_no'] = '';
            $_POST['inpost_packagesFilter_country'] = '';
            $_POST['inpost_packagesFilter_postcode'] = '';
            $_POST['inpost_packagesFilter_city'] = '';
            $_POST['inpost_packagesFilter_address'] = '';
            $_POST['inpost_packagesFilter_receiver'] = '';
            $_POST['inpost_packagesFilter_order_id'] = '';

            $this->removeFiltersFromSession();
        }
    }

    public function defaultSelectedFilters()
    {
//        if (!Tools::getValue('inpost_packagesFilter_label_generated') && !Tools::getValue('inpost_packagesOrderby'))

        if (!Tools::getValue('inpost_packagesFilter_created_at') && !$this->getFiltersFromSession()) {
            $_POST['inpost_packagesFilter_created_at'][0] = date('Y-m-d'); //show not downloaded label defaultowo
            $_POST['inpost_packagesFilter_created_at'][1] = ''; //show not downloaded label defaultowo
            $_POST['submitFilter'] = '';
        }
    }
    public function filterPackages($pushDataToPost = true)
    {
        $data = $this->prepareFilters($_POST, $pushDataToPost);

        $filter = [];
        $filter[] = 'iip.status <> "cancelled"';//Dont display packages with canceleld status
        if (isset($data['inpost_packagesFilter_order_id']) && (int)$data['inpost_packagesFilter_order_id']) {
            $filter[] = 'iip.order_id = '.pSQL($data['inpost_packagesFilter_order_id']);
        }

        if (isset($data['inpost_packagesFilter_parcel_no']) && (int)$data['inpost_packagesFilter_parcel_no']) {
            $filter[] = 'parcel_no like "%'.pSQL($data['inpost_packagesFilter_parcel_no']).'%"';
        }

        if (isset($data['inpost_packagesFilter_receiver']) && $data['inpost_packagesFilter_receiver']) {
            $filterCustomer = [];
            $customers = Db::getInstance()->executeS("
              SELECT id_customer
              FROM "._DB_PREFIX_."address
              WHERE CONCAT_WS(' ', firstname, lastname)
              LIKE '%".pSQL($data['inpost_packagesFilter_receiver'])."%'");

            if ($customers) {
                foreach ($customers as $customer) {
                    $filterCustomer[] = $customer['id_customer'];
                }
            } else {
                //brak wyszukiwany customersow zwracam pusta tablice
                return array();
            }

            if ($filterCustomer) {
                $filter[] = ' receiver_id IN('.implode(',', $filterCustomer).')';
            }

        }

        if (isset($data['inpost_packagesFilter_country']) && $data['inpost_packagesFilter_country']) {
            $countryId = InpostModel::getCountryIdByName(pSQL($data['inpost_packagesFilter_country']));

            $filter[] = 'receiver_country ='.$countryId;
        }

        if (isset($data['inpost_packagesFilter_postcode']) && $data['inpost_packagesFilter_postcode']) {
            $filter[] = 'postcode='.pSQL($data['inpost_packagesFilter_postcode']);
        }

        if (isset($data['inpost_packagesFilter_created_at'][0]) && $data['inpost_packagesFilter_created_at'][0]) {
            $filter[] = 'created_at >= "'.pSQL($data['inpost_packagesFilter_created_at'][0]).' 00:00:01"';
        }
        if (isset($data['inpost_packagesFilter_created_at'][1]) && $data['inpost_packagesFilter_created_at'][1]) {
            $filter[] = 'created_at <= "'.pSQL($data['inpost_packagesFilter_created_at'][1]).' 23:59:59"';
        }
        if (isset($data['inpost_packagesFilter_label_generated'])) {
            if (!Tools::isSubmit('submitResetinpost_packages')) {
                if ($data['inpost_packagesFilter_label_generated'] == false
                    && $data['inpost_packagesFilter_label_generated'] !== '') {
                    $filter[] = 'iil.package_id IS NULL';
                } elseif ((bool)$data['inpost_packagesFilter_label_generated'] === true) {
                    $filter[] = 'iil.package_id IS NOT NULL';
                }
            }
        }
        if (isset($data['inpost_packagesFilter_city']) && $data['inpost_packagesFilter_city']) {
            $filter[] = "iip.receiver_city like '%".pSQL($data['inpost_packagesFilter_city'])."%'";
        }
        if (isset($data['inpost_packagesFilter_address']) && $data['inpost_packagesFilter_address']) {
            $filter[] = "CONCAT_WS('', iip.receiver_street, iip.receiver_building_no)
            LIKE '%".pSQL($data['inpost_packagesFilter_address'])."%'";
        }

        if ($filter) {
            return implode(' AND ', $filter);
        }
        return false;
    }

    public function renderPackagesActions()
    {
        if (version_compare(_PS_VERSION_, '1.6', '<')) {
            return $this->context->smarty->fetch(INPOST_TPL_DIR.'admin/1.5/packages_actions.tpl');
        }

        return $this->context->smarty->fetch(INPOST_TPL_DIR.'admin/packages_actions.tpl');
    }

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

    public function cancelParcels()
    {
        $data = $_POST;
        $api = new InpostConnector();
        $errors = [];
        if (isset($data['inpost_packagesBox'])) {
            foreach ($data['inpost_packagesBox'] as $package) {
                $response = $api->cancelParcel($package);

                if ($response->status_code == 422) {
                    $errors[] = $response->message;
                } else {
                    self::changeParcelStatus($package, $response->status);
                }
            }
        }
        return $errors;
    }

    public static function changeParcelStatus($package, $status, $tracking_number = false)
    {
        Db::getInstance()->update('inpost_packages', array(
            'status' => pSQL($status),
        ), 'parcel_no="'.$package.'"');
        if ($tracking_number) {
          Db::getInstance()->update('inpost_packages', array(
              'tracking_number' => pSQL($tracking_number),
          ), 'parcel_no="'.$package.'"');
        }
    }

    public static function deletePackage($package)
    {
        Db::getInstance()->delete('inpost_packages', 'package_id="'.(string)$package.'"', 1);
    }
}
