<?php
/**
* 2007-2022 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    4webs <info@4webs.es>
*  @copyright 2022 4webs
*  @license   http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
*  International Registered Trademark & Property of PrestaShop SA
*/

require_once _PS_MODULE_DIR_ . 'hipercalzado/classes/HipercalzadoUtils.php';
require_once _PS_MODULE_DIR_ . 'hipercalzado/classes/HipercalzadoOrder.php';
require_once _PS_MODULE_DIR_ . 'hipercalzado/classes/HipercalzadoOrderProduct.php';

if (!defined('_PS_VERSION_')) {
    exit;
}

class Hipercalzado extends Module
{
    protected $config_form = false;
    public $configuration;

    public function __construct()
    {
        $this->name = 'hipercalzado';
        $this->tab = 'administration';
        $this->version = '1.0.1';
        $this->author = '4webs';
        $this->module_key = '8e80430a721d4364e6b2f173975163e8';
        $this->need_instance = 0;

        /**
         * Set $this->bootstrap to true if your module is compliant with bootstrap (PrestaShop 1.6)
         */
        $this->bootstrap = true;

        parent::__construct();

        $this->displayName = $this->l('Hipercalzado');
        $this->description = $this->l('This module connects with API from Hipecalzado an syncronize the orders');

        $this->configuration = json_decode(
            Configuration::get(
                $this->name . '_CONFIGURATION',
                null,
                Context::getContext()->shop->id_shop_group,
                (int)Context::getContext()->shop->id
            )
        );

        //Create a template configuration if it's empty
        if ($this->configuration == null) {
            Configuration::updateValue(
                $this->name . '_CONFIGURATION',
                HipercalzadoUtils::buildInnitialConfiguration(),
                null,
                Context::getContext()->shop->id_shop_group,
                (int)Context::getContext()->shop->id
            );
             $this->configuration = json_decode(
                Configuration::get(
                    $this->name . '_CONFIGURATION',
                    null,
                    Context::getContext()->shop->id_shop_group,
                    (int)Context::getContext()->shop->id
                )
            );
        } 

        $this->confirmUninstall = $this->l('Are you sure to want unistall?');

        $this->ps_versions_compliancy = array('min' => '1.7', 'max' => _PS_VERSION_);
    }

    /**
     * Don't forget to create update methods if needed:
     * http://doc.prestashop.com/display/PS16/Enabling+the+Auto-Update
     */
    public function install()
    {

        include(dirname(__FILE__).'/sql/install.php');

        // 
        return parent::install() &&
            $this->registerHook('header') &&
            $this->registerHook('backOfficeHeader') &&
            $this->registerHook('actionOrderReturn') &&
            $this->registerHook('actionOrderStatusPostUpdate') &&
            $this->registerHook('actionCarrierUpdate') &&
            $this->registerHook('actionOrderEdited') &&
            $this->registerHook('actionProductCancel') &&
            $this->registerHook('actionAdminOrdersTrackingNumberUpdate') &&
            $this->registerHook('actionObjectEmployeeDeleteAfter') &&
            $this->registerHook('actionObjectOrderStateDeleteAfter');

    }
    
    public function uninstall()
    {

        // include(dirname(__FILE__).'/sql/uninstall.php');
        
        HipercalzadoUtils::deleteFakeProduct($this);

        return  
        $this->unregisterHook('header') &&
        $this->unregisterHook('backOfficeHeader') &&
        $this->unregisterHook('actionOrderReturn') &&
        $this->unregisterHook('actionOrderStatusPostUpdate') &&
        $this->unregisterHook('actionCarrierUpdate') &&
        $this->unregisterHook('actionOrderEdited') &&
        $this->unregisterHook('actionProductCancel') &&
        $this->unregisterHook('actionAdminOrdersTrackingNumberUpdate') &&
        $this->unregisterHook('actionObjectEmployeeDeleteAfter') &&
        $this->unregisterHook('actionObjectOrderStateDeleteAfter') &&
        parent::uninstall();
    }

    /**
     * Load the configuration form
     */
    public function getContent()
    {
        /**
         * If values have been submitted in the form, process.
         */
        $savedOk = null;

        //Saving the form?
        if (Tools::isSubmit('submit' . $this->name)) {
            //We are in a demo?
            if ($_SERVER['HTTP_HOST'] == 'www.4webs.be' || $_SERVER['HTTP_HOST'] == '4webs.be') {
                //The current user is the admin?
                if (Context::getContext()->employee->id_profile == 1) {
                    $errorsDetected = $this->checkConfigurationData();

                    //If any error, break the operation
                    if (count($errorsDetected) > 0) {
                        //Set the variable to the smarty template
                        $this->context->smarty->assign([
                            'savedOk' => false,
                            'errors' => $errorsDetected
                        ]);

                        return $this->get4webs() . $this->getConfigurationForms();
                    }

                    //Save the form data
                    $this->saveConfigureFormData();
                    $savedOk = true;
                }
            } else {
                $errorsDetected = $this->checkConfigurationData();

                //If any error, break the operation
                if (count($errorsDetected) > 0) {
                    //Set the variable to the smarty template
                    $this->context->smarty->assign([
                        'savedOk' => false,
                        'errors' => $errorsDetected
                    ]);

                    return $this->get4webs() . $this->getConfigurationForms();
                }

                //Save the form data
                $this->saveConfigureFormData();
                $savedOk = true;
            }
        } elseif (Tools::isSubmit('action')) {
            // Procesamos las acciones
            switch(Tools::isSubmit('action')) {
                case 'ger_orders': 
                    // Hacemos la solicitud a la URL
                    $msg = HipercalzadoUtils::getOrders($this);
                    if (!empty($msg['errors']) && isset($this->context->controller->errors)) {
                        $this->context->controller->errors = $msg['errors'];
                    } 
                    if (!empty($msg['success']) && isset($this->context->controller->confirmations)) {
                        $this->context->controller->confirmations = $msg['success'];
                    } 
                    break;
                default:
                    break;
            }

        }

        if($savedOk) {
            $this->context->controller->confirmations[] = $this->l('Configuration updated correctly.');
        }

        $this->context->smarty->assign('module_dir', $this->_path);
        
        return $this->get4webs() . $this->getConfigurationForms();
    }

    /*
    * In this function we validate all fields
    */
    protected function checkConfigurationData()
    {
        //Declare the return array
        $errorsDetected = [];

        /*
        if (Tools::strlen((Tools::getValue('user_token'))) > 32) {
            $errorsDetected[] = $this->l('The user token is too long, (max 32 characters)');
        }
        */

        if (empty((Tools::getValue('user_token')))) {
            $errorsDetected[] = $this->l('User token is empty');
        }

        if (empty((Tools::getValue('order_state_default')))) {
            $errorsDetected[] = $this->l('Order state default is empty');
        }

        if (empty((Tools::getValue('order_state_sended')))) {
            $errorsDetected[] = $this->l('Order state sended is empty');
        }

        if (empty((Tools::getValue('order_state_cancel')))) {
            $errorsDetected[] = $this->l('Order state cancel is empty');
        }

        if (empty((Tools::getValue('id_employee')))) {
            $errorsDetected[] = $this->l('Employee is empty');
        }

        if (empty((Tools::getValue('id_carrier')))) {
            $errorsDetected[] = $this->l('Carrier is empty');
        }

        return $errorsDetected;
    }

    /**
     * This function will render back the forms for the config page
     */
    public function getConfigurationForms()
    {
        $languages = Language::getLanguages(true);
        // Miramos cual es el por defecto
        foreach($languages as &$lang) {
            $shopDefaultLangId = Configuration::get('PS_LANG_DEFAULT', null, Context::getContext()->shop->id_shop_group, Context::getContext()->shop->id);
            $lang['is_default'] = ($lang['id_lang'] == $shopDefaultLangId);
        }

        $tpl_vars = [
            //Settings
            'fields_value' => [
                'user_token'            => $this->configuration->user_token,
                'parent_id'             => $this->configuration->parent_id,
                'sku_id'                => $this->configuration->sku_id,
                'order_state_default'   => $this->configuration->order_state_default,
                'order_state_sended'    => $this->configuration->order_state_sended,
                'order_state_cancel'    => $this->configuration->order_state_cancel,
                'id_employee'           => $this->configuration->id_employee,
                'id_carrier'            => $this->configuration->id_carrier,
                'id_product_fake'       => $this->configuration->id_product_fake,
            ],
            'languages'    => $languages,
            'defaultFormLanguage'  => $this->context->language->id,
            'allowEmployeeFormLang' => 1,

            //Tab control
            'selected_tab_input' => Tools::getValue('selected_tab_input')
        ];

        $module_cron_url = $this->context->link->getBaseLink() . 'modules/hipercalzado/hipercalzado-get-orders.php?token=' . substr(Tools::hash('hipercalzado/index'), 0, 10) . '&id_shop=' . $this->context->shop->id;
        $get_orders_url = Context::getContext()->link->getAdminLink('AdminModules', true) . '&configure=hipercalzado&action=get_orders';

        $conn_info = HipercalzadoUtils::checkHipercalzadoConnection($this);
        $user_token_suffix = (!empty($conn_info->code) && (int) $conn_info->code <= 299) ? '<i class="material-icons md48 green" title="' . $this->l("Connection OK") . '">check_circle</i>' : '<i class="material-icons md48 red" title="' . $this->l("Connection error ") . (((int) $conn_info->code > 299) ? ((!empty($conn_info->code) ? $conn_info->code . ': ' : '') . $conn_info->msg) : '') . '">cancel</i>';
        $user_token_desc = HipercalzadoUtils::translate("To generate the user token click on the following link in the 'API' tab") . ': 
        https://www.menuweb.es/seller/mis_datos.php';

        //Set the fields_form
        $fields_form = [
            'form' => [
                'tabs' => [
                    [
                        'id' => 'config',
                        'name' => $this->l('Configuration'),
                        'icon' => '<i class="material-icons md48">tune</i>'
                    ],
                    [
                        'id' => 'get_orders',
                        'name' =>  $this->l('Get orders'),
                        'icon' => '<i class="material-icons md48">loop</i>'
                    ]
                ],
                'legend' => [
                    'title' => $this->displayName,
                    'desc' => $this->l('Hipercalzado configuration'),
                    'icon' => 'icon-facetime-video',
                ],
                'input' => [
                    //CONFIG
                    [
                        'type' => 'text',
                        'col' => 5,
                        'required' => true,
                        'label' => $this->l('User token'),
                        'class' => 'user_token',
                        'hint' => $this->l('Token to autenticate with Hipercalzado API'),
                        'name' => 'user_token',
                        'suffix' => $user_token_suffix,
                        'desc' => $user_token_desc,
                        'tab' => 'config'
                    ],
                    [
                        'type' => 'radio',
                        'col' => 4,
                        'label' => $this->l('PARENT ID'),
                        'hint' => $this->l('Main ID of products'),
                        'name' => 'parent_id',
                        'tab' => 'config',
                        'required' => true,
                        'values' => [
                            'query' => HipercalzadoUtils::getParetIdentifiers(),
                            'id' => 'id',
                            'name' => 'name'
                        ],
                    ],
                    [
                        'type' => 'radio',
                        'col' => 5,
                        'label' => $this->l('SKU ID'),
                        'hint' => $this->l('Main ID of product atrributes'),
                        'name' => 'sku_id',
                        'tab' => 'config',
                        'required' => true,
                        'values' => [
                            'query' => HipercalzadoUtils::getSKUIdentifiers(),
                            'id' => 'id',
                            'name' => 'name'
                        ],
                    ],
                    [
                        'type' => 'select',
                        'col' => 5,
                        'label' => $this->l('State order by default'),
                        'name' => 'order_state_default',
                        'tab' => 'config',
                        'required' => true,
                        'options' => [
                            'query' => OrderState::getOrderStates($this->context->employee->id_lang),
                            'id' => 'id_order_state',
                            'name' => 'name'
                        ]
                    ],
                    [
                        'type' => 'select',
                        'col' => 5,
                        'label' => $this->l('State order to notify is sended'),
                        'name' => 'order_state_sended',
                        'tab' => 'config',
                        'required' => true,
                        'options' => [
                            'query' => OrderState::getOrderStates($this->context->employee->id_lang),
                            'id' => 'id_order_state',
                            'name' => 'name'
                        ]
                    ],
                    [
                        'type' => 'select',
                        'col' => 5,
                        'label' => $this->l('Cancel state order'),
                        'name' => 'order_state_cancel',
                        'tab' => 'config',
                        'required' => true,
                        'options' => [
                            'query' => OrderState::getOrderStates($this->context->employee->id_lang),
                            'id' => 'id_order_state',
                            'name' => 'name'
                        ]
                    ],
                    [
                        'type' => 'select',
                        'col' => 5,
                        'label' => $this->l('Employee who will be registered in status changes'),
                        'name' => 'id_employee',
                        'tab' => 'config',
                        'required' => true,
                        'options' => [
                            'query' => HipercalzadoUtils::getAllEmployees(false),
                            'id' => 'id_employee',
                            'name' => 'email'
                        ]
                    ],
                    [
                        'type' => 'select',
                        'col' => 5,
                        'label' => $this->l('Carrier'),
                        'label' => $this->l('Default carriers for orders'),
                        'name' => 'id_carrier',
                        'tab' => 'config',
                        'required' => true,
                        'options' => [
                            'query' => Carrier::getCarriers($this->context->employee->id_lang, true),
                            'id' => 'id_carrier',
                            'name' => 'name'
                        ]
                    ],
                    [
                        'type' => 'html',
                        'col' => 9,
                        'label' => $this->l('Use the following url to fetch new orders periodically with a cron'),
                        'name' => 'html_field',
                        'tab' => 'get_orders',
                        'html_content' =>
                        '<a target="_blank" href="' . $module_cron_url . '">' . $module_cron_url .  '</a>'
    
                    ],
                    [
                        'type' => 'html',
                        'label' => '',
                        'col' => 10,
                        'name' => 'button_',
                        'tab' => 'get_orders',
                        'html_content' =>
                        '<a class="btn btn-success pull-left" href="' . $get_orders_url . '">' . $this->l('Get orders') .  '</a>'
    
                    ],
                ],
                'submit' => [
                    'title' => $this->l('Save'),
                    'name' => 'submit' . $this->name,
                ]
            ]
        ];

        //Get the form helper
        $helper = $this->getConfigurationHelperForm();

        //Inject the TPL vars to the TPL
        $helper->tpl_vars = $tpl_vars;

        //Return the HTML
        return $helper->generateForm([$fields_form]);
    }

    /**
     * This function will generate the helper form and return it
     */
    public function getConfigurationHelperForm()
    {
        $helper = new HelperForm();

        //basic module and security data
        $helper->module = $this;
        $helper->name_controller = $this->name;
        $helper->token = Tools::getAdminTokenLite('AdminModules');
        $helper->currentIndex = adminController::$currentIndex . '&configure=' . $this->name;

        //Alternative template config
        $helper->base_folder = _PS_MODULE_DIR_ . $this->name . '/views/templates/admin/';
        $helper->base_tpl = 'configure.tpl';

        //Appearance settings
        $helper->title = $this->displayName;
        $helper->show_toolbar = false;
        $helper->toolbar_scroll = false;
        $helper->submit_action = 'submit' . $this->name;

        return $helper;
    }

     /**
     * Saves the configuration form data
     */
    private function saveConfigureFormData()
    {
        $this->configuration->user_token            = Tools::getValue('user_token');
        $this->configuration->parent_id             = Tools::getValue('parent_id');
        $this->configuration->sku_id                = Tools::getValue('sku_id');
        $this->configuration->order_state_default   = Tools::getValue('order_state_default');
        $this->configuration->order_state_sended    = Tools::getValue('order_state_sended');
        $this->configuration->order_state_cancel    = Tools::getValue('order_state_cancel');
        $this->configuration->id_employee           = Tools::getValue('id_employee');
        $this->configuration->id_carrier            = Tools::getValue('id_carrier');

        //Store the configuration
        HipercalzadoUtils::updateConfiguration($this);
    }

    /**
     * Process actions
     */
    protected function postProcess()
    {


    }

    /**
    * Add the CSS & JavaScript files you want to be loaded in the BO.
    */
    public function hookBackOfficeHeader()
    {
        if (Tools::getValue('module_name') == $this->name) {
            $this->context->controller->addJS($this->_path.'views/js/back.js');
            $this->context->controller->addCSS($this->_path.'views/css/back.css');
        }
    }

    public function hookActionOrderReturn()
    {
        /* Place your code here. */
    }

    public function hookActionOrderStatusPostUpdate($params)
    {

        if (!empty($params['newOrderStatus'] && $params['id_order'])){

            $new_order_state_id = (int)$params['newOrderStatus']->id;
            $order_id = (int)$params['id_order'];

            $msg = Array();
            
            // En caso de que sea pedido enviado, notificamos envio junto al numero de seguimiento (si existe)
            if ($new_order_state_id == $this->configuration->order_state_sended) {
                // Hacemos la solicitud a la URL
                $msg = HipercalzadoUtils::sendNotificationOrderSended($this, $order_id);
            // En caso de que sea pedido cancelado, notificamos cancelacion (si flag can_cancel es true)
            } elseif ($new_order_state_id == $this->configuration->order_state_cancel) {
                // Hacemos la solicitud a la URL
                $msg = HipercalzadoUtils::sendNotificationOrderCancelled($this, $order_id);
            }
            
            // Notificamos en caso de estar en un controlador de administracion
            if(!empty($this->context->controller) && $this->context->controller->controller_name == 'Admin') {
                if (!empty($msg['errors'])) {
                    $this->context->controller->errors[] = $msg['errors'];
                } 
                if (!empty($msg['success'])) {
                    $this->context->controller->confirmations[] = $msg['success'];
                } 
            }
            // die(dump());
        }
    }


    public function hookActionOrderEdited($params)
    {
        // Check if product is deleted
        // die(dump($params));
    }

    public function hookActionProductCancel($params)
    {
        if (!empty($params['order']) && Validate::isLoadedObject($params['order']) && !empty($params['id_order_detail']) && !empty($params['cancel_quantity'])){

            $id_order = (int)$params['order']->id;
            $id_order_detail = (int)$params['id_order_detail'];
            $cancel_quantity = (int)$params['cancel_quantity'];

            $msg = HipercalzadoUtils::sendNotificationProductCancelled($this, $id_order, $id_order_detail, $cancel_quantity);

            // Notificamos en caso de estar en un controlador de administracion
            if(!empty($this->context->controller) && $this->context->controller->controller_name == 'Admin') {
                if (!empty($msg['errors'])) {
                    $this->context->controller->errors[] = $msg['errors'];
                } 
                if (!empty($msg['success'])) {
                    $this->context->controller->confirmations[] = $msg['success'];
                } 
            }
        }
    }

    public function hookActionAdminOrdersTrackingNumberUpdate($params) {
        if (!empty($params['order']) && Validate::isLoadedObject($params['order']) && !empty($params['carrier']) && Validate::isLoadedObject($params['carrier'])){

            $msg = HipercalzadoUtils::sendNotificationShippingNumberChange($this, $params['order'], $params['carrier']);

            // Notificamos en caso de estar en un controlador de administracion
            if(!empty($this->context->controller) && $this->context->controller->controller_name == 'Admin') {
                if (!empty($msg['errors'])) {
                    $this->context->controller->errors[] = $msg['errors'];
                } 
                if (!empty($msg['success'])) {
                    $this->context->controller->confirmations[] = $msg['success'];
                } 
            }
        }

    }

    public function hookActionCarrierUpdate($params)
    {
       // die(dump($params));
    }

    public function hookActionObjectEmployeeDeleteAfter($params)
    {
        $employee_id = (int) $params['object']->id;
        if($employee_id == $this->configuration->id_employee) {
            $this->configuration->id_employee = Context::getContext()->employee->id;
        }
        
        //Store the configuration
        HipercalzadoUtils::updateConfiguration($this);
    }
    
    public function hookActionObjectOrderStateDeleteAfter($params)
    {
        $order_state_id = (int) $params['object']->id;
        if($order_state_id == $this->configuration->order_state_default) {
            $this->configuration->order_state_default = Configuration::get('PS_OS_PAYMENT', null, Context::getContext()->shop->id_shop_group,  Context::getContext()->shop->id);
        } else if($order_state_id == $this->configuration->order_state_sended) {
            $this->configuration->order_state_sended = Configuration::get('PS_OS_SHIPPING', null, Context::getContext()->shop->id_shop_group,  Context::getContext()->shop->id);
        } else if($order_state_id == $this->configuration->order_state_cancel) {
            $this->configuration->order_state_cancel = Configuration::get('PS_OS_CANCELED', null, Context::getContext()->shop->id_shop_group,  Context::getContext()->shop->id);
        }

        //Store the configuration
        HipercalzadoUtils::updateConfiguration($this);
    }

    /*
     * Delete hipercalzado order information when order is deleted
     */
    /*
    public function hookActionObjectOrderDeleteAfter($params)
    {

        die(dump($params));
        $order_id = $params['id_order'];

        if ($HC_order = HipercalzadoOrder::getHipercalzadoOrderByIdOrder($st_id_order)) {
            $HC_order->delete();
        }


    }
    */

    /**
     * Renders the 4webs
     * @return mixed - HTML code
     */
    public function get4webs()
    {
        $idlang = $this->context->language->id;
        $lang = Language::getIsoById($idlang);

        switch ($lang) {
            case 'es':
                $lang = 'es';
                break;
            case 'pt':
                $lang = 'pt';
                break;
            case 'fr':
                $lang = 'fr';
                break;
            case 'it':
                $lang = 'it';
                break;
            default:
                $lang = 'en';
                break;
        }
        $this->context->smarty->assign(array(
            'module_display_name' => $this->displayName,
            'module_name' => $this->name,
            'module_path' => $this->_path,
            'module_lang' => $lang
        ));

        //Add the form CSS
        $this->context->controller->addCSS($this->_path . 'views/css/configure.css');
        $this->context->controller->addJS($this->_path . 'views/js/configure.js');

        return $this->context->smarty->fetch(_PS_MODULE_DIR_ . $this->name . '/views/templates/admin/module_head.tpl');
    }


    public function isUsingNewTranslationSystem()
    {
        return false;
    }
}
