<?php
//include_once dirname(__FILE__).'/../../classes/Condition.php';
require_once(_PS_MODULE_DIR_ . 'mbeshipping' . DIRECTORY_SEPARATOR . 'classes' . DIRECTORY_SEPARATOR . 'custom' . DIRECTORY_SEPARATOR . 'Ws.php');
require_once(_PS_MODULE_DIR_ . 'mbeshipping' . DIRECTORY_SEPARATOR . 'classes' . DIRECTORY_SEPARATOR . 'custom' . DIRECTORY_SEPARATOR . 'helper' . DIRECTORY_SEPARATOR . 'Data.php');
require_once(_PS_MODULE_DIR_ . 'mbeshipping' . DIRECTORY_SEPARATOR . 'classes' . DIRECTORY_SEPARATOR . 'custom' . DIRECTORY_SEPARATOR . 'helper' . DIRECTORY_SEPARATOR . 'Order.php');
require_once(_PS_MODULE_DIR_ . 'mbeshipping' . DIRECTORY_SEPARATOR . 'mbeshipping.php');

if (version_compare(_PS_VERSION_, '1.7.0.0', '<')) {
    require_once(_PS_MODULE_DIR_ . 'mbeshipping' . DIRECTORY_SEPARATOR . 'vendor/autoload.php');
}

use \iio\libmergepdf\Merger;
use \iio\libmergepdf\Driver\TcpdiDriver;

class AdminMbeShippingController extends ModuleAdminController
{
    public function __construct()
    {
        if (isset($_GET['creationorder'])) {
            $this->creationShipment();
        }

        if (isset($_GET['returnorder'])) {
            $this->creationReturnShipment();
        }

        if (isset($_GET['submitAction']) && $_GET['submitAction'] == 'generateDelivery') {
            $this->generateDelivery($_GET['id_order']);
        }

        if (_PS_VERSION_ >= 1.7) {
            $this->translator = Context::getContext()->getTranslator();
        }

        $dataHelper = new Mbe_Shipping_Helper_Data();
        $moduleInstance = new MbeShipping();

        $this->bootstrap = true;
        $this->table = 'order';
        $this->className = 'Order';
        $this->lang = false;
        $ws = new Mbe_Shipping_Model_Ws();
        $mustClose = $ws->mustCloseShipments();
        if ($mustClose) {
            if (Configuration::get('shipments_closure_mode') == Mbe_Shipping_Helper_Data::MBE_CLOSURE_MODE_MANUALLY) {
                $this->bulk_actions = array(
                    'sended' => array('text' => $moduleInstance->l('Close', 'AdminMbeShippingController'), 'confirm' => str_replace("'", "\'", $moduleInstance->l('Are you sure?', 'AdminMbeShippingController'))),
                );
            }
        }
        $this->addRowAction('detail');
        if (Configuration::get('shipments_creation_mode') == Mbe_Shipping_Helper_Data::MBE_CREATION_MODE_MANUALLY) {
            $this->addRowAction('creation');
            $this->bulk_actions['creation'] = array('text' => $moduleInstance->l('Creation', 'AdminMbeShippingController'), 'confirm' => str_replace("'", "\'", $moduleInstance->l('Do you want create shipments?', 'AdminMbeShippingController')));
        }
        $this->addRowAction('return');

        $this->bulk_actions['download'] = array('text' => $moduleInstance->l('Download', 'AdminMbeShippingController'), '');

        $this->allow_export = true;
        $this->list_no_link = true;
        $this->context = Context::getContext();
        $this->_select = 'a.date_add, oc.tracking_number, CONCAT(c.`firstname`, \' \', c.`lastname`) AS `customer`,o.`reference` , o.`id_order` AS `buttons`, o.`id_order` as status';
        $this->_join = ' LEFT JOIN `' . _DB_PREFIX_ . 'customer` c ON (c.`id_customer` = a.`id_customer`) ';
        $this->_join .= ' LEFT JOIN `' . _DB_PREFIX_ . 'orders` o ON (o.`id_order` = a.`id_order`) ';
        $this->_join .= ' INNER JOIN `' . _DB_PREFIX_ . 'order_carrier` oc ON (o.`id_order` = oc.`id_order`)';

        if( $dataHelper->isEnabledCustomMapping())
        {
            $customMapping = $dataHelper->getCustomMappingCarriers();
            $this->_join .= ' AND (oc.`id_carrier` IN (' . implode($customMapping,',') .') OR oc.`id_carrier` IN (SELECT `id_carrier` from `' . _DB_PREFIX_ . 'carrier` where `external_module_name` = "mbeshipping"))';
        }
        else {
            $this->_join .= ' AND oc.`id_carrier` IN (SELECT `id_carrier` from `' . _DB_PREFIX_ . 'carrier` where `external_module_name` = "mbeshipping")';
        }

        $this->_join .= ' INNER JOIN `' . _DB_PREFIX_ . 'carrier` ca ON (ca.`id_carrier` = oc.`id_carrier`)';
        $this->_where = 'AND (oc.tracking_number<>\'\' OR  o.current_state NOT IN (6))';
        $this->_defaultOrderBy = 'a.date_add';
        $this->_defaultOrderWay = 'DESC';

        $this->fields_list = array();

        $this->fields_list['reference'] = array(
            'title'      => $moduleInstance->l('Reference', 'AdminMbeShippingController'),
            'filter_key' => 'o!reference',
            'align'      => 'text-left');
        if ($mustClose) {
            $this->fields_list['status'] = array(
                'title'      => $moduleInstance->l('Status', 'AdminMbeShippingController'),
                'filter_key' => 'status',
                'callback'   => 'checkClose',
                'search'     => false,
                'orderby'    => false,
                'align'      => 'text-left');
        }
        $this->fields_list['customer'] = array(
            'title'        => $moduleInstance->l('Customer', 'AdminMbeShippingController'),
            'havingFilter' => true,
            'align'        => 'text-left');
        $this->fields_list['payment'] = array(
            'title'      => $moduleInstance->l('Payment', 'AdminMbeShippingController'),
            'filter_key' => 'o!payment',
            'align'      => 'text-left');
        $this->fields_list['date_add'] = array(
            'title'      => $moduleInstance->l('Request date', 'AdminMbeShippingController'),
            'align'      => 'text-right',
            'type'       => 'datetime',
            'filter_key' => 'a!date_add');
        $this->fields_list['total_paid_tax_incl'] = array(
            'title'      => $moduleInstance->l('Total', 'AdminMbeShippingController'),
            'filter_key' => 'o!total_paid_tax_incl',
            'align'      => 'text-center');
        $this->fields_list['id_carrier'] = array(
            'title'      => $moduleInstance->l('Carrier', 'AdminMbeShippingController'),
            'filter_key' => 'ca!name',
            'align'      => 'text-center',
            'callback'   => 'getCarrierName');
        $this->fields_list['tracking_number'] = array(
            'title'      => $moduleInstance->l('Tracking', 'AdminMbeShippingController'),
            //'filter' => false,
            //'search' => false,
            'orderby'    => true,
            'align'      => 'text-center',
            'callback'   => 'getTracking',
            'filter_key' => 'oc!tracking_number', 'AdminMbeShippingController',
        );
        $this->fields_list['buttons'] = array(
            'title'          => $moduleInstance->l('PDF', 'AdminMbeShippingController'),
            'align'          => 'text-center',
            'callback'       => 'printPDFIconsButton',
            'orderby'        => false,
            'search'         => false,
            'filter_key'     => 'o!id_order',
            'remove_onclick' => true);

        parent::__construct();
    }

    public function creationShipment()
    {
        $idOrder = Tools::getValue('id_order');
        if ($idOrder) {
            /**
             * @var $order OrderCore
             */
            $helper = new Mbe_Shipping_Helper_Data();
            $order = new Order($idOrder);
            $oc = $helper->getOrderCarrier($idOrder);

            $moduleInstance = new MbeShipping();

            if ($oc->tracking_number != '') {
                $this->errors[] = Tools::displayError($moduleInstance->l('The shipment was already created', 'AdminMbeShippingController'));
            }
            else {
                $service = Configuration::get('carrier_' . $order->id_carrier);
                if(!$service || $service==='')
                {
                    $carrier = new Carrier($order->id_carrier);
                    $service = $helper->getCustomMappingService($carrier->id);
                }
                $orderHelper = new Mbe_Shipping_Helper_Order();
                $errors = $orderHelper->addShipping($order, $service);
                //if (isset($order->_errors) && is_array($order->_errors) && count($order->_errors)) {
                if (isset($errors) && is_array($errors) && count($errors)) {
                    $this->errors = $errors;
                }
                else {
                    $this->confirmations[] = $moduleInstance->l('The shipment was successfully created', 'AdminMbeShippingController');
                }
            }
        }
    }

    public function creationReturnShipment()
    {
        $idOrder = Tools::getValue('id_order');
        if ($idOrder) {
            /**
             * @var $order OrderCore
             */
            $helper = new Mbe_Shipping_Helper_Data();
            $order = new Order($idOrder);
            $oc = $helper->getOrderCarrier($idOrder);

            $moduleInstance = new MbeShipping();

            if ($oc->tracking_number != '') {
                if(strpos($oc->tracking_number, 'RETURN') !== false) {
                    $this->confirmations[] = $moduleInstance->l('1 - Total of 1 return shipments were already created', 'AdminMbeShippingController');
                }
                else {
                    $orderHelper = new Mbe_Shipping_Helper_Order();
                    $errors = $orderHelper->addReturnShipping($order, $oc->tracking_number);
                    if (isset($errors) && is_array($errors) && count($errors)) {
                        $this->errors = $errors;
                    } else {
                        $this->confirmations[] = $moduleInstance->l('1 - Total of 1 return shipments created', 'AdminMbeShippingController');
                    }
                }
            }
        }
    }

    protected function processBulkCreation()
    {
        $moduleInstance = new MbeShipping();
        if (is_array($this->boxes) && !empty($this->boxes)) {
            $toCreationIds = array();
            $alreadyCreatedIds = array();
            foreach ($this->boxes as $idOrder) {
                $order = new Order($idOrder);
                $oc = new OrderCarrier($idOrder);
                if ($oc->tracking_number != '') {
                    array_push($alreadyCreatedIds, $idOrder);
                }
                else {
                    $service = Configuration::get('carrier_' . $order->id_carrier);
                    if(!$service || $service==='')
                    {
                        $helper = new Mbe_Shipping_Helper_Data();
                        $carrier = new Carrier($order->id_carrier);
                        $service = $helper->getCustomMappingService($carrier->id);
                    }
                    $orderHelper = new Mbe_Shipping_Helper_Order();
                    $errors = $orderHelper->addShipping($order, $service);
                    if (isset($errors) && is_array($errors) && count($errors)) {
                        $this->errors = $errors;
                    }
                    else {
                        array_push($toCreationIds, $idOrder);
                    }
                }
            }

            if (count($toCreationIds) > 0) {
                $this->confirmations[] = sprintf($moduleInstance->l('Total of %d shipment(s) have been created.', 'AdminMbeShippingController'), count($toCreationIds));
            }

            if (count($alreadyCreatedIds) > 1) {
                $this->errors[] = sprintf($moduleInstance->l('Total of %d shipment(s) was already created.', 'AdminMbeShippingController'), count($alreadyCreatedIds));
            }
        }
        else {
            $this->errors[] = Tools::displayError($moduleInstance->l('Please select items.', 'AdminMbeShippingController'));
        }
    }

    protected function processBulkSended()
    {
        $moduleInstance = new MbeShipping();

        if (is_array($this->boxes) && !empty($this->boxes)) {
            $toClosedIds = array();
            $alreadyClosedIds = array();

            $helper = new Mbe_Shipping_Helper_Data();

            $ws = new Mbe_Shipping_Model_Ws();


            foreach ($this->boxes as $shipmentId) {
                if ($helper->isShippingOpen($shipmentId)) {
                    array_push($toClosedIds, $shipmentId);
                    $tracks = $helper->getTrackings($shipmentId);
                }
                else {
                    array_push($alreadyClosedIds, $shipmentId);
                }
            }

            $ws->closeShipping($toClosedIds);


            if (!empty($tracks)) {
                $filePath = $helper->getTrackingFilePath(reset($tracks));
                if (file_exists($filePath)) {
                    $html = "<a target='_blank' href='" . __PS_BASE_URI__ . "modules/mbeshipping/pdf.php?files[]=" . $filePath . "'>" . $moduleInstance->l('here', 'AdminMbeShippingController') . "</a>";
                    $this->confirmations[] = sprintf($moduleInstance->l('To download file click %s.', 'AdminMbeShippingController'), $html);
                }
            }

            if (count($toClosedIds) > 0) {
                $this->confirmations[] = sprintf($moduleInstance->l('Total of %d shipment(s) have been closed.', 'AdminMbeShippingController'), count($toClosedIds));
            }

            if (count($alreadyClosedIds) > 1) {
                $this->confirmations[] = sprintf($moduleInstance->l('Total of %d shipment(s) was already closed.', 'AdminMbeShippingController'), count($alreadyClosedIds));
            }
        }
        else {
            $this->errors[] = Tools::displayError($moduleInstance->l('Please select items.', 'AdminMbeShippingController'));
        }
    }

    protected function processBulkDownload()
    {
        $moduleInstance = new MbeShipping();

        if (is_array($this->boxes) && !empty($this->boxes)) {
            $noTracking = array();
            $whitTracking = array();
            $helper = new Mbe_Shipping_Helper_Data();
            $orderHelper = new Mbe_Shipping_Helper_Order();
            $filenames = [];
            foreach ($this->boxes as $shipmentId) {
                if ($helper->hasTracking($shipmentId)) {
                    array_push($whitTracking, $shipmentId);

                    $order = new Order((int)$shipmentId);
                    if (!Validate::isLoadedObject($order)) {
                        throw new PrestaShopException('Can\'t load Order object');
                    }

                    $oc = $helper->getOrderCarrier($shipmentId);
                    $ts = explode(Mbe_Shipping_Helper_Data::MBE_SHIPPING_TRACKING_SEPARATOR, $oc->tracking_number);

                    foreach ($ts as $t) {
                        if(strpos($t, 'RETURN') == false) {
                            $filenames[] = $helper->getMediaPath() . $orderHelper->getFileName($order, $t);
                        }
                    }
                }
                else {
                    array_push($noTracking, $shipmentId);
                }
            }
            $labelsPdf = $helper->generateDeliveryForBulk($filenames);

            if (!empty($labelsPdf)) {
                $outputPdf     = $this->combineLabelsPdf($labelsPdf);
                $outputPdfPath = $helper->getMediaPath() . getdate()[0] . rand( 0, 999 ) . '.pdf';
                if ( file_put_contents( $outputPdfPath, $outputPdf ) !== false ) {
                    header( 'Content-Description: File Transfer' );
                    header( 'Content-Type: application/pdf' );
                    header( "Content-Disposition: attachment; filename=mbe-labels.pdf" );
                    header( 'Content-Transfer-Encoding: binary' );
                    header( 'Expires: 0' );
                    header( 'Cache-Control: must-revalidate, post-check=0, pre-check=0' );
                    header( 'Pragma: public' );
                    header( 'Content-Length: ' . filesize( $outputPdfPath ) );
                    if(ob_get_length() > 0) {
                        ob_clean();
                    }
                    flush();
                    readfile($outputPdfPath);
                    if(is_file($outputPdfPath))
                        unlink($outputPdfPath);
                   // exit;
                } else {
                    $errMess = __( 'MBE Download shipping labels - error writing to file ' . $outputPdfPath );
                    $this->logger->log( $errMess );
                }

             /*   if (count($noTracking) > 0) {
                    $this->confirmations[] = sprintf($moduleInstance->l('Total of %d shipment(s) have been closed.', 'AdminMbeShippingController'), count($noTracking));
                }

                if (count($whitTracking) > 1) {
                    $this->confirmations[] = sprintf($moduleInstance->l('Total of %d shipment(s) was already closed.', 'AdminMbeShippingController'), count($whitTracking));
                }*/
            } else {
               // $this->confirmations[] = sprintf($moduleInstance->l('MBE Download shipping labels - no label to download ', 'AdminMbeShippingController'), count($whitTracking));
            }
        }
        else {
            $this->errors[] = Tools::displayError($moduleInstance->l('Please select items.', 'AdminMbeShippingController'));
        }
    }

    public function combineLabelsPdf(array $labelsContent)
    {
        $outputPdf = new Merger(new TcpdiDriver());
        foreach ( $labelsContent as $item ) {
            $outputPdf->addRaw($item);
        }
        return $outputPdf->merge();
    }

    public function checkClose($value)
    {
        $helper = new Mbe_Shipping_Helper_Data();
        $moduleInstance = new MbeShipping;

        if ($helper->isShippingOpen($value)) {
            $label = $moduleInstance->l('Opened', 'AdminMbeShippingController');
        }
        else {
            $label = $moduleInstance->l('Closed', 'AdminMbeShippingController');
        }
        return $label;
    }

    public function printPDFIconsButton($id_order, $tr)
    {
        static $valid_order_state = array();
        $helper = new Mbe_Shipping_Helper_Data();

        $order = new Order($id_order);
        $order_carrier = $helper->getOrderCarrier($id_order);
        if (!Validate::isLoadedObject($order)) {
            return '';
        }

        if (!isset($valid_order_state[$order->current_state])) {
            $valid_order_state[$order->current_state] = Validate::isLoadedObject($order->getCurrentOrderState());
        }

        if (!$valid_order_state[$order->current_state]) {
            return '';
        }

        $href = '';

        $ws = new Mbe_Shipping_Model_Ws();
        $mustClose = $ws->mustCloseShipments();

        if ($mustClose) {

            if (ltrim($order_carrier->tracking_number) != '') {
                $arr = explode(Mbe_Shipping_Helper_Data::MBE_SHIPPING_TRACKING_SEPARATOR, ltrim($order_carrier->tracking_number));
                $t = reset($arr);
                if ($helper->getTrackingStatus($t) == Mbe_Shipping_Helper_Data::MBE_SHIPMENT_STATUS_CLOSED) {
                    $href = __PS_BASE_URI__ . 'modules/mbeshipping/pdf.php?files[]=' . $helper->getTrackingFilePath($t);
                }
            }
        }

        $this->context->smarty->assign(array(
            'order'         => $order,
            'order_carrier' => $order_carrier,
            'href'          => $href,
            'tr'            => $tr,
        ));

        if (version_compare(_PS_VERSION_, '1.6', '<')) {
            return $this->createTemplate('controllers/orders/_print_pdf_icon15.tpl')->fetch();
        }
        else {
            return $this->createTemplate('controllers/orders/_print_pdf_icon.tpl')->fetch();
        }
    }

    public function displayDetailLink($token, $id)
    {
        $controller = "AdminOrders";
        $identifier = "id_order";
        $table = "order";

//        // Code compliant from PrestaShop 1.5 to 1.7.4
//        $link->getAdminLink('AdminOrders') . '&amp;id_order={$order->id|intval}&amp;vieworder';
//
//        // Recommended code from PrestaShop 1.7.5
//        $link->getAdminLink('AdminOrders', true, [], ['id_customer' => $customer->id|intval, 'viewcustomer' => 1]);
//
//        // If you need to be compatible from 1.5 to the latest 1.7 version, then you can combine both styles
//        $link->getAdminLink('AdminOrders', true, [], ['id_customer' => $customer->id|intval, 'viewcustomer' => 1]) . '&amp;id_order={$order->id|intval}&amp;vieworder';

        //The link is created in such a way as to be compatible with both new and old versions as reported in the comment above
        $url = $this->context->link->getAdminLink($controller, true, [], [ 'id_order' => $id, 'vieworder' => 1]). '&' . $identifier . '=' . $id . '&view' . $table;

        $tpl = $this->createTemplate('list_action_detail.tpl');
        $moduleInstance = new MbeShipping();
        $tpl->assign(array(
            'href'   => $url,
            'action' => $moduleInstance->l('Show', 'AdminMbeShippingController'),
        ));

        return $tpl->fetch();
    }

    public function displayCreationLink($token, $id)
    {
        $controller = "AdminMbeShipping";
        $identifier = "id_order";
        $table = "order";

        $url = $this->context->link->getAdminLink($controller) . '&' . $identifier . '=' . $id . '&creation' . $table;

        $helper = new Mbe_Shipping_Helper_Data();

        $tpl = $this->createTemplate('list_action_creation.tpl');
        $moduleInstance = new MbeShipping();
        $tpl->assign(array(
            'href'   => $url,
            'action' => $moduleInstance->l('Create shipment', 'AdminMbeShippingController'),
        ));

        return $tpl->fetch();
    }

    public function displayReturnLink($token, $id)
    {
        $controller = "AdminMbeShipping";
        $identifier = "id_order";
        $table = "order";

        $url = $this->context->link->getAdminLink($controller) . '&' . $identifier . '=' . $id . '&return' . $table;

        $helper = new Mbe_Shipping_Helper_Data();
        $wsdl = $helper->getWsUrl();
        $isOnlineMBE = false;
        if (strpos(strtolower($wsdl),'onlinembe') == false) {
            $tpl = $this->createTemplate('list_action_return.tpl');
            $moduleInstance = new MbeShipping();
            $tpl->assign(array(
                'href' => $url,
                'action' => $moduleInstance->l('Create return shipment', 'AdminMbeShippingController')
            ));
            return $tpl->fetch();
        }
    }


    public function getTracking($value)
    {
        $values = explode(Mbe_Shipping_Helper_Data::MBE_SHIPPING_TRACKING_SEPARATOR, $value);
        $html = '';
        foreach ($values as $v) {
            $html .= $v . "</br>";
        }
        return $html;
    }

    public function generateDelivery($id_order)
    {
        $helper = new Mbe_Shipping_Helper_Data();
        $orderHelper = new Mbe_Shipping_Helper_Order();
        $order = new Order((int)$id_order);;
        if (!Validate::isLoadedObject($order)) {
            throw new PrestaShopException('Can\'t load Order object');
        }

        $oc = $helper->getOrderCarrier($id_order);
        $ts = explode(Mbe_Shipping_Helper_Data::MBE_SHIPPING_TRACKING_SEPARATOR, $oc->tracking_number);

        foreach ($ts as $t) {
            if(strpos($t, 'RETURN') == false) {
                $filenames[] = $helper->getMediaPath() . $orderHelper->getFileName($order, $t);
            }
        }

        $helper->generateDelivery($filenames);
    }

    public function getShipmentStatus($value)
    {
        $carrier = new Carrier($value);
        return $carrier->name;
    }

    public function getCarrierName($value)
    {
        $carrier = new Carrier($value);
        return $carrier->name;
    }

}
