<?php

namespace Modules\Evaluation\Controller;

use Entity\Model\BibGrpNot;
use Entity\Model\BibQstTh;
use Entity\Model\CampGrpNot;
use Entity\Model\CampQstTh;
use Entity\Model\GrilGrpNot;
use Modules\Evaluation\Service\CampaignService;
use Modules\Evaluation\Service\QuestionService;
use Skeleton\Controller\Controller;
use Modules\ProjetAchat\Repository\Action;
use Helpers\Ariane\Ariane;
use GuzzleHttp\Psr7\Response;
use Entity\Model\BibQstQ;
use Entity\Model\CampQstQ;
use Entity\Model\AoQstQ;
use Helpers\Outil\Sql;
use Modules\Evaluation\Repository\BibliothequeDeQuestions;
use Entity\Model\BibQstR;
use Entity\Model\CampQstR;
use Entity\Model\AoQstR;
use Entity\Model\CampQstDep;
use Entity\Model\GrilQstQ;
use Entity\Model\GrilQstR;
use Entity\Model\GrilTheme;
use Helpers\Ariane\ArianeSub;
use Helpers\Outil\Roles;
use Helpers\Pagination\Paginator;
use Helpers\Trad\ITrad;
use Helpers\Trad\Trad;
use Modules\Consultation\Repository\GestionConsultation;
use Modules\Consultation\Repository\AoEvent;
use Modules\Evaluation\Repository\Evaluation;
use Modules\Evaluation\Repository\Model;
use Modules\Evaluation\Repository\Question;
use Modules\Evaluation\Service\BibliothequeService;
use Modules\Evaluation\Service\EvaluationService;
use PDO;
use Helpers\Session\Enums\MenuTopEnum;
use Helpers\Session\Session;

class QuestionController extends Controller
{
    /**
     * @var array<mixed>
     */
    protected array $droits = [];

    /**
     * init
     * gestion des droits
     *
     * @return void
     */
    public function init()
    {
        $droits = [
            'HA_MQUESCM' => Roles::droitsUtilisateur($this->pdo, 'HA_MQUESCM', $_SESSION["Session_Login"]), // Droit de création et modification des modèles et les catégories de modèles
            'HA_CEVAVIS' => Roles::droitsUtilisateur($this->pdo, 'HA_CEVAVIS', $_SESSION["Session_Login"]), // Droit de visu des campagnes
            'HA_CEVALCM' => Roles::droitsUtilisateur($this->pdo, 'HA_CEVALCM', $_SESSION["Session_Login"]), // Droit de création et modification des campagnes
            'HA_CEVASUP' => Roles::droitsUtilisateur($this->pdo, 'HA_CEVASUP', $_SESSION["Session_Login"]), // Droit de suppression des campagnes d'évaluation
            'HA_BIBQTCM' => Roles::droitsUtilisateur($this->pdo, 'HA_BIBQTCM', $_SESSION["Session_Login"]), // Droit de création et modification de questionnaire
        ];

        $this->droits = $droits;
    }

    public function createEditAction(): string
    {
        $mode           = $this->request->getAttribute('mode');
        $idMode         = $this->request->getAttribute('idMode');
        $idTheme        = $this->request->getAttribute('idTheme');
        $idQuestion     = $this->request->getAttribute('idQuestion');
        $campaign       = [];

        $trad = $this->getTranslationService();

        $listeTypeRep['O'] = $trad->t('Texte');
        $listeTypeRep['N'] = $trad->t('Matrice réponse numérique / note');
        $listeTypeRep['L'] = $trad->t('Oui/non');
        $listeTypeRep['T'] = $trad->t('Matrice liste de réponses / notes');
        $listeTypeRepPourFournisseur = $listeTypeRep;

        $listeTypeNombre = [
            'N' => $trad->t('Normal'),
            'P' => $trad->t('Pourcentage'),
            'M' => $trad->t('Montant'),
        ];

        $listeRegleN = [
            '' => $trad->t('Rien'),
            'S' => $trad->t('Supérieur à'),
            'I' => $trad->t('Inférieur à'),
            'E' => $trad->t('Egal à'),
            'T' => $trad->t('Entre'),
        ];

        $listeRegleL = [
            'N' => $trad->t('Non'),
            'V' => $trad->t('Si "Oui"'),
            'F' => $trad->t('Si "Non"'),
            'T' => $trad->t('Toujours'),
        ];

        $listePour = [
            'F' => 'Fournisseur',
            'A' => 'Acheteur',
        ];

        $tagsListforCalculatedAnswer = [
            $trad->t('Tag Utilisateur'),
            $trad->t('Tag Société'),
            $trad->t('Tag Période'),
            $trad->t('Tag Fournisseur'),
        ];

        $count = 0;

        $questionRepository = new Question($this->pdo);
        $libraryRepository = new BibliothequeDeQuestions($this->pdo);

        if ($mode == 'question') {
            $menuLeft = '';
            $menuActive = Session::verifySessionTypeMenuTop(MenuTopEnum::S2C) ? 'Consultations' : 'Evaluations';
            $titre = $trad->t('Gestion de la Bibliothèque');
            $subTitle = $trad->t('Création question');
            Ariane::generate(1, $trad->t('Nouvelle Question'), []);

            $listeNoeur = [
                'N' => $trad->t('Evaluateur'),
                'D' => $trad->t('Demandeur'),
                'C' => $trad->t('Dépouilleur'),
            ];
        } elseif ($mode == 'campagne') {
            $arianeSubTitle = $idQuestion ? $trad->t('Modification Question') : $trad->t('Nouvelle Question');
            ArianeSub::generate(2, 1, $arianeSubTitle, 'Evaluation.Question.creatEdit', 1, []);
            $menuLeft = 'ratings';
            $menuActive = Session::verifySessionTypeMenuTop(MenuTopEnum::S2C) ? 'Consultations' : 'Evaluations';
            $campaign = (new CampaignService($this->pdo, $this->getTranslationService()))
                ->campaignDetail(
                    $idMode,
                    $this->router,
                    $this->droits
                );

            $campQstA = new CampQstQ($this->pdo);
            $count = $questionRepository->isDependencyAllowed($mode, $idMode);

            $listeNoeur = [
                'N' => $trad->t('Evaluateur'),
                'C' => $trad->t('Dépouilleur'),
            ];
        } elseif (in_array($mode, ['AO', 'AO_CONTRIB'])) {
            $menuLeft = 'gestionAO';
            $menuActive = Session::verifySessionTypeMenuTop(MenuTopEnum::P2P) ? 'eproc' : 'Consultations';
            $titre = $trad->t('Gestion consultations');
            $subTitle = $trad->t('Création question');

            $gestionConsu = new GestionConsultation($this->pdo);
            $consultation = $gestionConsu->getInfoAo($idMode);

            $aoEvent = new AoEvent($this->pdo);
            $AOEventCreat = $aoEvent->getNameCreate($idMode);

            ArianeSub::generate(1, 0, $trad->t('Création Question'), $_SERVER['REQUEST_URI'], 1);
        } elseif ($mode == 'modele') {
            $menuLeft = 'modele';
            $modelRepo = new Model($this->pdo);
            $model = $modelRepo->modelDetail($idMode);
            $menuActive = Session::verifySessionTypeMenuTop(MenuTopEnum::S2C) ? 'Consultations' : 'Evaluations';
            $titre = $trad->t('Gestion modèles');
            $subTitle = $trad->t('Création question');
            $modelQstQ = new GrilQstQ($this->pdo);
            $count = $questionRepository->isDependencyAllowed($mode, $idMode);

            $listeNoeur = [
                'N' => $trad->t('Evaluateur'),
                'D' => $trad->t('Demandeur'),
                'C' => $trad->t('Dépouilleur'),
            ];
            ArianeSub::generate(1, 0, $trad->t('Création Question'), $_SERVER['REQUEST_URI'], 1);
        }

        if (!in_array($mode, ['AO', 'AO_CONTRIB'])) {
            $listeTypeRep['C'] = $trad->t('Issue de la base de données');

            $listeOrigineNoteur = [
                'O' => $trad->t('À partir d\'un objet associé'),
                'P' => $trad->t('À partir d\'un profil'),
                'G' => $trad->t('À partir d\'un groupe'),
                'N' => $trad->t('Évaluateur nommé'),
            ];
        }

        $pathBack = $this->router->generateUri('Evaluation.BibliothequeDeQuestions.gestionBibliotheque', ['mode' => $mode, 'idCamp' => $idMode]);
        if ($mode == 'AO_CONTRIB') {
            $pathBack = $this->router->generateUri(
                'Evaluation.BibliothequeDeQuestions.gestionBibliothequeAoContrib',
                ['mode' => $mode, 'idAO' => $idMode]
            );
        }

        $question = [];
        $dependency = [];
        if ($idQuestion) {
            if ($mode == 'question') {
                $bibQstQ = new BibQstQ($this->pdo);
                $question = $bibQstQ->find(['ID_QUEST' => $idQuestion]);
                $bibQstR = new BibQstR($this->pdo);
                $listeReponse = $bibQstR->fetchAll([], ['filter_egal_ID_QUEST' => $idQuestion, 'tri_ID_REP' => 'ASC']);
            } elseif ($mode == 'campagne') {
                $campQstA = new CampQstQ($this->pdo);
                $question = $campQstA->find(['ID_CAMP' => $idMode, 'ID_THEME' => $idTheme,  'ID_QUEST' => $idQuestion], [], [], PDO::FETCH_ASSOC);
                $campQstR = new CampQstR($this->pdo);
                $listeReponse = $campQstR->fetchAll([], ['filter_egal_ID_CAMP' => $idMode, 'filter_egal_ID_THEME' => $idTheme, 'filter_egal_ID_QUEST' => $idQuestion, 'tri_ID_REP' => 'ASC']);
                $count = $questionRepository->isDependencyAllowed($mode, $idMode);
                $isDependentQuestion = $libraryRepository->isDependentQuestion($idMode, $idTheme, $idQuestion);
                if (\count($isDependentQuestion) > 0) {
                    $campQstDep = new CampQstDep($this->pdo);
                    $dependency = $campQstDep->find(['ID_CAMP' => $idMode, 'ID_THEME_DEP' => $idTheme, 'ID_QST_DEP' => $idQuestion]);
                    $question['QST_DEP'] = 'on';
                    $dependency['ID_QST_PARENT'] = $idMode . '~~' . $isDependentQuestion[0]['ID_THEME_PARENT'] . '~~' . $isDependentQuestion[0]['ID_QST_PARENT'];
                    if ($dependency['RULE_TYPE'] == 'LI') {
                        $answersList = $questionRepository->getAnswersList($idMode, $isDependentQuestion[0]['ID_THEME_PARENT'], $isDependentQuestion[0]['ID_QST_PARENT']);
                        $dependency['ANSWERS_CHECKED'] = \explode(' | ', $dependency['MIN_VALUE']);
                        $selectedCount = \count($dependency['ANSWERS_CHECKED']);
                    }
                    $parentQuestion = $questionRepository->getParentQuestionId($idMode, $isDependentQuestion[0]['ID_THEME_PARENT'], $isDependentQuestion[0]['ID_QST_PARENT']);

                    $basisRuleList = [
                        'N' => $trad->t('Note'),
                        'R' => $trad->t('Réponse'),
                    ];

                    $ruleTypesListN = [
                        'EQ'    => $trad->t('égale à'),
                        'BE'    => $trad->t('comprise entre'),
                        'GR'    => $trad->t('supérieure à'),
                        'LE'    => $trad->t('inférieure à'),
                        'DI'    => $trad->t('différente de'),
                    ];

                    $ruleTypesListR = [
                        'AN'    => $trad->t('Réponse'),
                        'LI'    => $trad->t('Liste de réponses'),
                    ];

                    switch ($parentQuestion['TYPE_REP']) {
                        case 'N':
                            $ruleTypesListR = $ruleTypesListN;
                            break;

                        case 'L':
                            $ruleTypesListR = [
                                'AN'    => $trad->t('Réponse'),
                            ];
                            $answersList = [
                                1 => $trad->t('Oui'),
                                0 => $trad->t('Non')
                            ];
                            break;

                        case 'T':
                            $ruleTypesListR = [
                                'LI'    => $trad->t('Liste de réponses'),
                            ];
                            $answersList = $questionRepository->getAnswersList($idMode, $isDependentQuestion[0]['ID_THEME_PARENT'], $isDependentQuestion[0]['ID_QST_PARENT']);
                            break;

                        case 'C':
                            $ruleTypesListR = $ruleTypesListN;
                            break;

                        default:
                            break;
                    }
                }
            } elseif (in_array($mode, ['AO', 'AO_CONTRIB'])) {
                $AoQstA = new AoQstQ($this->pdo);
                $question = $AoQstA->find(['NO_AO' => $idMode, 'ID_THEME' => $idTheme,  'ID_QUEST' => $idQuestion]);
                $aoQstR = new AoQstR($this->pdo);
                $listeReponse = $aoQstR->fetchAll([], ['filter_egal_NO_AO' => $idMode, 'filter_egal_ID_THEME' => $idTheme,
                    'filter_egal_ID_QUEST' => $idQuestion, 'tri_ID_REP' => 'ASC']);
            } elseif ($mode == 'modele') {
                $modelQstQ = new GrilQstQ($this->pdo);
                $question = $modelQstQ->find(['ID_MODEL' => $idMode, 'ID_THEME' => $idTheme,  'ID_QUEST' => $idQuestion]);
                $modelQstR = new GrilQstR($this->pdo);
                $modelRepo = new Model($this->pdo);
                $model = $modelRepo->modelDetail($idMode);
                $listeReponse = $modelQstR->fetchAll([], ['filter_egal_ID_QUEST' => $idQuestion, 'tri_ID_REP' => 'ASC']);
                $count = $questionRepository->isDependencyAllowed($mode, $idMode);
                $subTitle = $trad->t('Modification Question');
                ArianeSub::generate(1, 0, $trad->t('Modification Question'), $_SERVER['REQUEST_URI'], 1);
            }

            if ($question['NUM_FORMAT']) {
                $explodNumFormat = explode('.', $question['NUM_FORMAT']);
                $question['A_LONG'] = $explodNumFormat[0];
                $question['N_PARTIE_DEC'] = $explodNumFormat[1];
            }

            if (!in_array($mode, ['AO', 'AO_CONTRIB'])) {
                if (strpos($question['PROFNOTEUR1'], 'OBJ|') === 0) {
                    $PROFNOTEUR0 = 'O';
                } elseif ($question['PROFNOTEUR1'] == 'G' || $question['PROFNOTEUR1'] == 'N') {
                    $PROFNOTEUR0 = $question['PROFNOTEUR1'];
                    if ($question['PROFNOTEUR1'] == 'G') {
                        $title = $trad->t('Groupes d\'évaluateurs');
                    }
                } else {
                    $PROFNOTEUR0 = 'P';
                }
                $listeNoteur = (new QuestionService($this->pdo, $this->getTranslationService()))
                    ->_getListOfOriginOfRaters($PROFNOTEUR0, $mode, $idMode);
                if ($PROFNOTEUR0 === 'O') {
                    $listeNoteurObject = $this->getListeNoteurByOrigine(
                        $question['PROFNOTEUR1'],
                        $mode,
                        $idMode,
                        $this->getTranslationService(),
                        $this->pdo
                    );
                }
            }

            if ($mode != 'modele' && $mode != 'campagne') {
                $question['COMMENTAIRE'] = sql::getMemo($this->pdo, $question['NM_COM']);
            }
        }

        if (!in_array($mode, ['AO', 'AO_CONTRIB'])) {
            // si on n'est pas en modif, on récupère l'origine noteur du thème pour le passer en héritage à la question
            if (!$idQuestion) {
                if ($mode == 'question') {
                    $question = (new BibQstTh($this->pdo))->find($idTheme, ['PROFNOTEUR1', 'PROFNOTEUR2']);
                } elseif ($mode == 'campagne') {
                    $question = (new CampQstTh($this->pdo))->find(['ID_CAMP' => $idMode, 'ID_THEME' => $idTheme], ['PROFNOTEUR1', 'PROFNOTEUR2']);
                } elseif ($mode == 'modele') {
                    $question = (new GrilTheme($this->pdo))->find(['ID_MODEL' => $idMode, 'ID_THEME' => $idTheme], ['PROFNOTEUR1', 'PROFNOTEUR2']);
                }
            }
            
            if (strpos($question['PROFNOTEUR1'], 'OBJ|') === 0) {
                $PROFNOTEUR0 = 'O';
            } elseif ($question['PROFNOTEUR1'] == 'G' || $question['PROFNOTEUR1'] == 'N') {
                $PROFNOTEUR0 = $question['PROFNOTEUR1'];
                if ($question['PROFNOTEUR1'] == 'G') {
                    $title = $trad->t('Groupes d\'évaluateurs');
                }
            } else {
                $PROFNOTEUR0 = 'P';
            }
            $listeNoteur = (new QuestionService($this->pdo, $this->getTranslationService()))
                ->_getListOfOriginOfRaters($PROFNOTEUR0, $mode, $idMode);
            if ($PROFNOTEUR0 === 'O') {
                $listeNoteurObject = $this->getListeNoteurByOrigine(
                    $question['PROFNOTEUR1'],
                    $mode,
                    $idMode,
                    $this->getTranslationService(),
                    $this->pdo
                );
            }
        }

        return $this->renderer->render('@Evaluation/Question/createEdit', [
            'menuLeft'                      => $menuLeft ?? '',
            'menuActive'                    => $menuActive ?? '',
            'titre'                         => $titre ?? '',
            'title'                         => $title ?? '',
            'pathBack'                      => $pathBack,
            'subTitle'                      => $subTitle ?? '',
            'listeTypeRepPourFournisseur'   => $listeTypeRepPourFournisseur,
            'listeTypeRep'                  => $listeTypeRep,
            'listeTypeRepPourFour'          => $listeTypeRep,
            'listeNoeur'                    => $listeNoeur ?? [],
            'listeTypeNombre'               => $listeTypeNombre,
            'listeRegleN'                   => $listeRegleN,
            'listeRegleL'                   => $listeRegleL,
            'count'                         => $count,

            'mode'                          => $mode,
            'idMode'                        => $idMode,
            'idTheme'                       => $idTheme,
            'idQuestion'                    => $idQuestion,

            'consultation'                  => $consultation ?? [],
            'AOEventCreat'                  => $AOEventCreat ?? [],
            'listePour'                     => $listePour,
            'question'                      => $question,
            'listeReponse'                  => $listeReponse ?? [],
            'listeOrigineNoteur'            => $listeOrigineNoteur ?? [],
            'listeNoteur'                   => $listeNoteur ?? [],
            'listeNoteurObject'             => $listeNoteurObject ?? [],
            'PROFNOTEUR0'                   => $PROFNOTEUR0 ?? '',
            'PROFNOTEUR1'                   => $question['PROFNOTEUR1'] ?? '',
            'PROFNOTEUR2'                   => $question['PROFNOTEUR2'] ?? '',
            'tagsList'                      => $tagsListforCalculatedAnswer,

            'dependency'                    => $dependency,
            'basisRuleList'                 => $basisRuleList ?? [],
            'ruleTypesList'                 => $ruleTypesListN ?? [],
            'ruleTypesListR'                => $ruleTypesListR ?? [],
            'answers'                       => $answersList ?? [],
            'selectedCount'                 => $selectedCount ?? 0,

            'campaign'                      => $campaign,
            'modele'                        => $model ?? [],
            'droits'                        => $this->droits,
            'deleteMessage'                 => $trad->t('Voulez-vous supprimer la campagne @1@ ?'),
        ]);
    }

    public function addResponseAction(): string
    {
        $post = $this->request->getParsedBody();
        $mode = $this->request->getAttribute('mode');

        $lastId = $post['lastId'] ?? '0';

        return $this->renderer->render('@Evaluation/Question/ajaxLigneReponse', [
            'mode' => $mode,
            'rep' => ['ID_REP' => (int) $lastId + 1]
        ]);
    }

    public function addNoteAction(): string
    {
        $post = $this->request->getParsedBody();

        $trad = $this->getTranslationService();

        if (isset($post['lastId'])) {
            $lastId = (int) $post['lastId'] + 1;
            $note = ['ID_REP' => $lastId];
        } else {
            $lastId = 0;
            $note = ['ID_REP' => $lastId, 'TXT_REP' => $trad->t('Note de base')];
        }

        return $this->renderer->render('@Evaluation/Question/ajaxLigneNote', [
            'note' => $note,
        ]);
    }

    public function addExpectedAnswerAction(): string
    {
        $post = $this->request->getParsedBody();

        if (isset($post['lastId'])) {
            $lastId = (int) $post['lastId'] + 1;
        } else {
            $lastId = 0;
        }
        $answer = ['ID_REP' => $lastId];

        return $this->renderer->render('@Evaluation/Question/ajax-new-answer-line', [
            'answer' => $answer,
        ]);
    }

    public function checkRequestAction(): string
    {
        $post = $this->request->getParsedBody();
        $validator = $this->createValidator();
        $bibliothequeService = new BibliothequeService();

        $trad = $this->getTranslationService();

        if ($validator->checkIfRequestIsSafe($post['REPCALC_SELECT'])) {
            if (!$bibliothequeService->checkIfSqlRequestWorks($post['REPCALC_SELECT'], $post['REPCALC_REQ'], $this->pdo)) {
                return $this->renderer->render('@popup-erreur/erreurAlerteEtAvertissement', [
                    'params' => [
                        'alerte'    => $trad->t('La requête ne peut pas être exécutée.')
                    ]
                ]);
            } else {
                return $this->renderer->render('@popup-erreur/information', [
                    'message' => $trad->t('La requête est valide'),
                ]);
            }
        } else {
            return $this->renderer->render('@popup-erreur/erreurAlerteEtAvertissement', [
                'params' => [
                    'alerte'    => $trad->t('La requête contient des termes interdits.')
                ]
            ]);
        }
    }

    /**
     * validateAction
     *
     * @return string|Response
     */
    public function validateAction(
        BibQstQ $bibQstQ,
        CampQstQ $campQstQ,
        AoQstQ $aoQstQ,
        GrilQstQ $grilQstQ,
        BibQstR $bibQstR,
        CampQstR $campQstR,
        AoQstR $aoQstR,
        GrilQstR $grilQstR,
        CampQstDep $campQstDep,
        BibliothequeService $bibliothequeService,
        BibliothequeDeQuestions $bibliothequeRepo,
    ) {
        $mode           = $this->request->getAttribute('mode');
        $idMode         = $this->request->getAttribute('idMode');
        $idTheme        = $this->request->getAttribute('idTheme');
        $idQuestion     = $this->request->getAttribute('idQuestion');

        $post = $this->request->getParsedBody();
        $validator = $this->createValidator();

        /** @var array<mixed> $arrayQuestion */
        $arrayQuestion = [];

        $trad = $this->getTranslationService();

        if (isset($post['QUEST_FOUR']) && $post['QUEST_FOUR'] == 'on') {
            $post['TYPE_REP'] = $post['TYPE_REP_FOUR'];
        }

        // si questionnaire soumissionnaire et non contributeur, on force question fournisseur à vrai car on ne l'affiche plus sur le formulaire
        if ($mode == 'AO') {
            $post['QUEST_FOUR'] = 'on';
        }

        if ($idQuestion) {
            $saveQuestion = [];
            $saveDependency = [];
            if ($mode == 'question') {
                $saveQuestion = $bibQstQ->find(['ID_QUEST' => $idQuestion]);
            } elseif ($mode == 'campagne') {
                $saveQuestion = $campQstQ->find(['ID_CAMP' => $idMode, 'ID_THEME' => $idTheme,  'ID_QUEST' => $idQuestion], [], [], PDO::FETCH_ASSOC);
                $saveDependency = $campQstDep->find(['ID_CAMP' => $idMode, 'ID_THEME_DEP' => $idTheme, 'ID_QST_DEP' => $idQuestion], [], [], PDO::FETCH_ASSOC);
            } elseif (in_array($mode, ['AO', 'AO_CONTRIB'])) {
                $saveQuestion = $aoQstQ->find(['NO_AO' => $idMode, 'ID_THEME' => $idTheme,  'ID_QUEST' => $idQuestion]);
            } elseif ($mode == 'modele') {
                $saveQuestion = $grilQstQ->find(['ID_MODEL' => $idMode, 'ID_THEME' => $idTheme,  'ID_QUEST' => $idQuestion]);
            }

            if ($mode == 'AO') {
                $post['QUEST_FOUR'] = 'on';
                if (Sql::toBool($saveQuestion['QUEST_FOUR'])) {
                    $post['TYPE_REP'] = $post['TYPE_REP_FOUR'];
                } else {
                    $post['TYPE_REP_FOUR'] = $post['TYPE_REP'];
                }
            }

            if ($post['TYPE_REP'] != $saveQuestion['TYPE_REP']) {
                if (!in_array($mode, ['AO', 'AO_CONTRIB'])) {
                    $arrayQuestion['QUEST_FOUR'] = false;
                    $arrayQuestion['AUTHCOMMENT'] = false;
                    $arrayQuestion['OUV_NAPOSS'] = false;
                    $arrayQuestion['OUV_NOTEPAR'] = '';
                    $arrayQuestion['REGCOMOBLIG'] = '';
                    $arrayQuestion['TYP_NOMBRE'] = '';
                }

                $arrayQuestion['NUM_FORMAT'] = '';
                $arrayQuestion['NUM_MIN'] = '';
                $arrayQuestion['NUM_MAX'] = '';
                $arrayQuestion['NOTE_FAUX'] = '';
                $arrayQuestion['NOTE_VRAI'] = '';
            }
        }
        if ($mode == 'campagne') {
            if (isset($post['QST_DEP']) && $post['QST_DEP'] == 'on') {
                if ($post['BASIS_RULE'] == 'R') {
                    $post['RULE_TYPE'] = $post['RULE_TYPE_R'];
                    $post['MIN_VALUE'] = $post['MIN_VALUE_R'];
                }
                $validator->isObligatoire($post['ID_QST_PARENT'], $trad->t('Question parent'));
                $validator->isObligatoire($post['BASIS_RULE'], $trad->t('Base de la règle'));
                $validator->isObligatoire($post['RULE_TYPE'], $trad->t('Type de règle'));
                if ($post['RULE_TYPE'] == 'BE') {
                    $validator->isObligatoire($post['MIN_VALUE_INTERVAL'], $trad->t('Valeur min.'));
                    $validator->isObligatoire($post['MAX_VALUE'], $trad->t('Valeur max.'));
                } elseif ($post['RULE_TYPE'] == 'LI') {
                    $answers = '';
                    foreach (array_keys($post) as $key) {
                        if (strpos($key, 'dependency_answers_saved') === 0) {
                            $answer = substr($key, 24);
                            $answers .= $answer . ' | ';
                            $post['MIN_VALUE'] = $answers;
                        }
                    }
                    $post['MIN_VALUE'] = \rtrim($post['MIN_VALUE'], ' | ');
                    if ($post['MIN_VALUE'] == '') {
                        $validator->setError($trad->t('Vous devez sélectionner au moins une réponse attendue.'));
                    }
                } else {
                    $validator->isObligatoire($post['MIN_VALUE'], $trad->t('Valeur'));
                }
            }
        }

        $arrayQuestion['ID_THEME'] = $idTheme;

        $validator->isStringAvecEspace($trad->t('Libellé'), $post['LIB_QUEST'], 1, 120);
        $validator->isStringAvecEspace($trad->t('Commentaire'), $post['COMMENTAIRE'], 0, 3000);
        $validator->isInteger($trad->t('Poids'), $post['POIDS'], 1, 100, true);
        $validator->isObligatoire($post['TYPE_REP'], $trad->t('Type de réponse'));
        $validator->isCheck($post['QUEST_FOUR']);

        $arrayQuestion['LIB_QUEST']     = $post['LIB_QUEST'];
        $arrayQuestion['COMMENTAIRE']   = $post['COMMENTAIRE'];
        $arrayQuestion['POIDS']         = $post['POIDS'];
        $arrayQuestion['TYPE_REP']      = $post['TYPE_REP'];
        $arrayQuestion['QUEST_FOUR'] = sql::toBool($post['QUEST_FOUR']);

        $tabResponse = [];

        if (!in_array($mode, ['AO', 'AO_CONTRIB'])) {
            $validator->isCheck($post['AUTHCOMMENT']);
            $arrayQuestion['AUTHCOMMENT'] = sql::toBool($post['AUTHCOMMENT']);

            $post['PROFNOTEUR2'] = isset($post['PROFNOTEUR2']) ? $post['PROFNOTEUR2'] : '';
            if (isset($post['PROFNOTEUR2_LIST']) && $post['PROFNOTEUR2'] == '') {
                $post['PROFNOTEUR2'] = $post['PROFNOTEUR2_LIST'];
            }

            // si on modifie une question pour en faire une question de type calculé ou une question pour fournisseur, on supprime les infos PROFNOTEUR1 et PROFNOTEUR2
            if ($post['TYPE_REP'] == 'C' || (isset($post['QUEST_FOUR']) && $post['QUEST_FOUR'] == 1)) {
                unset($post['PROFNOTEUR0']);
                unset($post['PROFNOTEUR1']);
                unset($post['PROFNOTEUR2']);
            }

            if (isset($post['PROFNOTEUR0'])) {
                if (in_array(trim($post['PROFNOTEUR0']), ['G', 'N'])) {
                    $post['PROFNOTEUR1'] = $post['PROFNOTEUR0'];
                }
                if ($post['PROFNOTEUR0'] == 'N') {
                    $validator->zoom('Hastutil', $post['PROFNOTEUR2'], $trad->t('Evaluateur'), $this->pdo);
                } elseif ($post['PROFNOTEUR1'] != 'C') {
                    // si PROFNOTEUR1 est renseigné et différent des valeurs sans CS, PROFNOTEUR2 est obligatoire
                    if (! in_array(trim($post['PROFNOTEUR1']), ['M', 'A', 'L', 'D'])) {
                        if (!isset($post['PROFNOTEUR2']) || $post['PROFNOTEUR2'] == '') {
                            if ($post['PROFNOTEUR1'] == 'G') {
                                $validator->setError($trad->t('Veuillez sélectionner un groupe d\'évaluateurs.'));
                            } else {
                                $validator->setError($trad->t('Veuillez sélectionner un évaluateur.'));
                            }
                        }
                    }
                }
            }

            $arrayQuestion['PROFNOTEUR1'] = $post['PROFNOTEUR1'] ?? '';
            $arrayQuestion['PROFNOTEUR2'] = $post['PROFNOTEUR2'] ?? '';

            $validator->isCheck($post['OUV_NAPOSS']);
            $arrayQuestion['OUV_NAPOSS'] = sql::toBool($post['OUV_NAPOSS']);
            
            if ($post['TYPE_REP'] == 'O') {
                $arrayQuestion['OUV_NOTEPAR'] = $post['OUV_NOTEPAR'];
            }

            if (isset($post['QUEST_FOUR']) && $post['QUEST_FOUR'] == 1) {
                $arrayQuestion['OUV_NOTEPAR'] = 'C';
            }

            if ($post['TYPE_REP'] == 'N') {
                if ($post['N_REGCOMOBLIG'] != '' && $post['N_REGCOMOBLIG'] != 'T') {
                    $validator->isInteger($trad->t('Valeur commentaire obligatoire'), $post['MIN_REGCOMOBLIG'], 1, 5);
                }
                if ($post['N_REGCOMOBLIG'] != '' && $post['N_REGCOMOBLIG'] == 'T') {
                    $validator->isInteger($trad->t('Valeur commentaire obligatoire MAX'), $post['MAX_REGCOMOBLIG'], 1, 5);
                }

                $arrayQuestion['REGCOMOBLIG'] = $post['N_REGCOMOBLIG'] . '|' . $post['MIN_REGCOMOBLIG'] . '|' . $post['MAX_REGCOMOBLIG'];
            } elseif ($post['TYPE_REP'] == 'L') {
                $arrayQuestion['REGCOMOBLIG'] = $post['L_REGCOMOBLIG'];
            } elseif ($post['TYPE_REP'] == 'N') {
                $arrayQuestion['TYP_NOMBRE'] = $post['TYP_NOMBRE'];
            }
        }
        if ($post['TYPE_REP'] == 'N' || $post['TYPE_REP'] == 'C') {
            $missingValue = 0;
            foreach ($post as $key => $val) {
                // la première valeur est la note de base, donc le texte de réponse n'est pas nécessaire
                // on contrôle ensuite qu'au moins une note supplémentaire a bien été affectée à une réponse
                if (strpos($key, 'note_TXT_REP_') === 0) {
                    $ID_NOTE = substr($key, 13);

                    if ($ID_NOTE == '0') {
                        $post['note_TXT_REP_' . $ID_NOTE] = '';
                    } else {
                        if ($post['note_TXT_REP_' . $ID_NOTE] == '') {
                            $missingValue += 1;
                        }

                        $validator->isFloat(
                            $trad->t('Note de base') . ' ' . $ID_NOTE,
                            $post['note_TXT_REP_' . $ID_NOTE],
                            floatval(($post['A_LONG'] != '' ? $post['A_LONG'] : 15) . '.' . ($post['N_PARTIE_DEC'] != '' ? $post['N_PARTIE_DEC'] : 5))
                        );

                        if ($post['TYPE_REP'] == 'N') {
                            if ((($post['NUM_MIN'] ?? 0) > floatval($post['note_TXT_REP_' . $ID_NOTE])) || (($post['NUM_MAX'] ?? 0) < floatval($post['note_TXT_REP_' . $ID_NOTE]))) {
                                $validator->setError(
                                    $trad->t('Les valeurs du tableau de notes doivent se situer entre les valeurs min et max attendues.')
                                );
                            }
                        }
                    }

                    $validator->isInteger($trad->t('Note'), $post['note_NOTE_' . $ID_NOTE], 0, 10, true);

                    $tabResponse[] = [
                        'ID_REP'        => $ID_NOTE,
                        'TXT_REP'       => $post['note_TXT_REP_' . $ID_NOTE],
                        'NOTE'          => $post['note_NOTE_' . $ID_NOTE],
                    ];
                }
            }
            if ($missingValue > 0) {
                $validator->setError($trad->t('Renseignez une valeur de base pour le tableau de notes.'));
            }
            if (empty($tabResponse) || count($tabResponse) < 2) {
                $validator->setError($trad->t('Renseignez le tableau de notes avec au moins deux valeurs.'));
            }
        }

        if ($post['TYPE_REP'] == 'N') {
            $validator->isCheck($post['NEGATIF']);
            $validator->isInteger($trad->t('Longueur'), $post['A_LONG'], 0, 15, true);
            $validator->isInteger($trad->t('Longueur partie décimale'), $post['N_PARTIE_DEC'], 0, 5, true);
            $validator->isCheck($post['VAL_NEGATIF']);
            $validator->isFloat(
                $trad->t('Valeur min.'),
                $post['NUM_MIN'],
                \floatval(($post['A_LONG'] ?? 15) . '.' . ($post['N_PARTIE_DEC'] ?? 5)),
                false,
                null,
                $arrayQuestion['VAL_NEGATIF'] === false ? 0 : ($post['NUM_MIN'] ?? null)
            );
            $validator->isFloat($trad->t('Valeur min.'), $post['NUM_MIN'], \floatval(($post['A_LONG'] != '' ? $post['A_LONG'] : 15) . '.' . ($post['N_PARTIE_DEC'] != '' ? $post['N_PARTIE_DEC'] : 5)));
            $validator->isFloat($trad->t('Valeur max'), $post['NUM_MAX'], \floatval(($post['A_LONG'] != '' ? $post['A_LONG'] : 15) . '.' . ($post['N_PARTIE_DEC'] != '' ? $post['N_PARTIE_DEC'] : 5)), true);
            if ((floatval($post['A_LONG']) + floatval($post['N_PARTIE_DEC'])) > 15) {
                $validator->setError($trad->t('La partie décimale doit être inférieure à 5.'));
            }
            $arrayQuestion['NUM_FORMAT'] = ($post['NEGATIF'] ? 'N' : '') . ($post['A_LONG'] != '' ? $post['A_LONG'] : 15) . '.' . ($post['N_PARTIE_DEC'] != '' ? $post['N_PARTIE_DEC'] : 5);
            $arrayQuestion['NUM_MIN'] = $post['NUM_MIN'] ?? 0;
            $arrayQuestion['NUM_MAX'] = $post['NUM_MAX'];
        } elseif ($post['TYPE_REP'] == 'L') {
            $validator->isInteger($trad->t('Note pour non'), $post['NOTE_FAUX'], 0, 10, true);
            $validator->isInteger($trad->t('Note pour oui'), $post['NOTE_VRAI'], 0, 10, true);

            $arrayQuestion['NOTE_FAUX'] = $post['NOTE_FAUX'];
            $arrayQuestion['NOTE_VRAI'] = $post['NOTE_VRAI'];
        } elseif ($post['TYPE_REP'] == 'T') {
            foreach ($post as $key => $val) {
                if (strpos($key, 'TXT_REP_') === 0) {
                    $ID_REP = substr($key, 8);

                    $validator->isStringAvecEspace($trad->t('Texte réponse') . ' ' . $ID_REP, $val, 1, 120);
                    $validator->isInteger($trad->t('Note'), $post['NOTE_' . $ID_REP], 0, 10, true);
                    $validator->isCheck($post['COM_MANUEL_' . $ID_REP]);
                    $validator->isCheck($post['COM_OBLIG_' . $ID_REP]);

                    $tabResponse[] = [
                        'ID_REP'        => $ID_REP,
                        'TXT_REP'       => $post['TXT_REP_' . $ID_REP],
                        'COM_MANUEL'    => sql::toBool($post['COM_MANUEL_' . $ID_REP]),
                        'COM_OBLIG'     => sql::toBool($post['COM_OBLIG_' . $ID_REP]),
                        'NOTE'          => $post['NOTE_' . $ID_REP],
                    ];
                }
            }

            if (empty($tabResponse) || count($tabResponse) < 2) {
                $validator->setError($trad->t('Renseignez le tableau de notes avec au moins deux valeurs.'));
            }
            // $validator->isFalse($tabResponse, $trad->t('Au moins une réponse doit être saisie dans le tableau de réponse.'));
        } elseif ($post['TYPE_REP'] == 'C') {
            $validator->checkIfRequestIsSafe($post['REPCALC_REQ']);
            $validator->checkIfRequestIsSafe($post['REPCALC_SELECT']);
            $validator->isStringAvecEspace($trad->t('Requête'), $post['REPCALC_REQ'], 1, 3000);
            $validator->isStringAvecEspace($trad->t('Select'), $post['REPCALC_SELECT'], 1, 200);
            $arrayQuestion['REPCALC_SELECT'] = $post['REPCALC_SELECT'];
            $arrayQuestion['REPCALC_REQ'] = $post['REPCALC_REQ'];
            // si la question calculée ne contient pas de mots interdits, on vérifie qu'elle renvoie un résultat (qu'elle ne contient pas d'erreur de syntaxe, par exemple)
            if ($validator->checkIfRequestIsSafe($post['REPCALC_REQ']) && $validator->checkIfRequestIsSafe($post['REPCALC_SELECT'])) {
                if (!$bibliothequeService->checkIfSqlRequestWorks($post['REPCALC_SELECT'], $post['REPCALC_REQ'], $this->pdo)) {
                    $validator->setError($trad->t('La requête ne renvoie aucun résultat'));
                };
            }
        } elseif ($post['TYPE_REP'] != 'C' && !(isset($post['QUEST_FOUR']) && $post['QUEST_FOUR'] == 1) && !in_array($mode, ['AO', 'AO_CONTRIB'])) {
            $validator->isObligatoire($post['PROFNOTEUR1'], $trad->t('Origine évaluateur'));
        }

        if (!in_array($mode, ['AO', 'AO_CONTRIB'])) {
            $arrayQuestion['QST_OBLIG'] = $validator->isCheck($post['QST_OBLIG']);
        }
        
        $idQuest = '';
        if ($validator->isValid()) {
            if ($idQuestion) {
                if ($mode != 'campagne' && $mode != 'modele') {
                    $idMemo = Sql::updateMemo($this->pdo, $saveQuestion['NM_COM'], $post['COMMENTAIRE']);
                    unset($arrayQuestion['COMMENTAIRE']);
                    $arrayQuestion['NM_COM'] = $idMemo;
                }

                if ($mode == 'question') {
                    $bibQstR->delete(['ID_QUEST' => $idQuestion]);
                    $bibQstQ->update($arrayQuestion, ['ID_QUEST' => $idQuestion]);
                } elseif ($mode == 'campagne') {
                    $arrayQuestion['DESCRIPTION'] = $arrayQuestion['COMMENTAIRE'];
                    unset($arrayQuestion['COMMENTAIRE']);
                    $campQstR->delete(['ID_CAMP' => $idMode, 'ID_THEME' => $idTheme, 'ID_QUEST' => $idQuestion]);
                    $campQstQ->update($arrayQuestion, ['ID_CAMP' => $idMode, 'ID_THEME' => $idTheme, 'ID_QUEST' => $idQuestion]);
                    // dependency management
                    if (isset($post['QST_DEP']) && $post['QST_DEP'] == 'on') {
                        if (\is_array($saveDependency) && \count($saveDependency) > 0) {
                            $campQstDep->delete(['ID_CAMP' => $idMode, 'ID_THEME_DEP' => $idTheme, 'ID_QST_DEP' => $idQuestion]);
                        }

                        $parentQstArray = \explode('~~', $post['ID_QST_PARENT']);
                        $parentQstId = [
                            'ID_QUEST' => $parentQstArray[2],
                            'ID_THEME' => $parentQstArray[1]
                        ];

                        $insert = [];
                        switch ($post['BASIS_RULE']) {
                            case 'R':
                                $insert['RULE_TYPE'] = $post['RULE_TYPE_R'];
                                if ($post['RULE_TYPE_R'] == 'LI') {
                                    $insert['MIN_VALUE'] = $post['MIN_VALUE'];
                                } elseif ($post['RULE_TYPE'] == 'BE') {
                                    $insert['MIN_VALUE'] = $post['MIN_VALUE_INTERVAL'];
                                    $insert['MAX_VALUE'] = $post['MAX_VALUE'];
                                } else {
                                    $insert['MIN_VALUE'] = $post['MIN_VALUE_R'] ?? '';
                                }
                                break;

                            case 'N':
                                $insert['RULE_TYPE'] = $post['RULE_TYPE'];
                                if ($post['RULE_TYPE'] == 'BE') {
                                    $insert['MIN_VALUE'] = $post['MIN_VALUE_INTERVAL'];
                                    $insert['MAX_VALUE'] = $post['MAX_VALUE'];
                                } else {
                                    $insert['MIN_VALUE'] = $post['MIN_VALUE'];
                                }
                                break;

                            default:
                                break;
                        }


                        $insert['ID_CAMP'] = $idMode;
                        $insert['ID_THEME_PARENT'] = $parentQstId['ID_THEME'];
                        $insert['ID_QST_PARENT'] = $parentQstId['ID_QUEST'];
                        $insert['ID_THEME_DEP'] = $idTheme;
                        $insert['ID_QST_DEP'] = $idQuestion;
                        $insert['BASIS_RULE'] = $post['BASIS_RULE'];

                        $campQstDep->insert($insert);
                    }
                } elseif (in_array($mode, ['AO', 'AO_CONTRIB'])) {
                    $aoQstR->delete(['NO_AO' => $idMode, 'ID_THEME' => $idTheme, 'ID_QUEST' => $idQuestion]);
                    $aoQstQ->update($arrayQuestion, ['NO_AO' => $idMode, 'ID_THEME' => $idTheme, 'ID_QUEST' => $idQuestion]);
                } elseif ($mode == 'modele') {
                    $arrayQuestion['DESCRIPTION'] = $arrayQuestion['COMMENTAIRE'];
                    unset($arrayQuestion['COMMENTAIRE']);

                    $grilQstR->delete(['ID_QUEST' => $idQuestion]);
                    $grilQstQ->update($arrayQuestion, ['ID_MODEL' => $idMode, 'ID_THEME' => $idTheme, 'ID_QUEST' => $idQuestion]);
                }
                $idQuest = $idQuestion;
            } else {
                $idMemo = Sql::updateMemo($this->pdo, '', $post['COMMENTAIRE']);
                if ($mode == 'question') {
                    $maxOrder = $bibliothequeRepo->getMaxOrderQuestion($mode, 'NM_ORDRE', '', '');
                    $maxId    = $bibliothequeRepo->getMaxOrderQuestion($mode, 'ID_QUEST', '', '');
                    unset($arrayQuestion['COMMENTAIRE']);

                    $arrayQuestion['ID_QUEST'] = $idQuest = (int) $maxId + 1;
                    $arrayQuestion['NM_ORDRE'] = (int) $maxOrder + 1;

                    $arrayQuestion['NM_COM'] = $idMemo;
                    $bibQstQ->insert($arrayQuestion);
                } elseif ($mode == 'campagne') {
                    $maxOrder = $bibliothequeRepo->getMaxOrderQuestion($mode, 'NM_ORDRE', $idMode, $idTheme);
                    $maxId    = $bibliothequeRepo->getMaxOrderQuestion($mode, 'ID_QUEST', $idMode, $idTheme);

                    $arrayQuestion['DESCRIPTION'] = $arrayQuestion['COMMENTAIRE'];
                    unset($arrayQuestion['COMMENTAIRE']);

                    $arrayQuestion['ID_CAMP'] = $idMode;
                    $arrayQuestion['ID_QUEST'] = $idQuest = (int) $maxId + 1;
                    $arrayQuestion['NM_ORDRE'] = (int) $maxOrder + 1;

                    //dependency management
                    if (isset($post['QST_DEP']) && $post['QST_DEP'] == 'on') {
                        $parentQstArray = \explode('~~', $post['ID_QST_PARENT']);
                        $parentQstId = [
                            'ID_QUEST' => $parentQstArray[2],
                            'ID_THEME' => $parentQstArray[1]
                        ];
                        $insert = [];
                        switch ($post['BASIS_RULE']) {
                            case 'R':
                                $insert['RULE_TYPE'] = $post['RULE_TYPE_R'];
                                if ($post['RULE_TYPE_R'] == 'LI') {
                                    $insert['MIN_VALUE'] = $post['MIN_VALUE'];
                                } elseif ($post['RULE_TYPE_R'] == 'BE') {
                                    $insert['MIN_VALUE'] = $post['MIN_VALUE_INTERVAL'];
                                    $insert['MAX_VALUE'] = $post['MAX_VALUE'];
                                } else {
                                    $insert['MIN_VALUE'] = $post['MIN_VALUE_R'] ?? $post['MIN_VALUE'];
                                }
                                break;

                            case 'N':
                                $insert['RULE_TYPE'] = $post['RULE_TYPE'];
                                if ($post['RULE_TYPE'] == 'BE') {
                                    $insert['MIN_VALUE'] = $post['MIN_VALUE_INTERVAL'];
                                    $insert['MAX_VALUE'] = $post['MAX_VALUE'];
                                } else {
                                    $insert['MIN_VALUE'] = $post['MIN_VALUE'];
                                }
                                break;

                            default:
                                break;
                        }


                        $insert['ID_CAMP'] = $idMode;
                        $insert['ID_THEME_PARENT'] = $parentQstId['ID_THEME'];
                        $insert['ID_QST_PARENT'] = $parentQstId['ID_QUEST'];
                        $insert['ID_THEME_DEP'] = $idTheme;
                        $insert['ID_QST_DEP'] = $arrayQuestion['ID_QUEST'];
                        $insert['BASIS_RULE'] = $post['BASIS_RULE'];

                        $campQstDep->insert($insert);
                    }
                    $campQstQ->insert($arrayQuestion);
                } elseif (in_array($mode, ['AO', 'AO_CONTRIB'])) {
                    $maxOrder = $bibliothequeRepo->getMaxOrderQuestion($mode, 'NM_ORDRE', $idMode, $idTheme);
                    $maxId    = $bibliothequeRepo->getMaxOrderQuestion($mode, 'ID_QUEST', $idMode, $idTheme);
                    unset($arrayQuestion['COMMENTAIRE']);

                    $arrayQuestion['NO_AO'] = $idMode;
                    $arrayQuestion['ID_QUEST'] = $idQuest = (int) $maxId + 1;
                    $arrayQuestion['NM_ORDRE'] = (int) $maxOrder + 1;

                    $arrayQuestion['NM_COM'] = $idMemo;
                    $aoQstQ->insert($arrayQuestion);
                } elseif ($mode == 'modele') {
                    $maxOrder = $bibliothequeRepo->getMaxOrderQuestion($mode, 'NM_ORDRE', $idMode, $idTheme);
                    $maxId    = $bibliothequeRepo->getMaxOrderQuestion($mode, 'ID_QUEST', '', '');

                    $arrayQuestion['DESCRIPTION'] = $arrayQuestion['COMMENTAIRE'];
                    unset($arrayQuestion['COMMENTAIRE']);

                    $arrayQuestion['ID_MODEL'] = $idMode;
                    $arrayQuestion['ID_QUEST'] = $idQuest = (int) $maxId + 1;
                    $arrayQuestion['NM_ORDRE'] = (int) $maxOrder + 1;

                    $grilQstQ->insert($arrayQuestion);
                }
            }

            if ($mode == 'question') {
                foreach ($tabResponse as $response) {
                    $bibQstR->insert([
                        'ID_QUEST'    => $idQuest,
                        'ID_REP'      => $response['ID_REP'],
                        'TXT_REP'     => $response['TXT_REP'],
                        'COM_MANUEL'  => $response['COM_MANUEL'] ?? false,
                        'COM_OBLIG'   => $response['COM_OBLIG'] ?? false,
                        'NOTE'        => $response['NOTE'],
                    ]);
                }
            } elseif ($mode == 'campagne') {
                foreach ($tabResponse as $response) {
                    $campQstR->insert([
                        'ID_CAMP'       => $idMode,
                        'ID_THEME'      => $idTheme,
                        'ID_QUEST'      => $idQuest,
                        'ID_REP'        => $response['ID_REP'],
                        'TXT_REP'       => $response['TXT_REP'],
                        'COM_MANUEL'    => $response['COM_MANUEL'] ?? false,
                        'COM_OBLIG'     => $response['COM_OBLIG'] ?? false,
                        'NOTE'          => $response['NOTE'],
                    ]);
                }
            } elseif (in_array($mode, ['AO', 'AO_CONTRIB'])) {
                foreach ($tabResponse as $response) {
                    $aoQstR->insert([
                        'NO_AO'       => $idMode,
                        'ID_THEME'    => $idTheme,
                        'ID_QUEST'    => $idQuest,
                        'ID_REP'      => $response['ID_REP'],
                        'TXT_REP'     => $response['TXT_REP'],
                        'COM_MANUEL'  => $response['COM_MANUEL'] ?? false,
                        'NOTE'        => $response['NOTE'],
                    ]);
                }
            } elseif ($mode == 'modele') {
                foreach ($tabResponse as $response) {
                    $grilQstR->insert([
                        // 'ID_MODEL'                  => $idMode,
                        // 'ID_THEME'                  => $idTheme,
                        'ID_QUEST'    => $idQuest,
                        'ID_REP'      => $response['ID_REP'],
                        'TXT_REP'     => $response['TXT_REP'],
                        'COM_MANUEL'  => $response['COM_MANUEL'] ?? false,
                        'NOTE'        => $response['NOTE'],
                    ]);
                }
            }

            $path = $this->router->generateUri('Evaluation.BibliothequeDeQuestions.gestionBibliotheque', ['mode' => $mode, 'idCamp' => $idMode]);

            if ($mode == 'AO_CONTRIB') {
                $path = $this->router->generateUri(
                    'Evaluation.BibliothequeDeQuestions.gestionBibliothequeAoContrib',
                    ['mode' => $mode, 'idAO' => $idMode]
                );
            }
            return new Response(443, [], (string) \json_encode([
                'statut' => 'O',
                'path' => $path,
                'post' => ['id_theme' => $idTheme, 'filtre_question' => 'O']
            ]));
        } else {
            return $this->renderer->render('@popup-erreur/ErreurCreation', [
                'ErreurValid' => $validator->getError(),
            ]);
        }
    }

    /**
     * deleteAction
     *
     * @return  string|Response
     */
    public function deleteAction()
    {
        $mode           = $this->request->getAttribute('mode');
        $idMode         = $this->request->getAttribute('idMode');
        $idTheme        = $this->request->getAttribute('idTheme');
        $idQuestion     = $this->request->getAttribute('idQuestion');

        $questionRepo = new Question($this->pdo);

        $questionRepo->deleteQuestion($mode, $idMode, $idTheme, $idQuestion);
        
        $pathBack = $this->router->generateUri('Evaluation.BibliothequeDeQuestions.gestionBibliotheque', ['mode' => $mode, 'idCamp' => $idMode]);

        if ($mode == 'AO_CONTRIB') {
            $pathBack = $this->router->generateUri(
                'Evaluation.BibliothequeDeQuestions.gestionBibliothequeAoContrib',
                ['mode' => $mode, 'idAO' => $idMode]
            );
        }
        
        return new Response(200, [], (string) \json_encode([
            'statut' => 'O',
            'path' => $pathBack,
            'post' => ['id_theme' => $idTheme, 'filtre_question' => 'O']
        ]));
    }

    /**
     * reOrderAction
     *
     * @return  string|Response
     */
    public function reOrderAction()
    {
        $mode           = $this->request->getAttribute('mode');
        $idMode         = $this->request->getAttribute('idMode');
        $idTheme        = $this->request->getAttribute('idTheme');

        $post = $this->request->getParsedBody();


        $questionRepo = new Question($this->pdo);
        $questionRepo->reOrder($mode, $idMode, $idTheme, $post['idQuestion'], $post['initialPosition'], $post['newPosition']);

        return new Response(200);
    }

    public function ajaxNoteurAction(): string
    {
        $mode           = $this->request->getAttribute('mode');
        $idMode         = $this->request->getAttribute('idMode');
        $post           = $this->request->getParsedBody();

        $listeNoteur = (new QuestionService($this->pdo, $this->getTranslationService()))
            ->_getListOfOriginOfRaters($post['PROFNOTEUR0'], $mode, $idMode);
        if ($post['PROFNOTEUR0'] == 'G') {
            $title = $this->getTranslationService()->t('Groupes d\'évaluateurs');
        }

        return $this->renderer->render('@Evaluation/Question/ajaxNoteur', [
            'title' => $title ?? '',
            'mode' => $mode ?? '',
            'idMode' => $idMode ?? '',
            'listeNoteur' => $listeNoteur,
            'PROFNOTEUR0' => $post['PROFNOTEUR0'],
            'PROFNOTEUR1' => $post['PROFNOTEUR1'] ?? '',
        ]);
    }

    public function ajaxNoteurObjectAction(): string
    {
        $mode   = $this->request->getAttribute('mode');
        $idMode = $this->request->getAttribute('idMode');
        $post   = $this->request->getParsedBody();

        $listeNoteurObject = $this->getListeNoteurByOrigine($post['PROFNOTEUR1'], $mode, $idMode, $this->getTranslationService(), $this->pdo);

        return $this->renderer->render('@Evaluation/Question/ajaxNoteurObject', [
            'listeNoteurObject' => $listeNoteurObject,
        ]);
    }

    /**
     * addDependencyAction
     *
     * @return string
     */
    public function addDependencyAction()
    {
        $post             = $this->request->getParsedBody();
        $id               = $this->request->getAttribute('id');
        $mode             = $this->request->getAttribute('mode');
        $theme            = $this->request->getAttribute('theme');
        $menuActive       = Session::verifySessionTypeMenuTop(MenuTopEnum::S2C) ? 'Consultations' : 'Evaluations';

        $trad = $this->getTranslationService();

        $ruleBasisList = [
            'N' => $trad->t('Note'),
            'R' => $trad->t('Réponse'),
        ];

        $ruleTypesList = [];

        $questionsList = [];

        switch ($mode) {
            case 'campagne':
            case 'modele':
        }

        return $this->renderer->render('@Evaluation/Question/popup-dependency', [
            'questionsList'     => $questionsList,
            'ruleBasisList'     => $ruleBasisList,
            'ruleTypesList'     => $ruleTypesList,
            'id'                => $id,
            'mode'              => $mode,
            'theme'             => $theme,
            'menuActive'        => $menuActive,
            'titre'             => 'Edition',
            'pathValidation'    => $this->router->generateUri('Evaluation.BibliothequeDeQuestions.ajoutThemeValidation', ['mode' => $mode, 'idCamp' => $id])
        ]);
    }

    /**
     * ruleTypesAction
     *
     * @return string
     */
    public function ruleTypesAction()
    {
        return '';
    }

    public function parentQuestionListAction(): string
    {
        $post       = $this->request->getParsedBody();
        $id         = $this->request->getAttribute('id');
        $mode       = $this->request->getAttribute('mode');
        $theme      = $this->request->getAttribute('theme');
        $questionId = $this->request->getAttribute('questionId');
        $entity     = new Question($this->pdo);
        $campQstQ   = new CampQstQ($this->pdo);

        $listeEntity = $entity->parentQuestionList($post, $id, $mode);


        if ($questionId) {
            $question = $campQstQ->find(['ID_CAMP' => $id, 'ID_THEME' => $theme, 'ID_QUEST' => $questionId], ['ID_QUEST', 'ID_THEME', 'TYPE_REP'], [], PDO::FETCH_ASSOC);
            $forbiddenQuestions = $entity->dependencyForbiddenQuestions($id, $theme, $questionId);

            $forbiddenIds = [$question['ID_THEME'] . '|' . $question['ID_QUEST']];
            foreach ($forbiddenQuestions as $value) {
                $forbiddenIds[] = $value['ID_THEME_DEP'] . '|' . $value['ID_QST_DEP'];
            }

            $temporaryList = [];
            foreach ($listeEntity as $value) {
                $temporaryList[$value['ID_THEME'] . '|' . $value['ID_QUEST']] = $value;
            }

            foreach ($forbiddenIds as $value) {
                unset($temporaryList[$value]);
            }
            $listeEntity = \array_values($temporaryList);
        }

        $paginator = new Paginator();
        $infoPagination = $paginator->generate($listeEntity, 15, $post, $this->renderer);

        return $this->renderer->render('@Evaluation/Question/ajax-parent-question-list', [
            'entity'            => $listeEntity,
            'infoPagination'    => $infoPagination,
            'post'              => $post,
            'path'              => $this->router->generateUri('Evaluation.Question.parentQuestionList', ['mode' => $mode, 'id' => $id]),
            'mode'              => $mode,
            'id'                => $id,
        ]);
    }

    /**
     * generateDependencyOptionsAction
     *
     * @return string
     */
    public function generateDependencyOptionsAction()
    {
        $post = $this->request->getParsedBody();
        $id   = $this->request->getAttribute('id');
        $mode = $this->request->getAttribute('mode');
        $questionRepo = new Question($this->pdo);

        $trad = $this->getTranslationService();

        $parentQuestion = $questionRepo->getParentQuestionId($id, $post['themeId'], $post['questionId']);

        $basisRuleList = [
            'N' => $trad->t('Note'),
            'R' => $trad->t('Réponse'),
        ];

        $ruleTypesListN = [
            'EQ'    => $trad->t('égale à'),
            'BE'    => $trad->t('comprise entre'),
            'GR'    => $trad->t('supérieure à'),
            'LE'    => $trad->t('inférieure à'),
            'DI'    => $trad->t('différente de'),
        ];

        $ruleTypesListR = [
            'AN'    => $trad->t('Réponse'),
            'LI'    => $trad->t('Liste de réponses'),
        ];

        switch ($parentQuestion['TYPE_REP']) {
            case 'N':
                $ruleTypesListR = $ruleTypesListN;
                break;

            case 'L':
                $ruleTypesListR = [
                    'AN'    => $trad->t('Réponse'),
                ];
                $answersList = [
                    $trad->t('Oui'),
                    $trad->t('Non')
                ];
                break;

            case 'T':
                $ruleTypesListR = [
                    'LI'    => $trad->t('Liste de réponses'),
                ];
                $answersList = $questionRepo->getAnswersList($id, $post['themeId'], $post['questionId']);
                break;

            case 'C':
                $ruleTypesListR = $ruleTypesListN;
                break;

            default:
                break;
        }

        return $this->renderer->render('@Evaluation/Question/ajax-dependency-options', [
            'mode'              => $mode,
            'id'                => $id,
            'basisRuleList'     => $basisRuleList,
            'ruleTypesList'     => $ruleTypesListN,
            'ruleTypesListR'    => $ruleTypesListR,
            'answers'           => $answersList ?? [],
        ]);
    }

    /**
     * deleteDependencyAction
     *
     * @return Response
     */
    public function deleteDependencyAction()
    {
        $id                     = $this->request->getAttribute('campId');
        $parentThemeId          = $this->request->getAttribute('parentThemeId');
        $dependentThemeId       = $this->request->getAttribute('dependentThemeId');
        $parentQuestionId       = $this->request->getAttribute('parentQuestionId');
        $dependentQuestionId    = $this->request->getAttribute('dependentQuestionId');
        $mode                   = $this->request->getAttribute('mode');

        $campQstDep = new CampQstDep($this->pdo);
        $campQstDep->delete([
            'ID_CAMP'         => $id,
            'ID_QST_PARENT'   => $parentQuestionId,
            'ID_QST_DEP'      => $dependentQuestionId,
            'ID_THEME_PARENT' => $parentThemeId,
            'ID_THEME_DEP'    => $dependentThemeId,
        ]);
        return new Response(200, [], (string) \json_encode([
            'path' => $this->router->generateUri('Evaluation.BibliothequeDeQuestions.gestionBibliotheque', ['mode' => 'campagne', 'idCamp' => $id])
        ]));
    }

    /**
     * deleteParentDependencyAction
     *
     * @return Response
     */
    public function deleteParentDependencyAction()
    {
        $mode           = $this->request->getAttribute('mode');
        $idMode         = $this->request->getAttribute('idMode');
        $idTheme        = $this->request->getAttribute('idTheme');
        $idQuestion     = $this->request->getAttribute('idQuestion');

        $campQstDep = new CampQstDep($this->pdo);
        $campQstDep->delete([
            'ID_CAMP'           => $idMode,
            'ID_QST_PARENT'     => $idQuestion,
            'ID_THEME_PARENT'   => $idTheme,
        ]);

        return new Response(200, [], (string) \json_encode([
            'path' => $this->router->generateUri('Evaluation.Question.createEdit', ['mode' => $mode, 'idMode' => $idMode, 'idTheme' => $idTheme, 'idQuestion' => $idQuestion])
        ]));
    }

    //_____________________________________________________________________________
    // Sub-routine

    /**
     * getListeNoteurByOrigine
     *
     * @param  string $typeElem
     * @param  string $mode
     * @param  string $idMode
     * @param  ITrad $trad
     * @param  PDO $pdo
     * @return array<mixed>
     */
    public static function getListeNoteurByOrigine(string $typeElem, string $mode, $idMode, $trad, $pdo): array
    {
        if (strpos($typeElem, 'OBJ|') === 0) {
            switch ($typeElem) {
                case 'OBJ|FAMILLE':
                    $array['TB|CODE_ACH'] = $trad->t('Acheteur');
                    break;
                case 'OBJ|SSFAMILL':
                    $array['TB|CODE_ACH'] = $trad->t('Acheteur');
                    break;
                case 'OBJ|ACD':
                    $array['TB|ACH_RESP'] = $trad->t('Acheteur responsable');
                    break;
                case 'OBJ|CENTRE':
                    break;
                case 'OBJ|CENTRE_E':
                    $array['TB|ACHETEUR'] = $trad->t('Acheteur');
                    break;
                case 'OBJ|CENTRE_R':
                    $array['TB|ACHETEUR'] = $trad->t('Acheteur');
                    break;
                case 'OBJ|CENTRE_F':
                    $array['TB|ACHETEUR'] = $trad->t('Acheteur');
                    break;
                case 'OBJ|UO':
                    $array['TB|RESP_HIER'] = $trad->t('Responsable UO');
                    break;
                case 'OBJ|HASTUTIL':
                    $array['TB|SUPHIER'] = $trad->t('Supérieur hiérarchique');
                    $array['TB|RESPUO'] = $trad->t('Responsable UO');
                    break;
                case 'OBJ|MARCHES':
                    $array['TB|SIGNATAIR'] = $trad->t('Signataire');
                    break;
                default:
                    $array = null;
                    break;
            }

            $actionRepo = new Action($pdo);
            if (substr($typeElem, 4, 6) == 'CENTRE') {
                $listeCS = $actionRepo->getListeCSTypeActeur(substr($typeElem, 4, 6));
            } else {
                $listeCS = $actionRepo->getListeCSTypeActeur(substr($typeElem, 4));
            }

            foreach ($listeCS as $cs) {
                $array[$cs['NUM_FIX']] = $cs['NOM'];
            }
        } elseif ($typeElem == 'G') {
            $listeNoteurTmp = [];
            if ($mode == 'question') {
                $bibGrNot = new BibGrpNot($pdo);
                $listeNoteurTmp = $bibGrNot->fetchAll([]);
            } elseif ($mode == 'campagne') {
                $campGrNot = new CampGrpNot($pdo);
                $listeNoteurTmp = $campGrNot->fetchAll([], ['filter_egal_ID_CAMP' => $idMode]);
            } elseif ($mode == 'modele') {
                $campGrNot = new GrilGrpNot($pdo);
                $listeNoteurTmp = $campGrNot->fetchAll([], ['filter_egal_ID_MODEL' => $idMode]);
            }

            foreach ($listeNoteurTmp as $noteur) {
                $array[$noteur['GROUPE']] = $noteur['GROUPE'];
            }
        }

        return $array ?? [];
    }

    /**
     * previsualiser le questionnaire complet sans pouvoir le modifier
     *
     */
    public function previsualiserAction() : string
    {
        $idcamp = $this->request->getAttribute('campId');
        $trad = $this->getTranslationService();
        $listeThemeCampTmp = $listeQuestion = $listeQuestionPropose = [];
        $evalRepo = new Evaluation($this->pdo);

        $campaign = (new CampaignService($this->pdo, $this->getTranslationService()))
        ->campaignDetail(
            $idcamp,
            $this->router,
            $this->droits
        );

        $listeQuestion = (new CampQstQ($this->pdo))->findAll(['ID_CAMP' => $idcamp], [], ['tri_ID_QUEST' => 'ASC']);
        
        $listeQuestionPropose = [];
        foreach ($listeQuestion as $question) {
            // $listeQuestionPropose[($question['ID_PERE']?$question['ID_PERE']:$question['ID_THEME'])][] = $question;
            $listeQuestionPropose[$question['ID_THEME']][] = $question;
        }

        $arbo = $evalRepo->getArboQuestion($idcamp);
        $listeQuestionPropose = (new EvaluationService($this->pdo, $trad))->treeBibliotheque('', $listeQuestionPropose, $arbo);
        
        $listeThemeCamp = $evalRepo->getThemeParUser($idcamp);
        $listeThemeCampTmp = [];
        foreach ($listeThemeCamp as $theme) {
            $listeThemeCampTmp[$theme['ID_THEME']] = $theme;
        }

        ArianeSub::generate(1, 0, $trad->t('Prévisualisation questionnaire'), $_SERVER['REQUEST_URI'], 1);

        return $this->renderer->render('@Evaluation/Question/Previsualisation/prevu', [
            'menuActive'              => Session::verifySessionTypeMenuTop(MenuTopEnum::S2C) ? 'Consultations' : 'Evaluations',
            'menuLeft'                => 'ratings',
            'listeQuestion'           => $listeQuestion,
            'idFrs'                   => '',
            'listeThemeCamp'          => $listeThemeCampTmp,
            'titre'                   => Trad::strBuild(
                $trad->t('Visualisation des réponses pour la campagne : @1@ (@2@)'),
                $idcamp,
                $campaign['LIBELLE']
            ),
            'idcamp'                  => $idcamp,
            'listeQuestionPropose'    => $listeQuestionPropose,
            'commentaireGlobal'       => '',
            'campaign'                => $campaign,
            'canEdit'                 => 0,
            'visu'                    => false,
            'modeErreur'              => true,
            'isDepouilleur'           => true
        ]);
    }
}
