<?php
namespace Traits\Validator\Commande;

use Entity\Model\Parametr;
use Entity\Model\Unites;
use Helpers\Outil\Sql;
use Helpers\Trad\Trad;
use Helpers\Trad\ITrad;
use Modules\Commande\Repository\CreationCommande;
use Modules\Commande\Service\CreationCommandeService;
use Helpers\Parametres\Constante;

trait ValidatorCommandeService
{
    abstract public function getTrad() :ITrad;

    public function CAControleDA(string $value, string $nomChamp, string $societe): void
    {
        $creationCde = new CreationCommande($this->pdo);
        $daEntet = $creationCde->controleDA($value, $societe);

        $DaSigneObli = Sql::paravrac($this->pdo, 'PARAMSIG', 'NOTCREATCDEDANONSIG');

        if ($daEntet && $daEntet['countLigne'] == 0) {
            $this->setErrorNonBloquant(Trad::strBuild(
                $this->getTrad()->t('La DA @1@ ne comporte aucune ligne à commander.'),
                $value
            ));
        } elseif ($daEntet && (!Sql::boolSql($daEntet['SIGNEE']) && $DaSigneObli == 'O')) {
            $this->setError(Trad::strBuild(
                $this->getTrad()->t('La DA saisie @1@ n\'est pas signée.'),
                $value
            ));
        } elseif ($value != '' && $value !== '0' && !$daEntet) {
            $this->setError(Trad::strBuild(
                $this->getTrad()->t('Le code saisi @1@ n\'est pas présent dans la liste des @2@.'),
                $value,
                $nomChamp
            ));
        }
    }

    public function CAControleArticle(string $value, string $codeFou, string $nomChamp, bool $validation = false): void
    {
        $creationCde = new CreationCommande($this->pdo);
        $article = $creationCde->getInfoArticle($value, $codeFou);
        if ($article) {
            $articleTmp = CreationCommandeService::articleFrsGrpFrs($article);
            $ref      = $articleTmp['ref'];

            if (($article['REFARTFAB'] && $article['CODEFAB']) || ($ref && $codeFou)) {
            } else {
                $param = Sql::paravrac($this->pdo, 'PARINITDOC', 'LIENARTFOUOBLIGATOIRECDE');
                $explode = explode('|', $param);
                
                /**
                 *   1 : le contrôle est actif O/N
                 *   2 : valeur "S" le contrôle est à la saisie de cde, sinon c'est à la validation
                 *   3 : le contrôle est bloquant O/N (ou rien)
                 */
                if ($explode[0] == 'O' && ($explode[1] == 'S' || $validation)) {
                    $message = trad::strBuild($this->getTrad()->t('L\'article @1@ ne possède pas de liens fabricant/gamme ou fournisseur/référence fournisseur.'), $value);
                    if ($explode[2] == 'O') {
                        $this->setError($message);
                    } else {
                        $this->setErrorNonBloquant($message);
                    }
                }
            }
        } elseif ($value) {
            $this->setError(Trad::strBuild($this->getTrad()->t('Le code saisi @1@ n\'est pas présent dans la liste des @2@.'), $value, $nomChamp));
        }
    }
    
    public function CAControleQTE(string &$value, string $nomChamp, bool $validation = false, string $codeUnite = ''): void
    {
        /** @var array<mixed> $parameter */
        $parameter = Sql::parametr($this->pdo, 'CTRL_QTCA,BLO_QTECA,SAI_QTECA');
        

        if ($codeUnite) {
            $uniteEntity = new Unites($this->pdo);
            $unite = $uniteEntity->find($codeUnite);

            $nbrDecimalSession = Constante::qteEntier . '.' . ((int)$unite['NB_DECIM']);
        } else {
            $nbrDecimalSession = Constante::formatQTE;
        }

        $this->isFloat($nomChamp, $value, $nbrDecimalSession);

        if (Sql::boolSql($parameter['CTRL_QTCA']) && (Sql::boolSql($parameter['SAI_QTECA']) || $validation) && (trim($value)=='' || $value==0)) {
            if (Sql::boolSql($parameter['BLO_QTECA'])) {
                $message = Trad::strBuild($this->getTrad()->t('Le champ @1@ est obligatoire et doit être different de 0.'), $nomChamp);
                $this->setError($message);
            } else {
                $message = Trad::strBuild($this->getTrad()->t('Le champ @1@ est vide.'), $nomChamp);
                $this->setErrorNonBloquant($message);
            }
        }
    }

    public function CAControlePU(string &$value, string $nomChamp, bool $validation = false): void
    {
        /** @var array<mixed> $parameter */
        $parameter = Sql::parametr($this->pdo, 'CTRL_PUCA,BLO_PUCA,SAI_PUCA');
        $this->isFloat($nomChamp, $value, Constante::formatPU);

        if (Sql::boolSql($parameter['CTRL_PUCA']) && (Sql::boolSql($parameter['SAI_PUCA']) || $validation) && (trim($value)=='' || $value==0)) {
            if (Sql::boolSql($parameter['BLO_PUCA'])) {
                $message = Trad::strBuild($this->getTrad()->t('Le champ @1@ est obligatoire et doit être different de 0.'), $nomChamp);
                $this->setError($message);
            } else {
                $message = Trad::strBuild($this->getTrad()->t('Le champ @1@ est vide.'), $nomChamp);
                $this->setErrorNonBloquant($message);
            }
        }
    }

    /**
     * @param array<mixed> $accordCadre
     */
    public function CAControleDateLivraison(string &$value, string $nomChamp, bool $validation = false, $accordCadre = []) : void
    {
        $saveDate = $value;
        $config = (new Parametr($this->pdo))->getCommandeUpdateConfig()['DTE_LIV'];

        $this->isDate($value, '', '', true, $nomChamp);
        
        if ((!empty($config->validation) || $validation)
            && (trim($value)=='' || $value==0)
        ) {
            if ($config->validation == 'B') {
                $message = Trad::strBuild($this->getTrad()->t('Le champ @1@ est obligatoire.'), $nomChamp);
                $this->setError($message);
            } else {
                $message = Trad::strBuild($this->getTrad()->t('Le champ @1@ est vide.'), $nomChamp);
                $this->setErrorNonBloquant($message);
            }
        }
        
        if ($accordCadre && $value) {
            if ((
                    $accordCadre['DATE_DEB'] != '00000000'
                    && $accordCadre['DATE_DEB'] > $value
                ) || (
                    $accordCadre['DATE_FIN'] != '00000000'
                    && $accordCadre['DATE_FIN'] < $value
                )
            ) {
                $this->setError(trad::strBuild($this->getTrad()->t('La date de livraison @1@ n\'est pas dans l\'intervalle début et fin de contrat.'), $saveDate));
            }
        }
    }

    /**
     * @param array<mixed> $accordCadre
     */
    public function DAControleDateLivraison(string &$value, string $nomChamp, bool $validation = false, $accordCadre = []) : void
    {
        $saveDate = $value;
        $config = (new Parametr($this->pdo))->getDaUpdateConfig()['DTE_LIV'];
        $parameters = (new Parametr($this->pdo))->get();

        $this->isDate($value, '', '', true, $nomChamp);

        if (Sql::boolSql($parameters->SAI_DLDA)
            && (trim($value) == '' || $value == 0 || $value == '00000000')
        ) {
            if (Sql::boolSql($parameters->BLO_DLDA)) {
                $message = Trad::strBuild($this->getTrad()->t('Le champ @1@ est obligatoire.'), $nomChamp);
                $this->setError($message);
            } else {
                $message = Trad::strBuild($this->getTrad()->t('Le champ @1@ est vide.'), $nomChamp);
                $this->setErrorNonBloquant($message);
            }
        }
        
        if ($accordCadre && $value) {
            if ((
                    $accordCadre['DATE_DEB'] != '00000000'
                    && $accordCadre['DATE_DEB'] > $value
                ) || (
                    $accordCadre['DATE_FIN'] != '00000000'
                    && $accordCadre['DATE_FIN'] < $value
                )
            ) {
                $this->setError(trad::strBuild($this->getTrad()->t('La date de livraison @1@ n\'est pas dans l\'intervalle début et fin de contrat.'), $saveDate));
            }
        }
    }
}
