<?php
/**
* 2023 Anvanto
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
*
*  @author    Anvanto <anvantoco@gmail.com>
*  @copyright 2023 Anvanto
*  @license   http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
*/

if (!defined('_PS_VERSION_')) {
    exit;
}

use PrestaShop\PrestaShop\Core\Module\WidgetInterface;

require_once _PS_MODULE_DIR_ . 'an_productextratabs/classes/anTabsCombinations.php';
require_once _PS_MODULE_DIR_ . 'an_productextratabs/classes/anProductTabs.php';
require_once _PS_MODULE_DIR_ . 'an_productextratabs/classes/anProductTabsTplContent.php';
require_once _PS_MODULE_DIR_ . 'an_productextratabs/classes/anProductTabsLabels.php';

class an_productextratabs extends Module implements WidgetInterface
{
    const PREFIX = 'an_pt_';
    
    public $addons_product_id;

    protected $_tabs = [
 
        [
            'class_name' => 'AdminProductTabs',
            'parent' => 'AdminParentModulesSf',
            'name' => 'Product Tabs: Tabs',
            'active' => 0
        ], 
        [
            'class_name' => 'AdminProducttabsSettings',
            'parent' => 'AdminParentModulesSf',
            'name' => 'Product Tabs: Settings',
            'active' => 0
        ],
        [
            'class_name' => 'AdminProductTabstemplates',
            'parent' => 'AdminParentModulesSf',
            'name' => 'Product Tabs: Tabs templates',
            'active' => 0
        ],
        [
            'class_name' => 'AdminProducttabsLabels',
            'parent' => 'AdminParentModulesSf',
            'name' => 'Product Tabs: Labels',
            'active' => 0
        ],
        [
            'class_name' => 'AdminProducttabsAjax',
            'parent' => 'AdminParentModulesSf',
            'name' => 'Product Tabs: Ajax',
            'active' => 0
        ]     
    ];    

    public function __construct()
    {
        $this->name = 'an_productextratabs';
        $this->tab = 'others';
        $this->version = '3.2.7';
        $this->author = 'Anvanto';
        $this->need_instance = 0;

        $this->bootstrap = true;
        $this->module_key = '3b466206aa8f1f635aaa18f9c1523fd8';
        $this->addons_product_id = '26048';

        parent::__construct();

        $this->displayName = $this->l('Product Extra Tabs');
        $this->description = $this->l('The module creates additional description tabs with any format of content.');
        $this->confirmUninstall = $this->l('Are you sure you want to uninstall the module?');

        $this->ps_versions_compliancy = array('min' => '1.7', 'max' => _PS_VERSION_);
    }

    /**
     * @return bool
     */

    public function install()
    {
        $sql = include _PS_MODULE_DIR_ . $this->name . '/sql/install.php';
        foreach ($sql as $_sql) {
            Db::getInstance()->Execute($_sql);
        } 
            
        $languages = Language::getLanguages();
        foreach ($this->_tabs as $tab) {
            $_tab = new Tab();
            $_tab->active = $tab['active'];
            $_tab->class_name = $tab['class_name'];
            $_tab->id_parent = Tab::getIdFromClassName($tab['parent']);
            if (empty($_tab->id_parent)) {
                $_tab->id_parent = 0;
            }

            $_tab->module = $this->name;
            foreach ($languages as $language) {
                $_tab->name[$language['id_lang']] = $this->l($tab['name']);
            }

            $_tab->add();
        }

        anProductTabs::importJsonTabsDefault();
        
        return parent::install()
            && $this->registerHook('displayHeader')
            && $this->registerHook('displayProductExtraContent')
            && $this->registerHook('displayBackOfficeHeader')
            && $this->registerHook('displayAdminProductsExtra')
            && $this->registerHook('actionProductAdd')
            && $this->registerHook('actionProductFlagsModifier');
    }

    public function uninstall()
    {
         $sql = include _PS_MODULE_DIR_ . $this->name .  '/sql/uninstall.php';
        foreach ($sql as $_sql) {
            Db::getInstance()->Execute($_sql);
        }     
        
        foreach ($this->_tabs as $tab) {
            $_tab_id = Tab::getIdFromClassName($tab['class_name']);
            $_tab = new Tab($_tab_id);
            $_tab->delete();
        }        
    
        return parent::uninstall();
    }

    /**
     * @return bool
     */

    public function renderWidget($hookName, array $params)
    { 
        return; 
    }

    public function getWidgetVariables($hookName, array $params)
    {            
        $widgets = [];
        return $widgets;
    }
    
    public function getContent()
    {
        Tools::redirectAdmin($this->context->link->getAdminLink('AdminProductTabs'));
    }

    
    public function hookActionProductAdd($params)
    { 
        if (!isset($params['id_product_old'])){
            return;
        }
        
        $sql = 'SELECT * FROM `' . _DB_PREFIX_ . 'an_productextratabs_tpl_content` sw WHERE sw.`id_product` = '.(int) $params['id_product_old'].' '; 
        $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql);

        foreach ($result as $key => $content){
            $obj = new anProductTabsTplContent($content['id_content']);

            $newObj = $obj->duplicateObject();
            $newObj->id_product = $params['id_product']; 
            $newObj->save();

        }
    }

    public function hookDisplayHeader()
    { 

        $fileName = configuration::get(self::PREFIX.'_css_file_name');
        
        if ($fileName){
            $this->context->controller->registerStylesheet(
                $this->name . "_css_labels",
                'modules/' . $this->name . '/views/css/' .$fileName,
                ['server' => 'local', 'priority' => 150]
            );
        }

        if ($this->context->controller instanceof ProductController) {
            $this->context->controller->addJquery();
            
            $this->context->controller->registerStylesheet(
                $this->name . "_css",
                'modules/' . $this->name . '/views/css/front.css',
                ['server' => 'local', 'priority' => 150]
            );
            
            switch (Configuration::get( self::PREFIX . 'view_type')){
                case 0:
                    $jsFile = '';
                    break; 

                case 1:
                    $jsFile = 'block';
                    break;        

                case 2:
                    $jsFile = 'accordion';
                    break;    
                    
            } 
           
            if ($jsFile != ''){
                $this->context->controller->registerJavascript(
                    $this->name . "_js_typeview",
                    'modules/' . $this->name . '/views/js/'.$jsFile.'.js',
                    ['server' => 'local', 'priority' => 150]
                );
            }

            $this->context->controller->registerJavascript(
                $this->name . "_js",
                'modules/' . $this->name . '/views/js/front_quantity.js',
                ['server' => 'local', 'priority' => 150]
            );

            $this->context->controller->registerJavascript(
                $this->name . "_js_front",
                'modules/' . $this->name . '/views/js/front.js',
                ['server' => 'local', 'priority' => 150]
            );            
        }  
    }

    public function hookActionProductFlagsModifier($params)
    {
        
        $myLabels = anProductTabsLabels::getLabelsByIdProduct($params['product']['id_product']);

        if (count($myLabels) != 0){ 
            foreach ($myLabels as $label){
                $params['flags'][$label['id_label']] = [
                    'type' => $label['special_id_label'],
                    'label' => $label['label']
                ];
            }
        }
    }

    public function generateFileName($format = 'css', $prefix = self::PREFIX)
    {
        return $prefix . md5(uniqid() . context::getContext()->shop->id) . '.' . $format;
    }

    public function getCombinationsView($id_product)
    {
        $productObj = new Product($id_product, false, (int)$this->context->language->id);
        $attributeCombinations = $productObj->getAttributeCombinations((int)$this->context->language->id);
        $productData = anCombTabs::attributeCombinationForSelect($attributeCombinations, $productObj);

        $config = array(
            'display_image'          => true,
            'display_reference'      => true,
            'display_attributes'     => true,
            'combine_attributes'     => true,
            'display_availability'   => false,
            'display_quantity'       => false,
            'display_price'          => true,
            'display_add_to_cart'    => true,
            'display_field_quantity' => true,
        );

        $this->smarty->assign([                
            'cart' => $this->context->link->getPageLink('cart'),
            'token' => Tools::getToken(false),
            
            'product_id' => (int) $productObj->id,

            'config' => $config,
            'productData' => $productData,
        ]);

        return $this->display(__FILE__, 'views/templates/hook/combinations.tpl');
    }

    public function hookDisplayProductExtraContent($params)
    {
        $id_product = $params['product']->id;
        $myTabs = array_merge(anProductTabs::getTabsByIdProduct($id_product), anProductTabsTplContent::getTabsByIdProduct($id_product));
        
        $tabs = [];    
        foreach ($myTabs as $tabItem){
            $tab = new PrestaShop\PrestaShop\Core\Product\ProductExtraContent();

            $antabcontent['content'] = $tabItem['tab_content'];
            
            $antabcontent['combinations'] = '';
            if(isset($tabItem['combinations']) && $tabItem['combinations']){
                $antabcontent['combinations'] = $this->getCombinationsView($id_product);
            }

            $antabcontent['contactform'] = '';
            if(isset($tabItem['contactform']) && $tabItem['contactform']){
                $antabcontent['contactform'] = $this->renderContactForm();
            }

            $this->smarty->assign('antabcontent', $antabcontent);

            $tab->setTitle($tabItem['tab_name'])
                ->setContent($this->fetch($this->getTemplatePath('views/templates/front/tab_content.tpl')));
            $tabs[] = $tab;
        }

        return $tabs;
    }



    public function renderContactForm()
    {
        require_once _PS_MODULE_DIR_ . 'contactform/contactform.php';
        $contactForm = new Contactform();
        $this->context->smarty->assign(['urls' => $this->context->controller->getTemplateVarUrls()]);
        return $contactForm->renderWidget();
    }

    public function hookDisplayBackOfficeHeader()
    {
        if(Tools::getValue('controller') == 'AdminProducts'){
            $this->context->controller->addJquery();
            $this->context->controller->addJqueryUI('ui.sortable');
            $this->context->controller->addJS($this->_path.'views/js/back_product_tabs.js');
        }
    }

    public function hookDisplayAdminProductsExtra($params)
    {   
        $id_product = $params['id_product'];
        $myTabs = anProductTabs::getTabsByIdProduct($id_product);

        $urlEdit = $this->context->link->getAdminLink('AdminProductTabs').'&updatean_productextratabs&token='.Tools::getAdminTokenLite('AdminProductTabs').'&idtab=';
        
        foreach ($myTabs as $key => $tab){
            $myTabs[$key]['urlEdit'] = $urlEdit . $tab['idtab'];
            $myTabs[$key]['urlDelete'] = $this->context->link->getAdminLink('AdminProducttabsAjax', true, [], [
                'ajax'=>1, 
                'action' =>'deleteTab',
                'idtab' => $tab['idtab'],
            ]);

            $myTabs[$key]['updatePositions'] = $this->context->link->getAdminLink('AdminProducttabsAjax', true, [], [
                'ajax'=>1, 
                'action' =>'updatePositionsTabs',
            ]);            

            switch ($tab['relation']){
                case 1:
                    $myTabs[$key]['relation'] = $this->l('Categories');
                    break;        

                case 2:
                    $myTabs[$key]['relation'] = $this->l('Products');
                    break;    
                    
                default:
                $myTabs[$key]['relation'] = $this->l('all');
            }                        
        }

       $this->context->smarty->assign('myAnvantoTabs', $myTabs);

       $this->context->smarty->assign('myAnvantoTabsAddBtn', $this->context->link->getAdminLink('AdminProductTabs') . 
       '&addan_productextratabs&token=' . Tools::getAdminTokenLite('AdminProductTabs'));


        //
        $tabFieldsTemplate['content_active'] = [
            'name' => 'content_active',
            'label' => 'Active',
            'type' => 'switch',
            'value' => 0
        ];        
        $tabFieldsTemplate['content_combinations'] = [
            'name' => 'content_combinations',
            'label' => 'Combinations',
            'type' => 'switch',
            'value' => 0
        ];
        $tabFieldsTemplate['content_contactform'] = [
            'name' => 'content_contactform',
            'label' => 'Contactform',
            'type' => 'switch',
            'value' => 0
        ];
        $tabFieldsTemplate['content_name'] = [
            'name' => 'content_name',
            'label' => 'Tab name',
            'type' => 'text',
            'value' => ''
        ];
        $tabFieldsTemplate['content_content'] = [
            'name' => 'content_content',
            'label' => 'Tab content',
            'type' => 'textarea',
            'value' => ''
        ];

        $tabTemplates = anProductTabs::getTabTemplates();

        $tabTemplateFields = [];
        $fieldsValues = [];
        foreach ($tabTemplates as $tp){

            $tabTemplate = new anProductTabs($tp['idtab']);

            $tabTemplateFields[$tp['idtab']]['fields'] = $tabFieldsTemplate;
            $tabTemplateFields[$tp['idtab']]['idtab'] = $tp['idtab'];
            $tabTemplateFields[$tp['idtab']]['note'] = $tp['note'];
            $tabTemplateFields[$tp['idtab']]['saveController']  = $this->context->link->getAdminLink('AdminProducttabsAjax', true, [], [
                'ajax'=>1, 
                'id_product' => $id_product,
                'idtab' => $tp['idtab'],
                'action' =>'saveTabs',
            ]);

            $idContent = anProductTabsTplContent::getIdByProductTemplate($id_product, $tp['idtab']);
            if ($idContent){
                $contentObj = new anProductTabsTplContent($idContent);
                $fieldsValues[$tp['idtab']]['content_active'] = $contentObj->content_active;
                $fieldsValues[$tp['idtab']]['content_combinations'] = $contentObj->content_combinations;
                $fieldsValues[$tp['idtab']]['content_contactform'] = $contentObj->content_contactform;
                $fieldsValues[$tp['idtab']]['content_content'] = $contentObj->content_content;
                $fieldsValues[$tp['idtab']]['content_name'] = $contentObj->content_name;
            } elseif ($tabTemplate) {
                $fieldsValues[$tp['idtab']]['content_content'] = $tabTemplate->tab_content;
                $fieldsValues[$tp['idtab']]['content_name'] = $tabTemplate->tab_name;
            }
        }
        $this->context->smarty->assign('tabTemplateFields', $tabTemplateFields);
        $this->context->smarty->assign('fields_value', $fieldsValues);


        $languages = Language::getLanguages(1, 0, 0);
        $this->context->smarty->assign('languages', $languages);
        $this->context->smarty->assign('currentLang', array(
            'id_lang' => Configuration::get('PS_LANG_DEFAULT'),
            'iso_code' => Language::getIsoById((int) Configuration::get('PS_LANG_DEFAULT'))
        ));

        $this->context->smarty->assign('isNewProductPage', $this->isNewProductPage());

        $this->context->smarty->assign('myAnvantoTabsAddTemplate', $this->context->link->getAdminLink('AdminProductTabstemplates'));
       
       return $this->display(__FILE__, 'views/templates/admin/productpage/tab_form.tpl');
    }

    public function isNewProductPage()
    {
        $productPagev2 = Db::getInstance()->getValue('SELECT state FROM `' . _DB_PREFIX_ . 'feature_flag` WHERE `name` = \'product_page_v2\' ');

        if (version_compare(_PS_VERSION_, '8.1.0.0', '<') || $productPagev2 === 0){
            return false;
        }

        return true;
    }

    //////////////

    public function tabAdd($tab, $module)
    {
        if (count($tab) == 0){
            return false;
        }

        $languages = Language::getLanguages();
        
        $_tab = new Tab();
        $_tab->active = $tab['active'];
        $_tab->class_name = $tab['class_name'];
        $_tab->id_parent = Tab::getIdFromClassName($tab['parent']);
        if (empty($_tab->id_parent)) {
            $_tab->id_parent = 0;
        }

        $_tab->module = $module->name;
        foreach ($languages as $language) {
            $_tab->name[$language['id_lang']] = $module->l($tab['name']);
        }

        $_tab->add();

        return true;
    }

    public function tabDelete($tab)
    {
        if (count($tab) == 0){
            return false;
        }        
        
        $_tab_id = Tab::getIdFromClassName($tab['class_name']);
        $_tab = new Tab($_tab_id);
        $_tab->delete();

        return true;
    }
    
    public function topPromo()
    {        
        $this->context->smarty->assign('theme', $this->getThemeInfo());
        return $this->display(__FILE__, 'views/templates/admin/top.tpl');
    }
    
    public function getThemeInfo()
    {
        $theme = [];
        $themeFileJson = _PS_THEME_DIR_.'/config/theme.json';
        if (Tools::file_exists_no_cache($themeFileJson)) {
            $theme = (array)json_decode(Tools::file_get_contents($themeFileJson), 1);            
        }

        if (!isset($theme['url_contact_us']) || $theme['url_contact_us'] == ''){
            
            $urlContactUs = 'https://addons.prestashop.com/contact-form.php';

            if (isset($theme['addons_id']) && $theme['addons_id'] != ''){
                $urlContactUs .= '?id_product=' .$theme['addons_id'];
            } elseif (isset($this->url_contact_us) && $this->url_contact_us != ''){
                $urlContactUs = $this->url_contact_us;
            } elseif (isset($this->addons_product_id) && $this->addons_product_id != ''){
                $urlContactUs .= '?id_product=' .$this->addons_product_id;
            }
            
            $theme['url_contact_us'] = $urlContactUs;
        }
        
        if (!isset($theme['url_rate']) || $theme['url_rate'] == ''){
            
            $urlRate = 'https://addons.prestashop.com/ratings.php';

            if (isset($theme['addons_id']) && $theme['addons_id'] != ''){
                $urlRate .= '?id_product=' .$theme['addons_id'];
            } elseif (isset($this->url_rate) && $this->url_rate != ''){
                $urlRate = $this->url_rate;
            } elseif (isset($this->addons_product_id) && $this->addons_product_id != ''){
                $urlRate .= '?id_product=' .$this->addons_product_id;
            }
            
            $theme['url_rate'] = $urlRate;
        }        
        return $theme;
    }
}
