<?php

namespace Traits\Validator;

use Helpers\ChampsSupplementaire\ChampSupp;
use Helpers\Outil\Date;
use Helpers\Trad\ITrad;
use Helpers\Validator\Validator;
use Helpers\Outil\Sql;
use Helpers\Parametres\Constante;
use Helpers\Trad\Trad;

trait ValidatorChampSupp
{
    abstract public function getTrad() :ITrad;
    
    /**
     * @var array<mixed>
     */
    private array $listeCS;
    
    /**
     * @param array<mixed> $listeCS
     * @return void
     */
    public function setListeCS($listeCS)
    {
        $this->listeCS = $listeCS;
    }

    private bool $valueForWSDL;

    public function setValueForWSDL(bool $valueForWSDL) : void
    {
        $this->valueForWSDL = $valueForWSDL;
    }

    /**
     * validatorCS
     *
     * @param  string $codeTab
     * @param  string $codeEnreg
     * @param  array<mixed> $post : array du formulaire
     * @param  string $societe : societe (en cas de CS qui peuvent être sectorisé)
     * @param  float|int|string|null $date : cas spécial où la date de validté des CS n'est pas la date du jour
     * @param  string $codTableDifferent
     * @param  mixed $emailMultiple
     * @param  mixed $obligExterne
     * @param  string $messageComplementaire
     * @param  int|string|null $numFix
     * @param  bool|null $postVal
     * @return array<mixed>
     */
    public function validatorCS(
        $codeTab,
        $codeEnreg,
        &$post,
        \PDO $pdo,
        $societe = '',
        $date = 0,
        $codTableDifferent = '',
        $emailMultiple = false,
        $obligExterne = null,
        $messageComplementaire = '',
        $numFix = null,
        $postVal = null,
        bool $onlyNonDispo = false
    ) {
        $spliter = Constante::spliter;

        $CS = new ChampSupp($pdo);
        $Validator = new Validator($pdo, $this->getTrad());

        if (isset($this->listeCS)) {
            $listeCS = $this->listeCS;
        } else {
            $listeCS = $CS->generateChampSupp($codeTab, null, $numFix, $codTableDifferent, false, $postVal, false, null, false, true, $onlyNonDispo);
        }

        $messageComplementaire = ' '.$messageComplementaire.' ';

        $returnCS = [];
        foreach ($listeCS as $ligne_cs) {
            $key = 'CS_EXTENTION'.$spliter.$ligne_cs['COD_TAB'].$spliter.$codeEnreg.$spliter.$ligne_cs['NUM_FIX'];

            if ($ligne_cs['FORMAT']=='L') {
                $value = null;
                if (isset($post[$key])) {
                    $value = $post[$key];
                }
            } else {
                $value = $post[$key]??'';
            }

            if ($obligExterne === null || $obligExterne === '') {
                $obli = sql::boolSql($ligne_cs['OBLIG']);
            } else {
                $obli = $obligExterne;
            }

            $array = ChampSupp::getListeTableStd();

            if (Sql::toBool($ligne_cs['TBLSECTO'])) {
                if ($societe == '') {
                    $societe = $_SESSION['Session_SocUsr'];
                }

                $codeSte = $societe;
            } else {
                $codeSte = '';
            }

            $zoom=[];
            foreach ($array as $k => $v) {
                if ($k == $ligne_cs['TYPE']) {
                    $zoom=$array[$k];
                    break;
                }
            }

            if (Sql::toBool($ligne_cs['CONTROLE']) && !Sql::toBool($ligne_cs['CTRL_STD'])) {
                $Validator->validatorTSDON($ligne_cs['NOM'].$messageComplementaire, $value, $ligne_cs['TYPE'], $pdo, !$obli, $codeSte, $date);
            } elseif ($zoom) {
                if (key_exists(2, $zoom)) {
                    $where = [$zoom[2] => 'T'];
                } else {
                    $where = array();
                }
                
                $Validator->zoom($zoom[0], $value, $ligne_cs['NOM'].$messageComplementaire, $pdo, !$obli, $where);
            } elseif ($ligne_cs['FORMAT']=='D') {
                $saveDate = $value;
                $Validator->isDate($value, '', '', !$obli, $ligne_cs['NOM'].$messageComplementaire);

                $post[$key]=$saveDate;
            } elseif ($ligne_cs['FORMAT']=='N' || $ligne_cs['FORMAT']=='1') {
                $value = str_replace(' ', '', $value);
                $post[$key]=$value;
                $Validator->isFloat($ligne_cs['NOM'].$messageComplementaire, $value, $ligne_cs['PE_LONG'].'.'.$ligne_cs['PD_LONG'], $obli);
                $post[$key]=$value;
            } elseif ($ligne_cs['FORMAT']=='L') {
                $Validator->isCheck($value);

                if (isset($this->valueForWSDL) && $this->valueForWSDL) {
                    $post[$key] = $value? 'O':'N';
                } else {
                    $post[$key] = $value;
                }
            } elseif ($ligne_cs['FORMAT']=='M') {
                $Validator->isStringAvecEspace($ligne_cs['NOM'].$messageComplementaire, $value, $obli, 3000);
            } elseif ($ligne_cs['FORMAT']=='H') {
                $Validator->isHourWithSeconde($ligne_cs['NOM'].$messageComplementaire, $value, $obli);
            } elseif ($ligne_cs['FORMAT']=='E') {
                $Validator->adresseMail($ligne_cs['NOM'].$messageComplementaire, $value, $obli, 100, true);
            } elseif ($ligne_cs['FORMAT']=='U') {
                //URL
                $Validator->isUrlValide($ligne_cs['NOM'].$messageComplementaire, $value, $obli);
            } else {
                $Validator->isStringAvecEspace($ligne_cs['NOM'].$messageComplementaire, $value, $obli, ($ligne_cs['ALP_LONG']=='0'? '':$ligne_cs['ALP_LONG']));
            }

            $returnCS[$ligne_cs['NUM_FIX']] = $post[$key]??null;
        }

        $this->validate += $Validator->validate;
        $this->error .= $Validator->error;

        return $returnCS;
    }
    
    /**
     * Validator sur les CS TS_DON
     *
     * @param string $TYPE
     * @param boolean $null
     * @param string $societe
     * @param float|int|string|null $date
     * @return boolean
     */
    public function validatorTSDON(string $nomChamp, string &$value, $TYPE, \PDO $pdo, $null = false, $societe = '', $date = 0) :bool
    {
        $cs_valid = new ChampSupp($pdo);
        $params = ['CODEDICO' => $value];
        if ($societe != '' && $societe != '0') {
            // si présence du paramètre société, il faut ajouter le filtre COD_STE
            $params['COD_STE'] = $societe;
        }

        if (empty($value)) {
            if ($null) {
                return true;
            }
            if ($value!=='0') {
                $this->validate += 1;
                $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('Le champ @1@ ne peut pas être vide.'), $nomChamp);
                return false;
            }
        }
        
        
             
        $ts_don = $cs_valid->generateCSSelect($TYPE, $params, true, $date);
        if (!$ts_don) {
            $this->validate += 1 ;
            $this->error .= '<br />'.Trad::strBuild($this->getTrad()->t('Le code saisi @1@ n\'est pas présent dans la liste des @2@.'), $value, $nomChamp);
            return false;
        }
        
        return true;
    }

    /**
     * @param array<mixed> $post
     * @return void
     */
    public static function reformateDate(
        \PDO $pdo,
        string $codeTab,
        ?string $codeEnreg = null,
        ?string $numFix = null,
        ?string $codTableDifferent = null,
        &$post = [],
        string $formatOutput = ''
    ):void {
        $spliter = Constante::spliter;

        $CS = new ChampSupp($pdo);
        $listeCS = $CS->generateChampSupp($codeTab, $codeEnreg, $numFix, $codTableDifferent);
        
        foreach ($listeCS as $ligne_cs) {
            $key = 'CS_EXTENTION'.$spliter.$ligne_cs['COD_TAB'].$spliter.($codeEnreg??'').$spliter.$ligne_cs['NUM_FIX'];

            if ($ligne_cs['FORMAT']=='D') {
                if ($formatOutput == 'jj/mm/aaaa') {
                    Date::dateToSql($post[$key]);
                    $post[$key] = Date::dateConverte($post[$key], $formatOutput);
                } else {
                    Date::dateToSql($post[$key], '', '', false, 'jj/mm/aaaa');
                    $post[$key] = Date::dateConverte($post[$key], $formatOutput);
                }
            }
        }
    }
}
