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

class HDPostProcess extends HDTranslate
{
    static $_INSTANCE;
    /**
     * @var Ets_helpdesk
     */
    public $module;

    /**
     * @var Context
     */
    public $context;

    public $ajax;

    public $errors;

    public $allow_access = 0;

    public function allowAccess($access)
    {
        $this->allow_access = $access;

        return $this;
    }

    public function __construct($module, $context, $ajax)
    {
        $this->module = $module;
        $this->context = $context;
        $this->ajax = $ajax;
    }

    public static function getInstance($module, $context, $ajax = false)
    {
        if (!self::$_INSTANCE) {
            self::$_INSTANCE = new HDPostProcess($module, $context, $ajax);
        }
        return self::$_INSTANCE;
    }

    public function initProcess()
    {
        if ($action = trim(Tools::getValue('action'))) {
            $method = ($this->ajax ? 'ajaxProcess' : 'process') . Tools::ucfirst($action);
            if (method_exists('HDPostProcess', $method)) {
                $this->{$method}();
            } else
                $this->errors[] = $this->l('Methods does\'t exits');
        }
        if ($this->errors) {
            die(json_encode(array(
                'errors' => $this->errors
            )));
        }
        die('error');
    }

    public function ajaxProcessSearchProduct()
    {
        $query = ($q = Tools::getValue('q')) && Validate::isCleanHtml($q) ? $q : false;
        $excludeIds = ($ids = Tools::getValue('excludeIds', '')) && Validate::isCleanHtml($ids) ? $ids : '';
        $excludePackItself = ($pack = Tools::getValue('packItself')) && Validate::isCleanHtml($pack) ? $pack : false;
        if ($excludeIds && $excludeIds != 'NaN') {
            $excludeIds = implode(',', array_map('intval', explode(',', $excludeIds)));
        }
        $excludeVirtuals = (bool)Tools::getValue('excludeVirtuals', false);
        $exclude_packs = (bool)Tools::getValue('exclude_packs', false);
        $imageType = $this->module->ps17 ? ImageType::getFormattedName('home') : ImageType::getFormatedName('home');
        if ($items = HDDataProvider::findProducts($query, $excludeIds, $excludePackItself, $excludeVirtuals, $exclude_packs)) {
            foreach ($items as $item) {
                $product = array(
                    'id' => (int)($item['id_product']),
                    'name' => $item['name'],
                    'ref' => (!empty($item['reference']) ? $item['reference'] : ''),
                    'image' =>$item['id_image'] ? str_replace('http://', Tools::getShopProtocol(), $this->context->link->getImageLink($item['link_rewrite'], $item['id_image'], $imageType)) :self::getNoImageDefault($imageType),
                );
                echo implode('|', $product) . "\r\n";
            }
        }
        die;
    }
    public static function getNoImageDefault($type_image)
    {
        $context = Context::getContext();
        if(file_exists(_PS_PROD_IMG_DIR_.$context->language->iso_code.'-default-'.$type_image.'.jpg'))
            return $context->link->getMediaLink(_PS_PROD_IMG_.$context->language->iso_code.'-default-'.$type_image.'.jpg');
        else
        {
            $langDefault = new Language(Configuration::get('PS_LANG_DEFAULT'));
            if(file_exists(_PS_PROD_IMG_DIR_.$langDefault->iso_code.'-default-'.$type_image.'.jpg'))
                return $context->link->getMediaLink(_PS_PROD_IMG_.$langDefault->iso_code.'-default-'.$type_image.'.jpg');
        }
    }
    public function ajaxProcessSearchCustomer()
    {
        $query = ($q = Tools::getValue('q')) && Validate::isCleanHtml($q) ? $q : false;
        if (!$query or $query == '' or Tools::strlen($query) < 1) {
            die();
        }
        $searches = explode(' ', $query);
        $excludeIds = trim(Tools::getValue('excludeIds')) !== '' ? explode(',', Tools::getValue('excludeIds')) : array();
        if (is_array($excludeIds) && !Validate::isArrayWithIds($excludeIds)) {
            $excludeIds = array();
        }
        $searches = array_unique($searches);
        foreach ($searches as $search) {
            if (!empty($search) && $results = Customer::searchByName($search, 50)) {
                foreach ($results as $result) {
                    $customer = array();
                    if ($result['active'] && (!$excludeIds || !in_array($result['id_customer'], $excludeIds))) {
                        $customer = [
                            $result['id_customer'],
                            $result['firstname'],
                            $result['lastname'],
                            $result['email'],
                        ];
                    }
                    if (count($customer) > 0)
                        echo implode('|', $customer) . "\r\n";
                }
            }
        }
        die;
    }

    public function ajaxProcessNBTickets()
    {
        die(json_encode(array(
            'nb' => (int)HDTicket::getTickets(0, true, 0, 0, null, $this->context, $this->module->isStaff(), array(), null, array('open'), 0)
        )));
    }

    public function ajaxProcessButtonContact()
    {
        die(json_encode(array(
            'contact' => $this->module->contactSupportTeam()
        )));
    }

    static $cache_fields_orders;

    public function getFieldsOrder()
    {
        if (!self::$cache_fields_orders) {
            self::$cache_fields_orders = array(
                'reference' => array(
                    'name' => 'reference',
                    'label' => $this->l('Order reference'),
                    'type' => 'text',
                    'filter' => 'a.reference',
                    'link_ref_field' => 'link_view',
                    'class' => 'fixed-width-xs center hd_ticket_id',
                    'orderby' => false,
                    'search' => false,
                    'validate' => 'isUnsignedInt',
                ),
                'product_image' => array(
                    'name' => 'product_image',
                    'label' => $this->l('Image'),
                    'type' => 'image',
                    'width' => 80,
                    'filter' => '',
                    'class' => 'fixed-width-xs center',
                    'orderby' => false,
                    'search' => false,
                    'validate' => 'isCleanHtml',
                ),
                'product_name' => array(
                    'name' => 'product_name',
                    'label' => $this->l('Product name'),
                    'type' => 'text',
                    'link_ref_field' => 'product_link',
                    'filter' => 'pl.name',
                    'class' => 'left',
                    'orderby' => false,
                    'search' => false,
                    'validate' => 'isCleanHtml',
                ),
                'date_add' => array(
                    'name' => 'date_add',
                    'label' => $this->l('Date'),
                    'type' => 'datetime',
                    'filter' => 'a.date_add',
                    'class' => 'fixed-width-xs center',
                    'orderby' => false,
                    'search' => false,
                    'validate' => 'isCleanHtml',
                ),
                'order_status' => array(
                    'name' => 'order_status',
                    'label' => $this->l('Order status'),
                    'type' => 'order_status',
                    'filter' => 'os.name',
                    'class' => 'center',
                    'orderby' => false,
                    'search' => false,
                    'validate' => 'isCleanHtml',
                ),
            );
            if (HDDataProvider::tableExist('ets_sl_order_product')) {
                self::$cache_fields_orders = array_merge(
                    self::$cache_fields_orders,
                    array(
                        'support_status' => array(
                            'name' => 'support_status',
                            'label' => $this->l('Support status'),
                            'type' => 'status',
                            'filter' => 'a.support_status',
                            'class' => 'fixed-width-xs center',
                            'orderby' => false,
                            'search' => false,
                            'validate' => 'isCleanHtml',
                        )
                    )
                );
                self::$cache_fields_orders['product_name']['fields'] = array(
                    array(
                        'name' => 'shop_name',
                        'label' => $this->l('Shop'),
                        'type' => 'text',
                    )
                );
            }
        }

        return self::$cache_fields_orders;
    }

    public static function getCombinationImageById($id_product_attribute, $idLang = null)
    {
        if (!Combination::isFeatureActive() || !$id_product_attribute) {
            return false;
        }
        if (null == $idLang) {
            $idLang = Context::getContext()->language->id;
        }
        if (version_compare(_PS_VERSION_, '1.6.1.0', '<')) {
            $result = Db::getInstance()->executeS('
				SELECT pai.`id_image`, pai.`id_product_attribute`, il.`legend`
				FROM `' . _DB_PREFIX_ . 'product_attribute_image` pai
				LEFT JOIN `' . _DB_PREFIX_ . 'image_lang` il ON (il.`id_image` = pai.`id_image`)
				LEFT JOIN `' . _DB_PREFIX_ . 'image` i ON (i.`id_image` = pai.`id_image`)
				WHERE pai.`id_product_attribute` = ' . (int)$id_product_attribute . ' AND il.`id_lang` = ' . (int)$idLang . ' ORDER by i.`position` LIMIT 1'
            );
            if (!$result)
                return false;
            return $result[0];
        } else
            return Product::getCombinationImageById($id_product_attribute, $idLang);
    }

    static $cache_product_order;

    public function ajaxProcessViewOrders()
    {
        
        $id_customer = Tools::getValue('id_customer');
        if (!$id_customer || !Validate::isUnsignedInt($id_customer) || !(($customer = new Customer($id_customer)) && $customer->id > 0)) {
            die(json_encode(array(
                'errors' => $this->l('Error. Customer does\'t not exits'),
            )));
        }
        $order_ref = Tools::getValue('order_ref');
        if (trim($order_ref) !== '' && (!Validate::isReference($order_ref) || !HDTicket::orderReferenceAndEmail($order_ref, $customer->email))) {
            $order_ref = null;
        }
        $p = Tools::getValue('p');
        if (!$p || !Validate::isUnsignedInt($p) || $p < 1) {
            $p = 1;
        }
        $n = Tools::getValue('n');
        if (!$n || !Validate::isUnsignedInt($n) || $n < 1) {
            $n = 20;
        }
        $fields_list = $this->getFieldsOrder();
        $orders = HDDataProvider::getOrders($id_customer, $order_ref, false, $p, $n, null, $this->context);
        if ($orders) {
            foreach ($orders as &$order) {
                $product = new Product($order['product_id'], true, $this->context->language->id);
                $cache_id = $order['product_id'] . '_' . (isset($order['product_attribute_id']) ? $order['product_attribute_id'] : 0) . '_' . $this->context->language->id;
                if ($product->id) {
                    if (!isset(self::$cache_product_order[$cache_id])) {
                        $image = ($order['product_attribute_id'] && ($image = $this->getCombinationImageById($order['product_attribute_id']))) ? $image : Product::getCover($product->id);
                        self::$cache_product_order[$cache_id] = array(
                            $this->context->link->getProductLink($product, null, null, null, null, null, isset($order['product_attribute_id']) ? $order['product_attribute_id'] : 0),
                            $this->context->link->getImageLink($product->link_rewrite, isset($image['id_image']) ? $image['id_image'] : 0, HDTools::getImageType('cart')),
                        );
                    }
                    list($order['product_link'], $order['product_image']) = self::$cache_product_order[$cache_id];
                    if (isset($order['product_logo']) && $order['product_logo'] !== '' && @file_exists(_PS_ROOT_DIR_.'/' . $order['product_logo'])) {
                        $order['product_image'] = $this->context->shop->getBaseURI() . $order['product_logo'];
                    }
                    $order['link_view'] = $this->getLinkOrderAdmin($order['id_order']);
                }
                if (isset($order['date_add']) && trim($order['date_add']) !== '' && isset($order['support_status']) ) {
                    if(isset($order['date_expried']) && $order['date_expried'])
                    {
                        $support_status = (int)ceil((strtotime($order['date_expried']) - time()) / 86400);
                        $order['support_status'] = $support_status > 0 ? ($support_status > 1 ? sprintf($this->l('Valid (%d days)'), $support_status) : sprintf($this->l('Valid (%d day)'), $support_status)) : $this->l('Expired');
                        if ($support_status > 0) {
                            $order['badge_success'] = true;
                        } else {
                            $order['badge_danger'] = true;
                        }
                    }
                    else
                    {
                        $order['support_status'] =false;
                        $order['badge_danger'] = true;
                    }
                    
                }
            }
        }
        $total_records = HDDataProvider::getOrders($id_customer, $order_ref, true, 0, 0, null, $this->context);
        $router_id = 'module-ets_helpdesk-process';
        $params = array(
            'id_customer' => $id_customer,
            'order_ref' => $order_ref,
        );
        $paginates = HDLink::getInstance()->getPagination($router_id, $total_records, $p, $n, $params, 1, $this->module->isBackOffice() ? 'AdminEtsHDProcess' : null);
        $per_pages = array();
        if (Ets_helpdesk::$per_pages) {
            $per_pages_array = array_keys(Ets_helpdesk::$per_pages);
            foreach ($per_pages_array as $per_page) {
                $paramUrls = $params + array('n' => $per_page, 'p' => 1);
                $per_pages[$per_page] = $this->module->isBackOffice() ? $this->context->link->getAdminLink('AdminEtsHDProcess', true, array(), $paramUrls) : HDLink::getInstance()->getPaginationLink($router_id, $paramUrls, $this->context->language->id);
            }
        }
        $helper = new HDHelperList();
        $helper->module = $this->module;
        $helper->table = 'orders';
        $helper->list = $orders;
        $helper->fields_list = $fields_list;
        $helper->title = $total_records > 1 ? $this->l('Order') : $this->l('Orders');
        $helper->paginates = $paginates;
        $helper->list_per_pages = $per_pages;
        $helper->show_footer_btn = Ets_helpdesk::$min_per_page > 0 && ceil($total_records / Ets_helpdesk::$min_per_page) > 1;
        $helper->total_records = $total_records;
        $helper->current_per_page = $n;
        $helper->link = $this->module->isBackOffice() ? $this->context->link->getAdminLink('AdminEtsHDTickets') : HDLink::getInstance()->getStaffsLink($this->context->language->id);

        die(json_encode(array(
            'list' => $helper->generalList()
        )));
    }
    public function getLinkOrderAdmin($id_order)
    {
        if(defined('_PS_ADMIN_DIR_') && isset($this->context->employee) && $this->context->employee->id > 0)
        {
            if (version_compare(_PS_VERSION_, '1.7.7.0', '>=')) {
                $sfContainer = call_user_func(array('\PrestaShop\PrestaShop\Adapter\SymfonyContainer', 'getInstance'));
                if (null !== $sfContainer) {
                    $sfRouter = $sfContainer->get('router');
                    $link_order = $sfRouter->generate(
                        'admin_orders_view',
                        array('orderId' => $id_order)
                    );
                }
            } else
                $link_order = $this->context->link->getAdminLink('AdminOrders') . '&id_order=' . (int)$id_order . '&vieworder';
            return $link_order;
        }
        
    }
    private function isAjax()
    {
        // Usage of ajax parameter is deprecated
        $isAjax = (int)
            Tools::getValue('ajax') || Tools::isSubmit('ajax');

        if (isset($_SERVER['HTTP_ACCEPT'])) {
            $isAjax = $isAjax || preg_match(
                    '#\bapplication/json\b#',
                    $_SERVER['HTTP_ACCEPT']
                );
        }

        return $isAjax;
    }

    public function runCronjob()
    {
        if (!($token = trim(Tools::getValue('secure'))) ||
            !Validate::isCleanHtml($token) ||
            $token != Configuration::getGlobalValue('ETS_HD_CRONJOB_SECURE_TOKEN') ||
            !$this->allow_access && $this->isAjax()
        ) {
            die(json_encode(array(
                'errors' => $this->l('Access denied'),
            )));
        }
        Configuration::updateGlobalValue('ETS_HD_CRONJOB_TIME',date('Y-m-d H:i:s'));
        $day = (int)Configuration::get('ETS_HD_TICKET_CLOSING_TIME') ?: 0;
        $count = 0;
        if ($day > 0 && Configuration::get('ETS_HD_TICKET_ENABLED')) {
            $distance_time = pSQL(date('Y-m-d H:i:s', time() - $day * 24 * 60 * 60));
            if (($count = Db::getInstance()->getValue('SELECT COUNT(`id_ets_hd_ticket`) FROM `' . _DB_PREFIX_ . 'ets_hd_ticket` WHERE 1 AND "' . pSQL($distance_time) . '" > `date_upd` AND `status` = "open" AND replied=0 AND staff_replied=1'))) {
                Db::getInstance()->update('ets_hd_ticket', array('status' => 'closed'), '"' . pSQL($distance_time) . '" > `date_upd` AND `status` = "open" AND replied=0 AND staff_replied=1');
            }
        }
        $mailQueues = Ets_hd_mailqueue::getMailQueues();
        $count_send = 0;
        $count_failed =0;
        if($mailQueues)
        {
            foreach($mailQueues as $mailQueue)
            {
                $mailQueueObj = new Ets_hd_mailqueue($mailQueue['id_ets_hd_mailqueue']);
                if(Validate::isLoadedObject($mailQueueObj))
                {
                    $mailTracking =  Ets_hd_mailtraciking::getMailtrackingByQueue($mailQueue['id_ets_hd_mailqueue']);
                    $mailTracking->id_customer = $mailQueueObj->id_customer;
                    $mailTracking->id_employee = $mailQueueObj->id_employee;
                    $mailTracking->customer_name = $mailQueueObj->customer_name;
                    $mailTracking->email = $mailQueueObj->email;
                    $mailTracking->subject = $mailQueueObj->subject;
                    $mailTracking->content = $mailQueueObj->content;
                    $mailTracking->queue_date = $mailQueueObj->date_add;
                    $mailTracking->date_add = date('Y-m-d H:i:s');
                    $mailTracking->status ='time_out';
                    if(!$mailTracking->id)
                        $mailTracking->add();
                    else
                        $mailTracking->update();
                    if($mailTracking->id)
                    {
                        $sent = $mailQueueObj->sendMail(true,$mailTracking->id);
                        if($sent)
                        {
                            $mailTracking->status ='success';
                            $count_send++;
                        }
                        else
                        {
                            $mailTracking->status ='failed';
                            $count_failed++;
                        }
                        $mailTracking->update();
                        if($sent || $sent===false)
                            $mailQueueObj->delete();
                        else
                            $mailQueueObj->update();
                    }
                    
                }
            }
        }
        $msg ='';        
        if($count >0)
        {
            $msg .= ($msg !== '' ? "\n" : '').Tools::dateFormat(array('date' => date('Y-m-d H:i:s'), 'full' => true), $this->context->smarty).': '. ($count ==1 ? $this->l('1 ticket closed!') : sprintf($this->l('%s tickets closed!'), $count));
        }
        if($count_send || $count_failed)
        {
            if($count_send)
            {
                $msg .= ($msg !== '' ? "\n" : '').Tools::dateFormat(array('date' => date('Y-m-d H:i:s'), 'full' => true), $this->context->smarty).': '. ($count_send ==1 ? $this->l('Sent 1 email') : sprintf($this->l('Sent %s emails'),$count_send));
            }
            if($count_failed)
            {
                $msg .= ($msg !== '' ? "\n" : '').Tools::dateFormat(array('date' => date('Y-m-d H:i:s'), 'full' => true), $this->context->smarty).': '. ($count_failed ==1 ? $this->l('Sent failed 1 email') : sprintf($this->l('Sent failed %s emails'),$count_failed));
                                
            }                          
        }
        if(!$msg)
        {
            $msg .= ($msg !== '' ? "\n" : '').Tools::dateFormat(array('date' => date('Y-m-d H:i:s'), 'full' => true), $this->context->smarty).': '. $this->l('Nothing to do!');
        }
        $json_array = array('msg' => $this->l('Cronjob runs successfully'));
        if (Configuration::getGlobalValue('ETS_HD_SAVE_CRONJOB_LOG')) {
            $log = Configuration::getGlobalValue('ETS_HD_CRONJOB_LOG');
            $log .= ($log !== '' ? "\n" : '').$msg;
            Configuration::updateGlobalValue('ETS_HD_CRONJOB_LOG', $log, true);
            $json_array['log'] = $log;
        }
                
        die(json_encode($json_array));
    }
}