<?php
namespace TwigExtension;

use Twig\Extension\AbstractExtension;
use PDO;
use Twig\TwigFunction;
use Entity\Model\TSDon;
use Helpers\ChampsSupplementaire\ChampSupp;
use Helpers\Outil\Outils;
use Helpers\Outil\Sql;
use Helpers\Trad\ITrad;
use Psr\Container\ContainerInterface;
use Skeleton\Router;

class WorkflowExtension extends AbstractExtension
{
    protected OutilExtension $outil;
    private readonly ITrad $trad;
    
    public function __construct(protected readonly PDO $pdo, protected ContainerInterface $contenaire, private readonly Router $router)
    {
        $this->trad = $this->contenaire->get(ITrad::class);
        $this->outil = new OutilExtension($this->pdo, $this->contenaire, $this->router);
    }
    
    public function getFunctions()
    {
        return [
            new TwigFunction('visuOldValueWF', $this->visuOldValueWF(...), [
                'is_safe' => [
                    'html'
                ]
            ]),
            new TwigFunction('visuWFAdvance', $this->visuWFAdvance(...), [
                'is_safe' => [
                    'html'
                ]
            ]),
        ];
    }


    /**
     * @param array<mixed> $array
     * @return string|mixed
     */
    public function visuWFAdvance($array)
    {
        return $this->visuOldValueWF(
            $array['value']??'',
            $array['enSuivi']??'',
            $array['tooltipDirection']??'',
            $array['infoBulle']??'',
            $array['type']??'',
            $array['entity_fonction']??'',
            $array['libelle_fonction']??'',
            $array['fonction']??'',
            $array['compareValue']??false,
            $array['codeTab']??'',
            $array['numfix']??''
        );
    }

    /**
     * Fonction permet de voir si la valeur d'un champ est differente de ca valeurModif
     * si c'est le cas on affiche une infobulle avec l'ancienne valeur
     *
     * @param mixed $value                 : valeur affichage (généralement objet XML contenant le tag valeurModif)
     * @param bool $enSuivi                 : indique si on doit effectué le traitement ou pas
     * @param string $tooltipDirection      : direction de la tooltip (right/left/bottom/top)
     * @param boolean $infoBulle            : tooltips de l'ancienne valeur actif ou pas ? par defaut non
     * @param string $type                  : si l'objet retourné est une date / une entity (code/libelle) / ou une fonction, on le spéficie pour traite l'affichage de la valeur
     * @param string $entity_fonction       : si le $type est une entity on spéficie l'entity pour la requete
     * @param string $libelle_fonction      : si le $type est une entity, on spéficie le libelle si il ne l'ai pas dans l'entity
     * @param string $fonction              : si le $type est une fonction, on spéficie la fonction a appeler
     * @param boolean $compareValue         : si la $value est pas un objet XML, on spéficie la valeur a comparé pour l'affichage ou non de l'ancienne valeur
     * @param string $codTab               : table CS
     * @param string $numFix                : num fix cs
     * @return string|mixed
     */
    public function visuOldValueWF(
        $value,
        $enSuivi,
        $tooltipDirection = 'right',
        $infoBulle = false,
        $type = '',
        $entity_fonction = '',
        $libelle_fonction = '',
        $fonction = '',
        $compareValue = false,
        $codTab = '',
        $numFix = ''
    ) {

        if ($infoBulle && !$enSuivi) {
            return '';
        }
        
        if ($compareValue===false) {
            $valueBase = strval($value);
            $valeurModif=$value;
            if (!is_null($value) && $value->attributes()) {
                $valeurModif = strval($value->attributes()->ValeurModif);
            } else {
                $valeurModif=$value;
            }
        } else {
            $valueBase = strval($value);
            $valeurModif = strval($compareValue);
        }
        
        if ($type=='convertLibelleGlobal') {
            $convertLibelle = new ConvertLibelleExtension($this->pdo);
            
            $valueBase = $convertLibelle->convertLibelleGlobal($entity_fonction, $libelle_fonction, $valueBase). ' ('.$valueBase.')';

            $valeurModif = $convertLibelle->convertLibelleGlobal($entity_fonction, $libelle_fonction, $valeurModif). ' ('.$valeurModif.')';
        } elseif ($type=='fonction') {
            $valueBase = $this->outil->$fonction($valueBase);
            $valeurModif = $this->outil->$fonction($valeurModif);
        } elseif ($type=='date') {
            $valueBase = $this->outil->dateTrad($valueBase);
            $valeurModif = $this->outil->dateTrad($valeurModif);
        } elseif ($type=='LOGIQUE') {
            $valueBase = $this->outil->boolTrad($valueBase);
            $valeurModif = $this->outil->boolTrad($valeurModif);
        }
        
        $valeurModif = $valeurModif=='0'? '':$valeurModif;
        
        if (!$infoBulle && ($valueBase=='' || $valueBase=='0') && ($valeurModif=='' || $valeurModif=='0')) {
            $return = str_replace(' ()', '', $valueBase);
            
            return str_replace(' (0)', '', $return);
        }

        if (($valueBase!=$valeurModif) && $enSuivi) {
            $trad = $this->trad;

            $valueBase = $this->getLibelleCS($codTab, $numFix, $valueBase);
            $valeurModif = $this->getLibelleCS($codTab, $numFix, $valeurModif);

            if ($infoBulle || !$valueBase) {
                $affichage = '<img src="'.$this->contenaire->get('baseUrl').'/IconeV2/Gestion/info.svg">';
            } else {
                $affichage = str_replace(' ()', '', $valueBase);
            }

            $valeurModif = $this->getLibelleCS($codTab, $numFix, $valeurModif);
            
            return' <span class="white-tooltip align-right '.(($infoBulle)? 'wf_tooltip':'background-jaune').'">'.$affichage.'
                    <span class="infos_tooltip '.$tooltipDirection.'" >
                        <span class="tooltip-arrow"></span>
                        '.($valeurModif==''? ($trad->t('Aucune valeur précédente trouvée.')):($trad->t('Valeur précédente').' : </br> '.$valeurModif)).'
                    </span></span>';
        } elseif (!$infoBulle) {
            $valueBase = $this->getLibelleCS($codTab, $numFix, $valueBase);
            $return = str_replace(' ()', '', $valueBase);
            return str_replace(' (0)', '', $return);
        }

        return '';
    }

    private function getLibelleCS(string $codeTab, string $numFix, string $value, string $societe = '') : string
    {
        if ($codeTab) {
            $infoCS = (new ChampSupp($this->pdo))->getInfoCS($codeTab, $numFix);
            if ($infoCS['FORMAT'] == 'A' && Sql::boolSql($infoCS['CONTROLE'])) {
                if (Sql::boolSql($infoCS['CTRL_STD'])) {
                    $zoom = ChampSupp::getListeTableStd()[ $infoCS['TYPE'] ][0];
                    
                    $findValue = Outils::convertLibelleGlobal($this->pdo, $zoom, '', $value, true);

                    if ($findValue) {
                        return $findValue;
                    }
                } else {
                    $tsDon = new TSDon($this->pdo);
    
                    if (Sql::boolSql($infoCS['TBLSECTO']) && $societe) {
                        $idTsDon = ['TYPEDICO' => $infoCS['TYPE'], 'CODEDICO' => $value, 'COD_STE' => $societe];
                    } else {
                        $idTsDon = ['TYPEDICO' => $infoCS['TYPE'], 'CODEDICO' => $value];
                    }
    
                    $findValue = $tsDon->find($idTsDon);
                    if ($findValue) {
                        return $findValue['LIB01DICO'].' ('.$findValue['CODEDICO'].')';
                    }
                }
            }
        }

        return $value;
    }
}
