<?php

namespace Modules\Panier\Validator;

use Entity\Model\OxaUserPanierImputation;
use Entity\Model\OxaUserPanierLigne;
use Entity\Model\Paravrac;
use Helpers\Log\LogSysteme;
use Helpers\Outil\Date;
use Helpers\Outil\Sql;
use Helpers\Parametres\Constante;
use Helpers\Trad\Trad;
use Helpers\Validator\Validator;
use Modules\Ajax\Repository\Listes;
use Modules\Panier\Repository\PanierEntete;
use Modules\Panier\Repository\PanierFrs;
use Modules\Panier\Service\OutilPanierService;
use Modules\Panier\Service\ValidationPanierService;

class FieldPanierValidator extends Validator
{
    //panier_ong_3.php
    //setChampModifie
    //majAxeImputation
    public function controlFields(string $fields, string &$value) : void
    {
        $infoPanier = (new PanierEntete($this->pdo))->getEntetePanier($_SESSION['id_panier'], $_SESSION['id_user']);


        //plusieurs objet on le spliter : les CS, Les lignes et les champs des blocs frs
        $idExplode = explode(Constante::spliter, $fields);
        $idLigne = null;
        if (($idExplode[1]??'') == 'ligne') {
            $idLigne = $idExplode[2];
        } /*elseif(strpos($fields, 'CS_EXTENTION') === false) {
            $codeGroupement = str_replace(Constante::oxaPipe,'|', $idExplode[1]);
        }*/

        switch ($fields) {
            case strpos($fields, 'CS_EXTENTION') === 0:
            case strpos($fields, 'text_CS_EXTENTION') === 0:
                $csField = explode(Constante::spliter, $fields);

                $fieldsCS = str_replace('text_', '', $fields);
                $array = [$fieldsCS => $value];
                $this->setValueForWSDL(true);

                $this->validatorCS(
                    $csField['1'],
                    $csField['2'],
                    $array,
                    $this->pdo,
                    $infoPanier['CODE_STE'],
                    0,
                    'PANIER',
                    false,
                    null,
                    '',
                    $csField['3']
                );

                $value = $array[$fieldsCS];
                break;
            case strpos($fields, 'CONTENU') === 0:
                $nomChamp = $this->trad->t('Clause');
                $this->isStringAvecEspace($nomChamp, $value, 0, 3000);
                break;
            case 'text_CTR_EMETT':
                $nomChamp = $this->trad->t('Centre émetteur');
                $this->zoom('Centre', $value, $nomChamp, $this->pdo, true, ['filter_egal_CODE_STE' => $infoPanier['CODE_STE']]);
                break;
            case 'CHIF_EXEC':
                $countFrs = (new PanierFrs($this->pdo))->frsProspectInPanier();

                if ($countFrs > 0) {
                    $this->setError("Un fournisseur de type prospect est présent dans le panier en cours, le changement en mode 'Exécution' n'est pas possible");
                }
                
                break;
            case 'BUDGET_DA':
                $nomChamp = $this->trad->t('Budget');
                $this->isFloat($nomChamp, $value, Constante::formatMontant, false);
                break;
            case 'text_COD_DEV':
                $nomChamp = $this->trad->t('Devise');
                $this->zoom('Devise', $value, $nomChamp, $this->pdo, false);
                break;
            case strpos($fields, 'SECTIMP') === 0:
                $nomChamp = $this->trad->t('Section d\'imputation');

                $siSecto = \Helpers\Outil\Roles::droit($this->pdo, 'SISECTOR', 'PARAMSTE');

                $this->zoom(
                    'sectimpu',
                    $value,
                    $nomChamp,
                    $this->pdo,
                    true,
                    $siSecto? ['filter_egal_CODE_STE' => $infoPanier['CODE_STE']]:[]
                );

                if ($value && $this->isValid()) {
                    $siExist = (new Listes($this->pdo))->SectionImputation([
                        'CODE_STE'          => $infoPanier['CODE_STE'],
                        'centerEmetteur'    => $infoPanier['CENTRE_EMETTEUR'],
                        'filter_egal_CODE_SI' => $value
                    ], true);

                    $this->isFalse($siExist, Trad::strBuild($this->getTrad()->t('Le code saisi @1@ n\'est pas présent dans la liste des @2@.'), $value, $nomChamp));
                }
                break;
            case strpos($fields, 'CODGES') === 0:
                $si = '';
                if ($idLigne) {
                    $infoLigne = (new OxaUserPanierLigne($this->pdo))->find($idLigne, ['SI_CODE']);
                    $si = $infoLigne['SI_CODE']??'';
                } else {
                    $idEclatement = str_replace('CODGES', '', $fields);
                    $infoEclatement = (new OxaUserPanierImputation($this->pdo))->find([
                        'id_panier' => $_SESSION['id_panier'],
                        'id_user' => $_SESSION['id_user'],
                        'id_imputation' => $idEclatement
                    ], ['SI_CODE']);

                    $si = $infoEclatement['SI_CODE']??'';
                }

                if (!$si) {
                    $si = $infoPanier['SI_CODE']??'';
                }

                $nomChamp = $this->trad->t('Code gestion');

                $arrayCG = [
                    'CODE_SI'   => $si,
                    'NUM_LOT'   => '1',
                    'CODE_STE'  => $infoPanier['CODE_STE'],
                    'cgParId'   => false,
                    'AUTHACHAT' => 1
                ];
                $this->codeGestionZoom($value, $nomChamp, $this->pdo, true, $arrayCG);

                break;
            case strpos($fields, 'CODECOMP') === 0:
                $nomChamp = $this->trad->t('Code complémentaire');
                $cdcSecto = \Helpers\Outil\Roles::droit($this->pdo, 'CDCSECTO', 'PARAMSTE');

                $this->zoom(
                    'Codecomp',
                    $value,
                    $nomChamp,
                    $this->pdo,
                    true,
                    ($cdcSecto ? ['filter_egal_CODE_STE' => $infoPanier['CODE_STE']] : [])
                );
                if ($value && $this->isValid()) {
                    $si = '';
                    if ($idLigne) {
                        $infoLigne = (new OxaUserPanierLigne($this->pdo))->find($idLigne, ['SI_CODE']);
                        $si = $infoLigne['SI_CODE']??'';
                    } else {
                        $idEclatement = str_replace('text_CODGES', '', $fields);
                        $infoEclatement = (new OxaUserPanierImputation($this->pdo))->find([
                            'id_panier' => $_SESSION['id_panier'],
                            'id_user' => $_SESSION['id_user'],
                            'id_imputation' => $idEclatement
                        ], ['SI_CODE']);

                        $si = $infoEclatement['SI_CODE']??'';
                    }

                    if (!$si) {
                        $si = $infoPanier['SI_CODE']??'';
                    }
                    
                    $cdcExist = (new Listes($this->pdo))->Cdc([
                        'filter_CODE_CDC' => $value,
                        'CODE_STE' => $infoPanier['CODE_STE'],
                        'fromPanier' => true,
                        'SI_CODE'   => $si
                    ]);
    
                    $this->isFalse($cdcExist, Trad::strBuild($this->getTrad()->t('Le code saisi @1@ n\'est pas présent dans la liste des @2@.'), $value, $nomChamp));
                }
                break;

            case strpos($fields, 'SSCPTEANA') === 0:
                $nomChamp = $this->trad->t('Sous compte d\'analyse');

                $scaSecto = \Helpers\Outil\Roles::droit($this->pdo, 'SCASECTO', 'PARAMSTE');

                $this->zoom(
                    'Sscptana',
                    $value,
                    $nomChamp,
                    $this->pdo,
                    true,
                    ($scaSecto ? ['filter_egal_CODE_STE' => $infoPanier['CODE_STE']] : [])
                );
                break;
            case strpos($fields, 'REPARTITION') === 0:
                $nomChamp = $this->trad->t('Répartition');
                $this->isFloat($nomChamp, $value, 9.2, false, '100', 0);
                break;
            case strpos($fields, 'DATEDEBCONT') === 0:
            case strpos($fields, 'DATEFINCONT') === 0:
            case strpos($fields, 'DATELIVR') === 0:
                $nomChamp = $this->trad->t('Date');
                $this->isDate($value, '', '', true);

                $traitementDA = (int) (new Paravrac($this->pdo))->getValue('PARAMGEN', 'DUREETTDA');

                if ($idLigne) {
                    $infoLigne = (new OxaUserPanierLigne($this->pdo))->find($idLigne, ['DELAI']);
                } else {
                    $infoLigne['DELAI'] = 0;
                }

                $this->isFalse(
                    self::isDateLivraisonValide($this->pdo, $value, (int)$infoLigne['DELAI'], $traitementDA, true),
                    $this->trad->t('La date de livraison ne respecte pas la durée de traitement.'),
                );

                break;
            case strpos($fields, 'COMMENT_SUIVI_ACHAT') === 0:
                $nomChamp = $this->trad->t('Commentaire');
                $this->isStringAvecEspace($nomChamp, $value, 0, 3000);
                break;
            case strpos($fields, 'DOSSIER_ACHAT_COMP') === 0:
                $this->isCheck($value);
                break;

            case strpos($fields, 'Note') === 0:
                $nomChamp = $this->trad->t('Instruction fournisseur');
                $this->isStringAvecEspace($nomChamp, $value, 0, 3000);
                break;
            case strpos($fields, 'text_MDP') === 0:
                $nomChamp = $this->trad->t('Instruction fournisseur');
                $this->zoom('Modepaie', $value, $nomChamp, $this->pdo, true);
                break;
            case strpos($fields, 'text_CDP') === 0:
                $nomChamp = $this->trad->t('Instruction fournisseur');
                $this->zoom('Condpaie', $value, $nomChamp, $this->pdo, true);
                break;
            case strpos($fields, 'text_MDL') === 0:
                $nomChamp = $this->trad->t('Instruction fournisseur');
                $this->zoom('Modelivr', $value, $nomChamp, $this->pdo, true);
                break;
            case strpos($fields, 'text_MSG_STD') === 0:
                $nomChamp = $this->trad->t('Instruction fournisseur');
                $this->zoom('Messstan', $value, $nomChamp, $this->pdo, true);
                break;
            case strpos($fields, 'text_CodeCtrLivraison') === 0:
                $nomChamp = $this->trad->t('Centre de livraison');
                $this->zoom('Centre', $value, $nomChamp, $this->pdo, true, [
                    'filter_egal_LIVRAISON' => 'T',
                    'filter_egal_CODE_STE' => $infoPanier['CODE_STE']]);

                if ($this->isValid()) {
                    $this->zoomCentreLivraisonPanier($value, $nomChamp, $infoPanier['CODE_STE']);
                }

                break;
            case strpos($fields, 'ADR') === 0:
            case strpos($fields, 'TYP_ACH') === 0:
            case strpos($fields, 'TYP_ACH_CONF') === 0:
            case strpos($fields, 'PER_REC_AUTO') === 0:
            case strpos($fields, 'MODE_TRS') === 0:
            case strpos($fields, 'OUPL_RECEPAUTO_JOUR') === 0:
            case strpos($fields, 'FIN_DEB_PER') === 0:
                break;
            default:
                if ($_SESSION['environnement'] == 'developpement') {
                    $this->setError('Champs '.$fields.' inconnu.');
                } else {
                    LogSysteme::prefixErrorLog("Panier : Champs $fields inconnu.");
                }
                break;
        }
    }

    public function controleValidationFields(string $fields, string &$value) : void
    {
        switch ($fields) {
            case 'TITRE_'.ValidationPanierService::DS:
            case 'TITRE_'.ValidationPanierService::DA:
                $nomChamps = $this->trad->t('Titre');
                $this->isStringAvecEspace($nomChamps, $value, 0, 3000);
                break;
            case 'COMMENT_INT_'.ValidationPanierService::DS:
            case 'COMMENT_INT_'.ValidationPanierService::DA:
                $nomChamps = $this->trad->t('Commentaire interne');
                $this->isStringAvecEspace($nomChamps, $value, 0, 3000);
                break;
            case 'ZONE_LIBRE_'.ValidationPanierService::DS:
            case 'ZONE_LIBRE_'.ValidationPanierService::DA:
                $nomChamps = $this->trad->t('Zone libre');
                $this->isStringAvecEspace($nomChamps, $value, 0, 30);
                break;
            case 'OBJET_'.ValidationPanierService::DS:
            case 'OBJET_'.ValidationPanierService::DA:
            case 'OBJET_'.ValidationPanierService::CDE:
                $nomChamps = $this->trad->t('Zone libre');
                $this->isStringAvecEspace($nomChamps, $value, 0, 60);
                break;
            case 'REF':
                $nomChamps = $this->trad->t('Réf. offre frs.');
                $this->isStringAvecEspace($nomChamps, $value, 0, 60);
                break;
            case 'AVENANT':
                $nomChamps = $this->trad->t('Motif avenant');
                $this->isStringAvecEspace($nomChamps, $value, 0, 120);
                break;
            case 'TYPE_DOC':
            case 'NumFactureRegulCde':
            case 'sign_spec':
                break;
            default:
                if ($_SESSION['environnement'] == 'developpement') {
                    $this->setError('Champs '.$fields.' inconnu.');
                } else {
                    LogSysteme::prefixErrorLog("Panier : Champs $fields inconnu.");
                }
                break;
        }
    }

    public static function isDateLivraisonValide(\PDO $pdo, string $date_livraison, int $delai_appro, int $delai_traitement, bool $controleSaisie = false):bool
    {
        if (sql::boolSql(Sql::parametr($pdo, 'CTRL_DLDA'))
            && (
                ($controleSaisie && sql::boolSql(Sql::parametr($pdo, 'SAI_DLDA')))
                ||
                (!$controleSaisie && sql::boolSql(Sql::parametr($pdo, 'VAL_DLDA')))
            )
            && sql::boolSql(Sql::parametr($pdo, 'BLO_DLDA'))
        ) {
            $dateLimite = OutilPanierService::getDateLivraisonMin($delai_appro, $delai_traitement);
            Date::dateToSql($date_livraison);
    
            return $date_livraison >= $dateLimite;
        }

        return true;
    }
}
