<?php
namespace TwigExtension;

use Entity\Model\OxalinkUser;
use Entity\Model\Paravrac;
use Helpers\Outil\Sql;
use Helpers\Session\ParseBase1;
use Helpers\Session\Session;
use Helpers\Trad\ITrad;
use Modules\Evaluation\Data\Parametre;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use Psr\Container\ContainerInterface;
use Skeleton\Router;
use Helpers\Outil\Date;
use Helpers\Parametres\Constante;
use Helpers\Trad\Trad;
use Helpers\ChargeDocument\ChargeDocument;
use Helpers\Log\LogSysteme;
use Helpers\Fichier\Fichier;
use Helpers\Outil\Outils;
use Helpers\Outil\Roles;
use Twig\TwigFilter;

class OutilExtension extends \Twig\Extension\AbstractExtension
{
    protected \PDO $pdo;
    
    protected ContainerInterface $contenaire;
    
    protected Parametre $parameter;
    
    protected Router $router;

    private ITrad $trad;
    private OxalinkUser $oxalinkUser;
    
    public function __construct(\PDO $pdo, ContainerInterface $contenaire, Router $router)
    {
        $this->pdo = $pdo;
        $this->contenaire = $contenaire;
        $this->router = $router;
        $this->parameter =  new Parametre($this->pdo);
        $this->oxalinkUser = new OxalinkUser($this->pdo);
        $this->trad = $contenaire->get(ITrad::class);
    }
    
    public function getFunctions()
    {
        return [
            new \Twig\TwigFunction(
                'uid',
                [ $this,'uid'],
                ['is_safe' => ['html']]
            ),
            new \Twig\TwigFunction('boolSql', [
                $this,
                'boolSql'
            ], [
                'is_safe' => [
                    'html'
                ]
            ]),
            new \Twig\TwigFunction('getAll', [
                $this,
                'getAll'
            ], [
                'is_safe' => [
                    'html'
                ]
            ]),
            new \Twig\TwigFunction('baseUrl', [
                $this,
                'baseUrl'
            ], [
                'is_safe' => [
                    'html'
                ]
            ]),
            new \Twig\TwigFunction('base', [
                $this,
                'base'
            ], [
                'is_safe' => [
                    'html'
                ]
            ]),
            new \Twig\TwigFunction('googleMap', [
                $this,
                'googleMap'
            ], [
                'is_safe' => [
                    'html'
                ]
            ]),

            new \Twig\TwigFunction('include_file', [
                $this,
                'include_file'
            ], [
                'is_safe' => [
                    'html'
                ]
            ]),
            new \Twig\TwigFunction('skinCode', [
                $this,
                'skinCode'
            ], [
                'is_safe' => [
                    'html'
                ]
            ]),
            new \Twig\TwigFunction('spliter', [
                $this,
                'spliter'
            ], [
                'is_safe' => [
                    'html'
                ]
            ]),
            new \Twig\TwigFunction('piedDePage', [
                $this,
                'piedDePage'
            ], [
                'is_safe' => [
                    'html'
                ]
            ]),
            new \Twig\TwigFunction('titleHtml', [
                $this,
                'titleHtml'
            ], [
                'is_safe' => [
                    'html'
                ]
            ]),
            new \Twig\TwigFunction('var_dump', [
                $this,
                'var_dump'
            ], [
                'is_safe' => [
                    'html'
                ]
            ]),
            new \Twig\TwigFunction('remise', [
                $this,
                'remise'
            ], [
                'is_safe' => [
                    'html'
                ]
            ]),
            new \Twig\TwigFunction('shortLibelle', [
                $this,
                'shortLibelle'
            ], [
                'is_safe' => [
                    'html'
                ]
            ]),
            new \Twig\TwigFunction('keyPathliste', [
                $this,
                'keyPathliste'
            ], [
                'is_safe' => [
                    'html'
                ]
            ]),
            new \Twig\TwigFunction('deleteSession', [
                $this,
                'deleteSession'
            ], [
                'is_safe' => [
                    'html'
                ]
            ]),
            new \Twig\TwigFunction('getSession', [
                $this,
                'getSession'
            ], [
                'is_safe' => [
                    'html'
                ]
            ]),
            new \Twig\TwigFunction('labelCreateur', [
                $this,
                'labelCreateur'
            ], [
                'is_safe' => [
                    'html'
                ]
            ]),
            new \Twig\TwigFunction('tradBuild1Variable', [
                $this,
                'tradBuild1Variable'
            ], [
                'is_safe' => [
                    'html'
                ]
            ]),
            new \Twig\TwigFunction('iconeDocAtt', [
                $this,
                'iconeDocAtt'
            ], [
                'is_safe' => [
                    'html'
                ]
            ]),
            new \Twig\TwigFunction('scriptReporting', [
                $this,
                'scriptReporting'
            ], [
                'is_safe' => [
                    'html'
                ]
            ]),
                
            new \Twig\TwigFunction('str_replace', [
                $this,
                'str_replace'
            ], [
                'is_safe' => [
                    'html'
                ]
            ]),
            new \Twig\TwigFunction('affichageImageOxadata', [
                $this,
                'affichageImageOxadata'
            ], [
                'is_safe' => [
                    'html'
                ]
            ]),
            new \Twig\TwigFunction('displayImgOxadata', [
                $this,
                'displayImgOxadata'
            ], [
                'is_safe' => [
                    'html'
                ]
            ]),
            new \Twig\TwigFunction('tradDatePickers', [
                $this,
                'tradDatePickers'
            ], [
                'is_safe' => [
                    'html'
                ]
            ]),
            new \Twig\TwigFunction('str_pad', [
                $this,
                'str_pad'
            ], [
                'is_safe' => [
                    'html'
                ]
            ]),
            new \Twig\TwigFunction('hover_action', [
                $this,
                'hover_action'
            ], [
                'is_safe' => [
                    'html'
                ]
            ]),
            new \Twig\TwigFunction('convertIDToInput', [
                $this,
                'convertIDToInput'
            ], [
                'is_safe' => [
                    'html'
                ]
            ]),
            new \Twig\TwigFunction('buttonUpDown', [
                $this,
                'buttonUpDown'
            ], [
                'is_safe' => [
                    'html'
                ]
            ]),
            new \Twig\TwigFunction(
                'colon',
                [$this, 'colon'],
                ['is_safe' => ['html']]
            ),
            new \Twig\TwigFunction(
                'strBuild',
                [$this, 'strBuild'],
                ['is_safe' => ['html']]
            ),
            new \Twig\TwigFunction(
                'generateDataTooltips',
                [$this, 'generateDataTooltips'],
                ['is_safe' => ['html']]
            ),
            new \Twig\TwigFunction(
                'attr',
                [$this, 'attr'],
                ['is_safe' => ['html']]
            ),
            new \Twig\TwigFunction(
                'entityLabel',
                [__CLASS__, 'entityLabel'],
            ),
            new \Twig\TwigFunction(
                'hastutilLabel',
                [$this, 'hastutilLabel'],
                ['is_safe' => ['html']]
            ),
            new \Twig\TwigFunction(
                'ajaxPopup',
                [$this,'ajaxPopup'],
                ['is_safe' => ['html']]
            ),
            new \Twig\TwigFunction(
                'qteByUnite',
                [$this,'qteByUnite'],
                ['is_safe' => ['html']]
            ),
            new \Twig\TwigFunction(
                'getConst',
                [$this,'getConst'],
                ['is_safe' => ['html']]
            ),
            new \Twig\TwigFunction(
                'hasRight',
                [$this,'hasRight'],
                ['is_safe' => ['html']]
            ),
            new \Twig\TwigFunction(
                'connexionImage',
                [$this, 'connexionImage'],
                ['is_safe' => ['html']]
            ),
            new \Twig\TwigFunction(
                'updateImageFromSource',
                [$this, 'updateImageFromSource'],
                ['is_safe' => ['html']]
            ),
            new \Twig\TwigFunction(
                'attrJs',
                [$this, 'attrJs'],
                ['is_safe' => ['html']]
            ),
            new \Twig\TwigFunction(
                'qteByDecimal',
                [$this, 'qteByDecimal'],
                ['is_safe' => ['html']]
            ),
            new \Twig\TwigFunction(
                'oxalinkUserStatut',
                [$this,'oxalinkUserStatut'],
                ['is_safe' => ['html']
                ]
            ),
        ];
    }
    
    
    public function getFilters()
    {
        return array(
            'upperValue' => new TwigFilter('upperValue', array($this, 'upperValue')),
            //'withoutParenthese' => new TwigFilter('withoutParenthese', array($this, 'withoutParenthese')),
            'prix' =>  new TwigFilter('prix', array($this, 'prix')),
            'prixUnitaire' =>  new TwigFilter('prixUnitaire', array($this, 'prixUnitaire')),
            'numberFormat' =>  new TwigFilter('numberFormat', array($this, 'numberFormat')),
            'tva' =>  new TwigFilter('tva', array($this, 'tva')),
            'qte' =>  new TwigFilter('qte', array($this, 'qte')),
            'dateTrad' => new TwigFilter('dateTrad', array($this, 'dateTrad')),
            'dateOrigin' => new TwigFilter('dateOrigin', array($this, 'dateOrigin')),
            'heureTrad' => new TwigFilter('heureTrad', array($this, 'heureTrad')),
            'paramDateFormat' => new TwigFilter('paramDateFormat', array($this, 'paramDateFormat')),
            'boolTrad' => new TwigFilter('boolTrad', array($this, 'boolTrad')),
            'boolSql' => new TwigFilter('boolSql', array($this, 'boolSql')),
            'firstLettre' => new TwigFilter('firstLettre', array($this, 'firstLettre')),
            'trad' => new TwigFilter('trad', array($this, 'trad')),
            'baseUrl' => new TwigFilter('baseUrl', array($this, 'baseUrl')),
            'convert_encoding' => new TwigFilter('convert_encoding', array($this, 'convert_encoding')),
            'lengthTable' => new TwigFilter('lengthTable', array($this, 'lengthTable')),
            'substr' => new TwigFilter('substr', array($this, 'substr')),
            'lienExterieur' => new TwigFilter('lienExterieur', array($this, 'lienExterieur')),
            'convertInt' => new TwigFilter('convertInt', array($this, 'convertInt')),
            'convertStr' => new TwigFilter('convertStr', array($this, 'convertStr')),
            'convertFloat' => new TwigFilter('convertFloat', array($this, 'convertFloat')),
            'majF00' => new TwigFilter('convertStr', array($this, 'convertStr')),
            'moisHistoFournisss' => new TwigFilter('moisHistoFournisss', array($this, 'moisHistoFournisss')),
            'replaceInID' => new TwigFilter('replaceInID', array($this, 'replaceInID')),
            'addslashes' => new TwigFilter('addslashes', array($this, 'addslashes')),
            'montantAbreger' => new TwigFilter('montantAbreger', array($this, 'montantAbreger')),
            
            'attr' => new TwigFilter('attr', [$this, 'attr'], ['is_safe' => ['html']]),
            'json' => new TwigFilter('json', [$this, 'json'], ['is_safe' => ['html']]),
            'jsTemplate' => new TwigFilter('jsTemplate', [$this, 'jsTemplate'], ['is_safe' => ['html']]),

            'importFormatLabel' => new TwigFilter('importFormatLabel', [$this, 'importFormatLabel']),
            'excelColLabel' => new TwigFilter('excelColLabel', [$this, 'excelColLabel']),
        );
    }

    public function getAll()
    {
        return Roles::GetALL();
    }
    
    /**
     * @param mixed $ajaxPopup
     */
    public function shortLibelle($value, $taille = 30, $position = 'top-right', $oldTooltips = false, $ajaxPopup = true) : string
    {
        // TODO : retire or refactor $oldTooltips
        if ($oldTooltips) {
            if (mb_strlen($value)>$taille) {
                return '<span title="'.$value.' ">'.mb_substr($value, 0, $taille).'...</span>';
            } else {
                return $value??'';
            }
        }
        
        if (mb_strlen($value)>$taille) {
            return '<span class="white-tooltip" '.($ajaxPopup? 'style="cursor:pointer;" onClick="
            ajaxPopup(\''.$this->router->generateUri('Ajax.outil.contentText').'\',
             \'\', \''.urlencode($value).'\');"':'').'>
                    	'.mb_substr($value, 0, $taille).' ...
                    	<span class="infos_tooltip '.$position.' ">
            			<span class="tooltip-arrow"></span>
                            '.$value.'              			
                    	</span>
                	</span>';
        } else {
            return $value??'';
        }
    }

    /**
     * @param array<string> $routeParam
     * @param array<string> $popupParam
     */
    public function ajaxPopup(
        string $title,
        string $route,
        array $routeParam = [],
        array $popupParam = []
        // TODO : add params ?
    ) :string {
        //function ajaxPopup(path, title, divCode, divLibelle, params, width_popup)
        return 'ajaxPopup('
            . implode(',', [
                json_encode($this->router->generateUri($route, $routeParam)),
                json_encode($title),
                '""',
                '""',
                json_encode($popupParam)
            ])
            . ')';
    }
    
    public function moisHistoFournisss($value) : string
    {
        return Date::convertDateEnMois($value, $this->contenaire->get(\Helpers\Trad\ITrad::class));
    }
    
    // phpcs:disable
    public function var_dump($value)
    {
        echo '<pre>';
        var_dump($value);
        echo '</pre>';
    }
    // phpcs:enable
    
    public function remise($value, $remise = '')
    {
        if ($remise) {
            return $value - $value*$remise/100;
        } else {
            return $value;
        }
    }
    
    // pour recuperer le baseUrl de OXAPROCV2
    public function baseUrl(string $value = '')
    {
        return $this->contenaire->get('baseUrl').$value;
    }
    
    public function spliter()
    {
        return Constante::spliter;
    }

    /**
     * @return float|string|int
     */
    public function getConst(string $value)
    {
        $constant = new Constante();
        return $constant->getConst($value);
    }
    
    // pour recuperer le baseUrl de l'ancien OXAPROC
    public function base(string $value = '')
    {

        return $this->contenaire->get('base').$value;
    }
    
    public function skinCode()
    {
        // $baseURL = new OutilExtension($this->pdo, $this->contenaire, $this->router);
        $baseURL = $this->contenaire->get('baseUrl');

        $paravrac = new Paravrac($this->pdo);
        $post['colorClient1'] = $paravrac->find(['TYPEPARV' => 'OXAPROC', 'CODEPARV' => 'COLOR_CLIENT_1'])['LIB01PARV']??'';
        $post['colorClient2'] = $paravrac->find(['TYPEPARV' => 'OXAPROC', 'CODEPARV' => 'COLOR_CLIENT_2'])['LIB01PARV']??'';

        $post['colorTable'] = $paravrac->find(['TYPEPARV' => 'OXAPROC', 'CODEPARV' => 'COLOR_TABLE'])['LIB01PARV']??'';

        if (!$post['colorClient1']) {
            $post['colorClient1'] = '#89ccc5';
        }

        if (!$post['colorClient2']) {
            $post['colorClient2'] = '#0a264e';
        }

        if ($post['colorTable'] != '2') {
            $mainColor = '#7C7C7C';
            $textColor = '#fff';

            $triUp = 'url('.$baseURL.'/IconeV2/Misc/trier_up.png)';
            $triDown = 'url('.$baseURL.'/IconeV2/Misc/trier_down.png)';
            $tri = 'url('.$baseURL.'/IconeV2/Misc/trier_tableau.png)';

            $image = 'url(../IconeV2/Global/add-white.svg)';
        } else {
            $mainColor = '#fff';
            $textColor = '#000';

            $triUp = 'url('.$baseURL.'/IconeV2/Misc/trier_up_black.png)';
            $triDown = 'url('.$baseURL.'/IconeV2/Misc/trier_down_black.png)';
            $tri = 'url('.$baseURL.'/IconeV2/Misc/trier_tableau_black.png)';

            $image = 'url(../IconeV2/MenuContextuel/create.svg)';
        }
        
        $_SESSION['SESSION_SKIN_CODE_V2'] = $post['colorClient1'];
        
        $return = '<style>:root{
            --main-color-client1    : '.$post['colorClient1'].';
            --main-color-opac15     : '.$post['colorClient1'].'26;
            --main-color-opac25     : '.$post['colorClient1'].'3F;
            --main-color-opac50   : '.$post['colorClient1'].'80;

            --main-color-client2 : '.$post['colorClient2'].';
            --main-color-client2-opac50 : '.$post['colorClient2'].'80;


            --header-main-color      : '.$mainColor.';
            --header-text-color      : '.$textColor.';
            --image-add              : '.$image.';

            --triUp : '.$triUp.';
            --triDown : '.$triDown.';
            --tri : '.$tri.';
        }</style>';

        return $return;
    }


    public function googleMap($adresse, $ville)
    {
        $adresse = str_replace(" ", "+", $adresse);
        
        return "https://www.google.com/maps/place/$adresse,$ville";
    }
    
    // phpcs:disable
    public function include_file($path)
    {
        include $path;
    }
    
    public function convert_encoding($value, $val, $text)
    {
        return$value;
    }
    // phpcs:enable

    public function upperValue($value) : string
    {
        $str = strtoupper($value);
        return 'transformated-' . $str;
    }
    
    public function trad($value)
    {
        if (!is_string($value)) {
            LogSysteme::prefixErrorLog(
                (new \Exception('Expected string got "'.gettype($value).'"'))->__toString()
            );
            return '';
        }
        return $this->trad->t($value);
    }

    /**
     * @param array<string> $param
     */
    public function strBuild(string $template, array $param) :string
    {
        return Trad::strBuild($template, ...$param);
    }
    
    public function colon() :string
    {
        return $this->contenaire->get(\Helpers\Trad\ITrad::class)->colon();
    }
    
    public function tradBuild1Variable($value, $variable)
    {
        return Trad::strBuild($value, $variable);
    }
    
    /*public function withoutParenthese($value)
    {
        return substr($value, ($p = strpos($value, '(')+1), strrpos($value, ')')-$p);
    }*/
    
    public function prixUnitaire($value)
    {
        return Outils::formatPrixUnitaire($value);
    }
    
    public function prix($value)
    {
        return str_replace(' ', "\xc2\xa0", Outils::formatMontant($value));
    }
    
    public function numberFormat($value)
    {
        $value = chunk_split($value, 3, ' ');
        
        return  $value;
    }
    
    public function tva($value)
    {
        return Outils::formatMontant($value);
    }

    /**
     * @deprecated use qteByUnite instead
     * @param mixed $value
     * @return mixed
     */
    public function qte($value)
    {
        $prixDeBase = str_replace(',', '.', $value);
        
        if (!is_numeric($prixDeBase)) {
            return $value;
        }
        if ($prixDeBase) {
            $value = number_format((float)$prixDeBase, constante::qteDecimal, '.', ' ');
        } else {
            $value = '0.000';
        }
                
        return  $value;
    }

    public function qteByDecimal(string $value, string $decimal = null):string
    {
        if (!$decimal && $decimal !== '0') {
            $decimal = Constante::qteDecimal;
        } elseif ($decimal>3) {
            $decimal = Constante::qteDecimal;
        }

        $prixDeBase = str_replace(',', '.', $value);
        
        if (!is_numeric($prixDeBase)) {
            return $value;
        }
        if ($prixDeBase) {
            $value = number_format((float)$prixDeBase, (int)$decimal, '.', ' ');
        } else {
            $value = '0.000';
        }
                
        return  $value;
    }

    /**
     * @param float|string|null $qte
     * @param string|null $unite
     */
    public function qteByUnite($qte, $unite) : string
    {
        return Outils::qteByUnite($this->pdo, $qte, $unite);
    }
    
    public function montantAbreger($value)
    {
        $prixDeBase = str_replace(',', '.', $value);

        if ($prixDeBase) {
            $prixDeBase = ((float)$prixDeBase/1000);
            $value = number_format($prixDeBase, 2, '.', ' ');
        } else {
            $value = '0.00';
        }
        
        return $value;
    }
    
    public function dateTrad($date) : string
    {
        if ($date == '') {
            return '';
        }
        
        $dateObjet = new \Helpers\Outil\Date();
        $date = $dateObjet->dateConverte($date, null);
        
        if ($date=='  /  /    ') {
            return '';
        }
            
        return $date;
    }
    /**
     * Cette fonction permet de retourner la date passer en parametre sans les caractères spéciaux
     */
    public function dateOrigin($date) : string
    {
        $year=substr($date, 6, 4);
        $month=substr($date, 3, 2);
        $day=substr($date, 0, 2);
        
        $dateConvertie = $year."".$month."".$day;
        
        $dateReturn = str_replace('/', '', $dateConvertie);
        
        return $dateReturn;
    }

    public function heureTrad($heuresend) : string
    {
        if ($heuresend == '') {
            return '';
        }

        return Date::heureTrad($heuresend);
    }
    
    public function paramDateFormat(string $value = null)
    {
        $date = str_replace('j', 'd', (string)$_SESSION['DATE_FORMAT']);
        $date = str_replace('a', 'y', $date);

        if (\strpos('yyyy', $date)) {
            $date = str_replace('yyyy', 'yy', $date);
        } else {
            $date = str_replace('yyyy', 'yy', $date);
        }
            
        return $date;
    }
    
    
    public function boolTrad($value) : string
    {
        if (Sql::toBool($value)) {
            return $this->trad->t('Oui');
        }
        return $this->trad->t('Non');
    }
    public function boolSql($info) : string
    {
        return \Helpers\Outil\Sql::boolSql($info);
    }
    
    public function firstLettre($value) : string
    {
        return substr($value, 0, 1);
    }

    /**
     * @param mixed $table
     * @return int
     */
    public function lengthTable($table)
    {
        if ($table) {
            return count($table);
        }
        return 0;
    }
    
    public function substr($value, $first, $length = null)
    {
        if ($length==null || $length=='') {
            $text = substr($value, $first);
        } else {
            $text = substr($value, $first, $length);
        }
        
        return $text;
    }

    public function lienExterieur($url)
    {
        if (filter_var($url, FILTER_VALIDATE_URL)) {
            return $url;
        } else {
            return 'http://'.$url;
        }
    }

    
    public function titleHtml()
    {
        return "<title>.: Oxalys :. - ".($this->contenaire->get('version'))." (".((new ParseBase1())->getEnvName()).")</title>";
    }
    
    public function piedDePage()
    {
        $support = ($urlSupport = sql::paravrac($this->pdo, 'OXAPROC', 'SUPPORT_URL')) != ''
            ? '<a href="' . $urlSupport . '">' . $this->trad->t('Support') . '</a>'
            : '';

        $contact = ($urlContact = sql::paravrac($this->pdo, 'OXAPROC', 'CONTACT_URL')) != ''
            ? '<a href="' . $urlContact . '">' . $this->trad->t('Contact') . '</a>'
            : '';

        return "<span>".($this->contenaire->get('fullVersion'))." | Code client N°".($_SESSION['Session_NumClient']??'')." | ".($_SESSION['parametrage']['NOM_SITE_INSTALL_HAP']??'')." | ".($this->contenaire->get('copyright'))." |  ENV : ".((new ParseBase1())->getEnvName())." | ".substr($_SERVER['COMPUTERNAME'], 0, 4)."OXA" . " | " . $support . " | " . $contact . "</span>";
    }
    
    public function convertInt($value)
    {
        return (int) $value;
    }
    
    public function convertStr($value)
    {
        return (string) $value;
    }
    
    public function convertFloat($value)
    {
        return (float) str_replace(' ', '', $value);
    }

    public function replaceInID($value)
    {
        // $specCaract = array("&", "?", ">", "|", "*", "^", "<", "'", '"', "%", ".","_",'+',"-", '(',')', '@', '[', ']', ' ');
        $specCaract = array("&", "?", ">", "|", "*", "^", "<", "'", '"', "%", ".",'+',"-", '(',')', '@', '[', ']', ' ');

        foreach ($specCaract as $caract) {
            $value = str_replace($caract, '', $value);
        }

        return $this->suppr_accents($value);
    }
    
    // phpcs:disable
    public function suppr_accents($str, $encoding = 'utf-8')
    {
        // phpcs:enable
        // transformer les caractères accentués en entités HTML
        $str = htmlentities($str, ENT_NOQUOTES, $encoding);
    
        // remplacer les entités HTML pour avoir juste le premier caractères non accentués
        // Exemple : "&ecute;" => "e", "&Ecute;" => "E", "à" => "a" ...
        $str = preg_replace('#&([A-za-z])(?:acute|grave|cedil|circ|orn|ring|slash|th|tilde|uml);#', '\1', $str);
    
        // Remplacer les ligatures tel que : , Æ ...
        // Exemple "œ" => "oe"
        $str = preg_replace('#&([A-za-z]{2})(?:lig);#', '\1', $str);
        // Supprimer tout le reste
        $str = preg_replace('#&[^;]+;#', '', $str);
    
        return $str;
    }

    public function keyPathliste($str, $type = 'path')
    {
        if ($type == 'titre') {
            return $this->parameter->keyPathListeTitre($str, $this->trad);
        }
        $keyPathListe = $this->parameter->keyPathliste($str, $type);
        
        return $keyPathListe;
    }

    public function deleteSession($value)
    {
        unset($_SESSION[$value]);
    }

    public function getSession($value)
    {
        return $_SESSION[$value] ?? null;
    }

    /**
     * @param array<mixed> $param
     */
    public function attrJs(string $function, array $param) :string
    {
        return htmlspecialchars(
            $function
            . '('
                . join(',', array_map(function ($s) {
                    return (string) json_encode($s);
                }, $param))
            . ')'
        );
    }
    
    public function labelCreateur($params)
    {
        $html = '<label class="createur" '
            . $this->attr([
                'for' => 'input_'.$params['name'],
                'id' => 'label_'.$params['name'],
                'onclick' => 'changeCodeLibelle('
                    . implode(',', [
                        json_encode('input_'.$params['name']),
                        json_encode($params['code']),
                        json_encode('text_'.$params['name']),
                        json_encode($params['libelle']. ' ('.$params['code'].')'),
                    ])
                    .');'
                    . ($params['form'] ?? ''
                        ? '$(\'#'.($params['form']??'').'\').submit();'
                        : ''
                    ),
            ]) . '>'
            . htmlentities($params['titre'])
            . '&nbsp;<span class="white-tooltip icon-user">
                    <span class="infos_tooltip '.$params['orientation'].'">
                        '.htmlentities($params['textTooltip']).'
                    </span>
                </span>
            </label>';

        return $html;
    }
    
    public function iconeDocAtt($NO_DA, $id, $path)
    {
        $traduction = $this->contenaire->get(\Helpers\Trad\ITrad::class);
        switch ($NO_DA) {
            case 'FAC_ENT':
                $id = str_pad($id, 9, '0', STR_PAD_LEFT);
                $text = $traduction->t('Présence de documents rattachés pour cette facture. Cliquer pour les visualiser');
                break;
            case 'DA_ENTET':
                $id = str_pad($id, 9, '0', STR_PAD_LEFT);
                $text = $traduction->t('Présence de documents rattachés pour cette demande d\'achat. Cliquer pour les visualiser');
                break;
            case 'FAMILLE':
                $text = $traduction->t('Présence de documents rattachés pour cette famille. Cliquer pour les visualiser');
                break;
            default:
                $text = $traduction->t('Présence de documents rattachés. Cliquer pour les visualiser');
                break;
        }
        $docRatt = new \Modules\GlobalApplication\Repository\DocumentsRattaches($this->pdo);
        $listDocAtt = $docRatt->getDocRattaches($NO_DA, $id);

        $html = '';
        if (is_array($listDocAtt) && count($listDocAtt)>0) {
            $html = '<a href="'.$path.'" class="documents_attaches white-tooltip">
                        <span class="infos_tooltip top-left">
                            <span class="tooltip-arrow"></span>'.
                            $text.
                        '</span>
                    </a>';
        }
                
        return $html;
    }

    public function addslashes($value)
    {
        return addslashes($value);
    }

    public function scriptReporting()
    {
        // if(isset($_SESSION['Matomo']['ALPHA1']) && $_SESSION['Matomo']['ALPHA1']!='')
        // {
        //     return "
        //         <script>
                
        //             var _paq = _paq || [];
        //             _paq.push([function() {
        //                 var self = this;
        //                 function getOriginalVisitorCookieTimeout() {
        //                     var now = new Date(),
        //                     nowTs = Math.round(now.getTime() / 1000),
        //                     visitorInfo = self.getVisitorInfo();
        //                     var createTs = parseInt(visitorInfo[2]);
        //                     var cookieTimeout = 33696000; // 13 mois en secondes
        //                     var originalTimeout = createTs + cookieTimeout - nowTs;
        //                     return originalTimeout;
        //                 }
        //                 this.setVisitorCookieTimeout( getOriginalVisitorCookieTimeout() );
        //             }]);
                    
        //             _paq.push(['trackPageView']);
        //             _paq.push(['enableLinkTracking']);
        //             (function() {
        //                 var u='//".$_SESSION['Matomo']['ALPHA1']."/';
        //                 _paq.push(['setTrackerUrl', u+'piwik.php']);
        //                 _paq.push(['setSiteId', '".$_SESSION['Matomo']['ALPHA2']."']);
        //                 var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
        //                 g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
        //             })();
        //             </script>
        //     ";
        // }
    }
    
    public function affichageImageOxadata($path)
    {
        $chargeDocument = new ChargeDocument();
        return "<img src='".$chargeDocument->chargeDoc($this->pdo, $path, 'img', true)."'/>";
    }

    public function displayImgOxadata($path)
    {
        /**
         * TODO ModSecurity
         */
        $fileContent = $path ? file_get_contents($path): '';
        if ($fileContent) {
            $image_path = base64_encode($fileContent);
            return '<img src="data:image/x-icon;base64,'.$image_path.'" height="auto" width="50%">';
        }

        return '';
    }

    // phpcs:disable
    public function str_replace($char, $replace, $string)
    {
        // phpcs:enable
        return str_replace($char, $replace, $string);
    }
    
    public function tradDatePickers()
    {

        return "	  $.datepicker.regional['fr'] = {
            clearText: '".$this->trad->t('Effacer')."', 
            clearStatus: '',
            closeText: '".$this->trad->t('Fermer')."', 
            closeStatus: '".$this->trad->t('Fermer sans modifier')."',
            prevText: '&lt;".$this->trad->t('Préc')."', 
            prevStatus: '".$this->trad->t('Voir le mois précédent')."',
            nextText: '".$this->trad->t('Suiv')."&gt;', 
            nextStatus: '".$this->trad->t('Voir le mois suivant')."',
            currentText: '".$this->trad->t('Courant')."', 
            currentStatus: '".$this->trad->t('Voir le mois courant')."',
            monthNames: ['".$this->trad->t("Janvier")."','". $this->trad->t('Février')."','". $this->trad->t('Mars') ."','". $this->trad->t('Avril')."','".$this->trad->t('Mai')."','".$this->trad->t('Juin')."','".$this->trad->t('Juillet')."','".$this->trad->t('Août')."','".$this->trad->t('Septembre')."','".$this->trad->t('Octobre')."','".$this->trad->t('Novembre')."','".$this->trad->t('Décembre')."'],

            monthNamesShort: ['".$this->trad->t("Jan")."','". $this->trad->t('Fév')."','". $this->trad->t('Mar')."','". $this->trad->t('Avr')."','".$this->trad->t('Mai')."','".$this->trad->t('Jun')."','".$this->trad->t('Jul')."','".$this->trad->t('Aoû')."','".$this->trad->t('Sep')."','".$this->trad->t('Oct')."','".$this->trad->t('Nov')."','".$this->trad->t('Déc')."'],
            monthStatus: '".$this->trad->t('Voir un autre mois')."', 
            yearStatus: '".$this->trad->t('Voir un autre année')."',
            weekHeader: 'Sm', 
            weekStatus: '',
            dayNames: ['".$this->trad->t('Dimanche')."','".$this->trad->t("Lundi")."','". $this->trad->t('Mardi')."','". $this->trad->t('Mercredi') ."','". $this->trad->t('Jeudi')."','".$this->trad->t('Vendredi')."','".$this->trad->t('Samedi')."'],
            dayNamesMin: ['".$this->trad->t('Di')."','".$this->trad->t("Lu")."','".$this->trad->t('Ma')."','". $this->trad->t('Me') ."','".$this->trad->t('Je')."','".$this->trad->t('Ve')."','".$this->trad->t('Sa')."'],
            dayNamesShort:  ['".$this->trad->t('Dim.')."','".$this->trad->t("Lun.")."','".$this->trad->t('Mar.')."','". $this->trad->t('Mer.') ."','". $this->trad->t('Jeu.')."','".$this->trad->t('Ven.')."','".$this->trad->t('Sam.')."'],
            dayStatus: '".$this->trad->t('Utiliser DD comme premier jour de la semaine')."', 
            dateStatus: '".$this->trad->t('Choisir le DD, MM d')."',
            dateFormat: 'dd/mm/yy', 
            firstDay: 1, 
            initStatus: '".$this->trad->t('Choisir la date')."', isRTL: false};";
    }
    
    // phpcs:disable
    public function str_pad($value, $length = 9, $valeurComplement = '', $orientation = 'right')
    {
        // phpcs:disable
        switch ($orientation) {
            case 'right';
            case 'STR_PAD_RIGHT':
                $orientation = STR_PAD_RIGHT;
                break;
            case 'left';
            case 'STR_PAD_LEFT':
                $orientation = STR_PAD_LEFT;
                break;
            case 'both';
            case 'STR_PAD_BOTH':
                $orientation = STR_PAD_BOTH;
                break;
            default:
                $orientation = STR_PAD_RIGHT;
        }
        $value = str_pad($value, $length, $valeurComplement, $orientation);
        
        return  $value;
    }

    public function convertIDToInput($input)
    {
        
        $inputFinal = str_replace('.', Constante::replacePoint, $input);
        $inputFinal = str_replace(' ', Constante::replaceEspace, $inputFinal);
        
        return $inputFinal;
    }
    
    /**
     *
     * @param string $zoneHover // div qui activera le hover
     * @param string $icone     // icone a afficher °
     * @param string $onclick   // fonction a executer (redirection, open popup...) sur click
     * @param bool $onhover   // fonction a executer (redirection, open popup...) sur click
     *
     * Liste °:
     * menu_contextuel_v2
     * ajouter_v2
     * modifier_v2
     * Supprimer_v2
     * visualiser_v2
     *
     * @return string
     */
    // phpcs:disable
    public function hover_action($zoneHover, $icone, $onclick, $style = '', $tooltips = '', $tooltipV2 = '', $onhover = false)
    {
        // phpcs:enable
        $rand = random_int(0, 999999999);
        
        $html = "

            <span class='$icone  ".($tooltipV2? 'white-tooltip':'')."' data-container-contextuel='$zoneHover' style='".($zoneHover? 'opacity: 0':'opacity: 1')."; $style' " . ($onhover ? "onmouseover" : "onclick") . "=\"".htmlspecialchars($onclick)."\" title=\"$tooltips\">
                <span id='addChamps' class='infos_tooltip left'>
                <span class='tooltip-arrow'></span>$tooltipV2</span>
            </span>";
        
        return $html;
    }

    public function generateDataTooltips(string $position, string $texte, bool $container = false) : string
    {
        return '  '.($container? 'data-container="#div_tooltip"':'').' data-toggle="tooltip" data-placement="'.$position.'" data-html="true" data-original-title="'.$texte.'"';
    }

    public function buttonUpDown() : string
    {
        return '            			
            <div class="divDeplacement" style="display:none;">
                <button onClick="$(\'html,body\').animate({ scrollTop: 0},\'slow\');" type="button" class="button principal buttonDeplacer btn_double_top"></button>
                <button onClick="$(\'html,body\').animate({ scrollTop: $(document).scrollTop()-2050},\'slow\');" type="button" class="button principal buttonDeplacer btn_top"></button>
                <button onClick="$(\'html,body\').animate({ scrollTop: $(document).scrollTop()+2050},\'slow\');" type="button" class="button principal buttonDeplacer btn_bottom"></button>
                <button onClick="$(\'html,body\').animate({ scrollTop: $(document).height()},\'slow\');" type="button" class="button principal buttonDeplacer btn_double_bottom"></button>
            </div>	
            <script>
                $( ".divDeplacement" ).draggable();
                $( document ).ready(function() {
                    var sizeScreen = $( document ).height();

                    if (sizeScreen > 3000) {
                        $(\'.divDeplacement\').show();
                    }
                });
            </script>';
    }

    /**
     * attr
     * Turn a map into a lsit of html attribute (string)
     *
     * @param  array<mixed> $attr
     * @return string
     */
    public function attr($attr):string
    {
        if (empty($attr)) {
            return '';
        }
        return implode(' ', array_map(
            function ($k, $v) {
                return $k .'="'. htmlspecialchars($v) .'"';
            },
            array_keys($attr),
            $attr
        ));
    }

    /**
     * Shorthand for "| json_encode | raw"
     *
     * @param  mixed $data
     * @return string
     */
    public function json($data) :string
    {
        $s = json_encode($data);
        if ($s === false) {
            throw new \Exception(json_last_error_msg());
        }
        return $s;
    }
    
    // phpcs:ignore
    static int $uniqId = 0;
    public function uid() :int
    {
        return self::$uniqId++;
    }
    
    /**
     * @param array<mixed>|null|object $entity
     */
    public static function entityLabel($entity, string $codeField, string $labelField) :string
    {
        if (empty($entity)) {
            return '';
        }
        if (is_object($entity)) {
            $code = $entity->{ $codeField };
            $value = $entity->{ $labelField };
        } else {
            $code = $entity[ $codeField ];
            $value = $entity[ $labelField ];
        }
        if (empty($code)) {
            return '';
        }
        return $value . ' ('. $code . ')';
    }

    /**
     * Je ne saisie pas l'utilité de cette fonction ? on a déjà le convertLibelle qui retourne libelle (code) pourquoi redevelopper une fonction ?
     * @param array<mixed>|null|object $entity
     */
    public function hastutilLabel($entity) :string
    {
        return $this->entityLabel($entity, 'CODE', 'NOM');
    }
    
    public function hasRight(string $droit) :bool
    {
        return Roles::droitsUtilisateur($this->pdo, $droit) == 1;
    }

    /**
     * @return string
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    public function connexionImage()
    {

        if ($lienBG = Sql::paravrac($this->pdo, 'OXAPROC', 'PAGECNX_URLIMAGE')) {
            if (Sql::paravrac($this->pdo, 'OXAPROC', 'TYPE_HEADER_URL_RELATIVE')=='O') {
                $link = (new ParseBase1())->getPath()->oxadataWeb.$lienBG;
            } else {
                $link = $lienBG;
            }
            $image = '<img src="'.Fichier::updateImageFromSource($link).'"/>';
        } else {
            $image = '<img src="'.$this->contenaire->get('base')."V2/IconeV2/Misc/Page_Connexion_Principale.png".'"/>';
        }

        $html = '<div class="colonneImage">
    			     '.$image.'
                 </div>';

        return $html;
    }
    
    public function updateImageFromSource(string $link) : string
    {
        return Fichier::updateImageFromSource($link);
    }

    public function jsTemplate(string $content, string $id) :string
    {
        if (empty($id)) {
            throw new \Exception('Id required');
        }

        return "<script>
            if(typeof window.template !== 'object') window.template = {};
            window.template[". json_encode($id).'] = '.json_encode($content).'</script>';
    }

    public function excelColLabel(int $index) :string
    {
        return Coordinate::stringFromColumnIndex($index);
    }
    public function importFormatLabel(string $format) :string
    {
        switch ($format) {
            case 'A':
                return $this->trad->t('Alphanumérique');
            case 'N':
                return $this->trad->t('Numérique');
            case 'D':
                return $this->trad->t('Date');
            case 'L':
                return $this->trad->t('Booléen');
            case 'M':
                return $this->trad->t('Texte');
        }
        return $format;
    }

    /**
     * oxalinkUserStatut
     *
     * @param  string $oxalinkid
     * @return string
     */
    public function oxalinkUserStatut(?string $oxalinkid):string
    {
        if (!$oxalinkid) {
            return $this->trad->t('Non');
        }

        $tableauStatut = [
            'C' => $this->trad->t('En création'),
            'A' => $this->trad->t('Actif'),
            'B' => $this->trad->t('Bloqué'),
            'F' => $this->trad->t('Fermé'),
            'V' => $this->trad->t('En attente de validation'),
        ];

        $statut = $this->oxalinkUser->find($oxalinkid);

        if (!$statut) {
            return $this->trad->t('Non');
        }

        return $tableauStatut[$statut['STATUT']];
    }
}
