<?php

namespace Modules\Evaluation\Service;

use Entity\Model\CampEnt;
use Entity\Model\CampNotex;
use Entity\Model\CampQstQ;
use Entity\Model\CampQstR;
use Entity\Model\CampRepQst;
use Entity\Model\Fourniss;
use Entity\Model\Hastutil;
use Helpers\Fichier\Fichier;
use Helpers\Outil\Sql;
use Helpers\Trad\ITrad;
use Helpers\Trad\Trad;
use Modules\Evaluation\Repository\Evaluation;
use Psr\Container\ContainerInterface;
use Skeleton\Router;
use Helpers\Session\ParseBase1;

class EvaluationService
{
    private ITrad $trad;
    private CampRepQst $campRepQst;
    private CampQstQ $campQstQ;
    private \PDO $pdo;

    private Evaluation $evaluationRepository;

    public function __construct(\PDO $pdo, ITrad $trad)
    {
        $this->pdo                  = $pdo;
        $this->trad                 = $trad;
        $this->evaluationRepository = new Evaluation($this->pdo);
        $this->campRepQst           = new CampRepQst($this->pdo);
        $this->campQstQ             = new CampQstQ($this->pdo);
    }

    /**
     * Summary of resetReponse
     * @param  array<mixed> $post
     * @param  string $idCamp
     * @param  string $idFrs
     * @return bool
     */
    public function resetReponse($post, $idCamp, $idFrs): bool
    {
        $infoChps = $post['chps'];

        $arrayId = [
            'ID_CAMP' => (int) $idCamp,
            'CODE_FOU' => (string) $idFrs,
            'COD_NOTEUR' => (string) $_SESSION['Session_Login'],
            'ID_QUEST' => (int) $infoChps['question'],
            'ID_THEME' => (string) $infoChps['theme']
        ];

        $valueUpdate = [
            "REP_NUM" => "",
            "REP_LOG" => Sql::boolSql2(false),
            "REP_TAB" => 0,
            "COMMENT" => "",
            "REP_OUV" => "",
            "REP_CALC" => "",
            "COMMENTAIRE" => "",
            "OUVNONAPPL" => Sql::boolSql2(false),
            "DTE_REP" => "00000000",
            "NOTE" => 0,
            "TERMINE" => Sql::boolSql2(false),
        ];

        return $this->campRepQst->update($valueUpdate, $arrayId);
    }

    /**
     * Summary of updateNote
     * @param array<mixed> $post
     * @param string|int $idCamp
     * @param string|int $idFrs
     * @param string|int $codNoteur
     * @return bool
     */
    public function updateNote(
        array $post,
        string|int $idCamp,
        string|int $idFrs,
        string|int $codNoteur,
    ): bool {
        $infoChps = $post['chps'];

        $note = $infoChps['note'] ?? 0;

        $arrayId = [
            'ID_CAMP' => (int) $idCamp,
            'CODE_FOU' => (string) $idFrs,
            'COD_NOTEUR' => (string) $codNoteur,
            'ID_QUEST' => (int) $infoChps['question'],
            'ID_THEME' => (string) $infoChps['theme']
        ];

        $valueUpdate = [
            "NOTE" => (int) $note,
        ];

        return $this->campRepQst->update($valueUpdate, $arrayId);
    }

    /**
     * Summary of updateNoteValidationDepouilleur
     * @param string $idCamp
     * @param string $theme
     * @param string $question
     * @param string $idFrs
     * @param string $codNoteur
     * @param string $note
     * @return bool
     */
    public function updateNoteValidationDepouilleur(string $idCamp, string $theme, string $question, string $idFrs, string $codNoteur, string $note): bool
    {
        $arrayId = [
            'ID_CAMP' => (int) $idCamp,
            'CODE_FOU' => (string) $idFrs,
            'COD_NOTEUR' => (string) $codNoteur,
            'ID_QUEST' => (int) $question,
            'ID_THEME' => (string) $theme
        ];

        $valueUpdate = [
            "NOTE" => $note,
            "OUV_NOTE" => Sql::boolSql2(true)
        ];

        return $this->campRepQst->update($valueUpdate, $arrayId);
    }

    /**
     * updateValueReponseWithNote
     *
     * @param  array<mixed> $post
     * @param  string $idCamp
     * @param  string $idFrs
     * @return bool
     */
    public function updateValueReponseWithNote($post, $idCamp, $idFrs): bool
    {

        $noActiveUpdate = false;

        $infoChps = $post['chps'];
        $arrayId  = [
            'ID_CAMP' => $idCamp,
            'CODE_FOU' => $idFrs,
            'COD_NOTEUR' => $_SESSION['Session_Login'],
            'ID_QUEST' => $infoChps['question'],
            'ID_THEME' => $infoChps['theme']
        ];
        $infoRep  = $this->campRepQst->find($arrayId);

        $valueUpdate = [];

        $campQstR = new CampQstR($this->pdo);

        switch ($infoChps['name']) {
            case 'REP_OUV':
                if (($post['value'] === '') && Sql::toBool($infoRep['OUVNONAPPL'])) {
                    $noActiveUpdate = true;
                } else {
                    $valueUpdate['REP_OUV'] = $post['value'];
                }
                break;
            case 'REP_OUV_NM':
                if (($post['value'] === '') && Sql::toBool($infoRep['OUVNONAPPL'])) {
                    $noActiveUpdate = true;
                } else {
                    $valueUpdate['REP_OUV'] = $post['value'];
                }
                break;
            case 'REP_LOG':
                $valueUpdate['REP_LOG'] = ($post['value'] == '1');

                $arrayIdForQSTQ = [
                    'ID_CAMP' => $idCamp,
                    'ID_QUEST' => $infoChps['question'],
                    'ID_THEME' => $infoChps['theme']
                ];

                $result = $this->campQstQ->find($arrayIdForQSTQ);

                if ($post['value'] == '1') {
                    $noteQst = $result['NOTE_VRAI'];
                } else {
                    $noteQst = $result['NOTE_FAUX'];
                }

                $this->evaluationRepository->updateCampRepQstRepLog($idCamp, $idFrs, $infoChps['question'], $infoChps['theme'], $valueUpdate['REP_LOG'], $noteQst);
                $noActiveUpdate = true;
                break;
            case 'NM_COM':
                $valueUpdate['COMMENTAIRE'] = $post['value'];
                break;
            case 'REP_NUM':
                $valueUpdate[$infoChps['name']] = str_replace(' ', '', $post['value']);

                $noteByReq = $this->evaluationRepository->getNoteForNumerique($idCamp, $infoChps['theme'], $infoChps['question'], $post['value']);
                $valueUpdate['NOTE'] = $noteByReq['NOTE'] ?? 0;

                break;
            case 'REP_TAB':
                $valueUpdate['REP_TAB'] = $post['value'];

                $rep = $campQstR->find(['ID_CAMP' => $idCamp, 'ID_THEME' => $infoChps['theme'], 'ID_QUEST' => $infoChps['question'], 'ID_REP' => $post['value']]);

                $valueUpdate['NOTE'] = $rep['NOTE'] ?? 0;
                break;

            case 'COMMENTAIRE_FINAL':
                $valueUpdate['COMMENTAIRE'] = $post['value'];

                if (is_null($this->campRepQst->find([
                        'ID_CAMP' => $idCamp,
                        'CODE_FOU' => $idFrs,
                        'COD_NOTEUR' => $_SESSION['Session_Login'],
                        'ID_QUEST' => 0,
                        'ID_THEME' => ''
                    ]))
                ) {
                    $this->campRepQst->insert([
                        'ID_CAMP' => $idCamp,
                        'CODE_FOU' => $idFrs,
                        'COD_NOTEUR' => $_SESSION['Session_Login'],
                        'ID_QUEST' => '0',
                        'ID_THEME' => '',
                        'COMMENTAIRE' => $post['value']
                    ]);
                } elseif (count($valueUpdate)) {
                    $this->campRepQst->update($valueUpdate, [
                        'ID_CAMP' => $idCamp,
                        'CODE_FOU' => $idFrs,
                        'COD_NOTEUR' => $_SESSION['Session_Login'],
                        'ID_QUEST' => '0',
                        'ID_THEME' => ''
                    ]);
                }

                $noActiveUpdate = true;
                break;

            case 'NAPPL':
                $this->evaluationRepository->updateCampRepQstNA($idCamp, $idFrs, $infoChps['question'], $infoChps['theme'], $post['value'] == '1');
                $noActiveUpdate = true;
                break;
            // case 'REP_TAB':
            //     $valueUpdate['REP_TAB'] = $post['value'];

            //     $rep = $campQstR->find([ 'ID_THEME' => $infoChps['theme'], 'ID_QUEST' => $infoChps['question'], 'ID_REP' => $post['value']]);
            //     $valueUpdate['NOTE'] = $rep['NOTE'];
            //     break;
            default:
                $valueUpdate[$infoChps['name']] = $post['value'];
                break;
        }

        if (($infoChps['name'] != 'COMMENTAIRE_FINAL') && ($infoChps['name'] != "NM_COM") && (Sql::toBool($infoRep['OUVNONAPPL']) != true)) {
            $rep = $this->evaluationRepository->validerReponseParCampagne(
                $idCamp,
                $idFrs,
                $infoChps['question'],
                $infoChps['theme'],
                ($post['value'] === '' ? false : true)
            );
        }

        if (!$noActiveUpdate) {
            if ($infoRep && count($valueUpdate)) {
                $this->campRepQst->update($valueUpdate, $arrayId);
            } else {
                $arrayMerge = array_merge($valueUpdate, $arrayId);
                $this->campRepQst->insert($arrayMerge);
            }
        }

        return true;
    }

    /**
     * getQuestionDependante
     *
     * @param  array<mixed> $post
     * @param  string $idCamp
     * @param  string $idFrs
     * @param  array<mixed> $noDep
     * @param  ContainerInterface $contenaire
     * @param  Router $router
     * @param  string $keyJWT
     * @return array<mixed>
     */
    public function getQuestionDependante($post, $idCamp, $idFrs, &$noDep, $contenaire, $router, $keyJWT): ?array
    {
        if (Fichier::fileExisteTmp($_SESSION['Session_Login'] . ' ' . $idCamp . '_DepSaisieRep')) {
            $jsonDep = Fichier::getContentFile($_SESSION['Session_Login'] . ' ' . $idCamp . '_DepSaisieRep');
            $jsonDep = json_decode((string) $jsonDep, true);
        } else {
            $jsonDep = [];
        }
        if ($jsonDepExt = Fichier::getContentFile($_SESSION['Session_Login'] . ' ' . $idCamp . '_DepSaisieRepExterne')) {
            $jsonDepExt = json_decode($jsonDepExt, true);
        } else {
            $jsonDepExt = [];
        }

        $infoChps = $post['chps'];

        $rs = (new Fourniss($this->pdo))->find(['CODE' => $idFrs], ['RS'])['RS'];

        $tmpQuestionDependante = [];
        $questionDependante    = $this->evaluationRepository->getQuestionDependante($idCamp, $infoChps['question'], $infoChps['theme'], $idFrs);

        $dependanceActif    = [];
        $dependanceDesactif = [];


        foreach ($questionDependante as $question) {
            // Recuperation de la valeur
            unset($question['ID_QST_PARENT']);
            $resultatTest = ($question['BASIS_RULE'] == 'R' ? $post['value'] : $this->campRepQst->find(
                [
                    'ID_CAMP' => $idCamp,
                    'ID_QUEST' => $infoChps['question'],
                    'ID_THEME' => $infoChps['theme'],
                    'CODE_FOU' => $idFrs,
                    'COD_NOTEUR' => $_SESSION['Session_Login']
                ]
            )['NOTE']);

            switch ($question['RULE_TYPE']) {
                case 'LI':
                    $donneeTestBDD = explode('|', $question['MIN_VALUE']);
                    $listeOK = false;
                    foreach ($donneeTestBDD as $testBDD) {
                        if ($resultatTest == $testBDD) {
                            $this->gestionFichier($question, $jsonDepExt, $jsonDep, $tmpQuestionDependante, $contenaire, $router, $keyJWT, $dependanceActif, $idCamp, $idFrs, $rs);

                            $listeOK = true;
                        }
                    }
                    if ($listeOK == false) {
                        $this->dependanceNoActif($question, $jsonDep, $jsonDepExt, $dependanceDesactif, $noDep);
                    }
                    break;
                case 'AN':
                    if ($resultatTest == $question['MIN_VALUE']) {
                        $this->gestionFichier($question, $jsonDepExt, $jsonDep, $tmpQuestionDependante, $contenaire, $router, $keyJWT, $dependanceActif, $idCamp, $idFrs, $rs);
                    } else {
                        $this->dependanceNoActif($question, $jsonDep, $jsonDepExt, $dependanceDesactif, $noDep);
                    }

                    break;
                case 'DI':
                    if ($resultatTest != $question['MIN_VALUE']) {
                        $this->gestionFichier($question, $jsonDepExt, $jsonDep, $tmpQuestionDependante, $contenaire, $router, $keyJWT, $dependanceActif, $idCamp, $idFrs, $rs);
                    } else {
                        $this->dependanceNoActif($question, $jsonDep, $jsonDepExt, $dependanceDesactif, $noDep);
                    }

                    break;
                case 'LE':
                    if ($resultatTest < $question['MIN_VALUE']) {
                        $this->gestionFichier($question, $jsonDepExt, $jsonDep, $tmpQuestionDependante, $contenaire, $router, $keyJWT, $dependanceActif, $idCamp, $idFrs, $rs);
                    } else {
                        $this->dependanceNoActif($question, $jsonDep, $jsonDepExt, $dependanceDesactif, $noDep);
                    }

                    break;
                case 'GR':
                    if ($resultatTest > $question['MIN_VALUE']) {
                        $this->gestionFichier($question, $jsonDepExt, $jsonDep, $tmpQuestionDependante, $contenaire, $router, $keyJWT, $dependanceActif, $idCamp, $idFrs, $rs);
                    } else {
                        $this->dependanceNoActif($question, $jsonDep, $jsonDepExt, $dependanceDesactif, $noDep);
                    }

                    break;
                case 'BE':
                    if ($resultatTest >= $question['MIN_VALUE'] && $resultatTest <= $question['MIN_VALUE']) {
                        $this->gestionFichier($question, $jsonDepExt, $jsonDep, $tmpQuestionDependante, $contenaire, $router, $keyJWT, $dependanceActif, $idCamp, $idFrs, $rs);
                    } else {
                        $this->dependanceNoActif($question, $jsonDep, $jsonDepExt, $dependanceDesactif, $noDep);
                    }

                    break;

                case 'EQ':
                    if ($resultatTest == $question['MIN_VALUE']) {
                        $this->gestionFichier($question, $jsonDepExt, $jsonDep, $tmpQuestionDependante, $contenaire, $router, $keyJWT, $dependanceActif, $idCamp, $idFrs, $rs);
                    } else {
                        $this->dependanceNoActif($question, $jsonDep, $jsonDepExt, $dependanceDesactif, $noDep);
                    }
                    break;
                default:
                    $this->dependanceNoActif($question, $jsonDep, $jsonDepExt, $dependanceDesactif, $noDep);
                    break;
            }
        }

        Fichier::createFichierTmp($_SESSION['Session_Login'] . ' ' . $idCamp . '_DepSaisieRep', (string) json_encode($jsonDep));
        Fichier::createFichierTmp($_SESSION['Session_Login'] . ' ' . $idCamp . '_DepSaisieRepExterne', (string) json_encode($jsonDepExt));

        if (count($dependanceActif)) {
            $this->dependanceGestion($idCamp, $idFrs, true, $dependanceDesactif, $dependanceActif);
        }

        if (count($dependanceDesactif)) {
            $this->dependanceGestion($idCamp, $idFrs, false, $dependanceDesactif, $dependanceActif);
        }

        return $tmpQuestionDependante;
    }

    /**
     * dependanceNoActif
     *
     * @param  array<mixed> $question
     * @param  array<mixed> $jsonDep
     * @param  array<mixed> $jsonDepExt
     * @param  array<mixed> $dependanceDesactif
     * @param  array<mixed> $noDep
     * @return void
     */
    public function dependanceNoActif(array $question, array &$jsonDep, array &$jsonDepExt, array &$dependanceDesactif, &$noDep)
    {
        $noDep[$question['ID_THEME'] . '-' . $question['ID_QUEST']][] = $question;
        unset($jsonDep[$question['ID_THEME'] . '-' . $question['ID_QUEST']]);
        unset($jsonDepExt[$question['ID_THEME'] . '-' . $question['ID_QUEST']]);
        $dependanceDesactif[] = [
            'ID_THEME' => $question['ID_THEME'],
            'ID_QUEST' => $question['ID_QUEST'],
            'COD_NOTEUR' => $question['COD_NOTEUR'],
            'NOTEUR_EXTERNE' => $question['NOTEUR_EXTERNE'],
        ];
    }

    /**
     * gestionFichier
     *
     * @param  array<mixed> $question
     * @param  array<mixed> $jsonDepExt
     * @param  array<mixed> $jsonDep
     * @param  array<mixed> $tmpQuestionDependante
     * @param  ContainerInterface $contenaire
     * @param  Router $router
     * @param  string $keyJWT
     * @param  array<mixed> $dependanceActif
     * @param  string $idCamp
     * @param  string $idFrs
     * @param  string $rs
     * @return void
     */
    public function gestionFichier(array $question, array &$jsonDepExt, array &$jsonDep, array &$tmpQuestionDependante, $contenaire, $router, $keyJWT, &$dependanceActif, $idCamp, $idFrs, $rs)
    {
        $jsonDepExtTmp = [];

        if ($question['COD_NOTEUR'] == $_SESSION['Session_Login']) {
            $tmpQuestionDependante[$question['ID_THEME'] . '-' . $question['ID_QUEST']][] = $question;
            $jsonDep[$question['ID_THEME'] . '-' . $question['ID_QUEST']]['LIB_THEME']    = $question['ID_THEME'];
        } else {
            $jsonDepExt[$question['ID_THEME'] . '-' . $question['ID_QUEST']] = $question['ID_THEME'];
            if (Sql::toBool($question['NOT_FOUR'])) {
                $i                = 0;
                $noteurOxalinkAll = $this->evaluationRepository->getContactOxalink($question['CODE_FOU']);
                foreach ($noteurOxalinkAll as $noteurOxalink) {
                    $jsonDepExtTmp[$question['ID_THEME'] . '-' . $question['ID_QUEST']][$i]['NOM']     = $noteurOxalink['NOM'];
                    $jsonDepExtTmp[$question['ID_THEME'] . '-' . $question['ID_QUEST']][$i]['EMAIL']   = $noteurOxalink['EMAIL'];
                    $jsonDepExtTmp[$question['ID_THEME'] . '-' . $question['ID_QUEST']][$i]['SOCIETE'] = $noteurOxalink['RS'];
                    $jsonDepExtTmp[$question['ID_THEME'] . '-' . $question['ID_QUEST']][$i]['COD_LNG'] = $noteurOxalink['COD_LNG'];
                    $jsonDepExtTmp[$question['ID_THEME'] . '-' . $question['ID_QUEST']][$i]['ORIGIN']  = 'I';
                    $jsonDepExtTmp[$question['ID_THEME'] . '-' . $question['ID_QUEST']][$i]['LINK']    = $contenaire->get('urlOxaLinkIndex') . '/index.php';
                    $i++;
                }

                $jsonDepExt = array_merge($jsonDepExt, $jsonDepExtTmp);
            } elseif (Sql::toBool($question['NOTEUR_EXTERNE'])) {
                $campNotEx     = new CampNotex($this->pdo);
                $noteurExterne = $campNotEx->find(['ID_NOTEUR' => $question['COD_NOTEUR']], ['NOM_NOTEUR', 'EMAIL_NOTEUR', 'SOC_NOTEUR']);

                $jsonDepExtTmp[$question['ID_THEME'] . '-' . $question['ID_QUEST']]['NOM']      = $noteurExterne['NOM_NOTEUR'];
                $jsonDepExtTmp[$question['ID_THEME'] . '-' . $question['ID_QUEST']]['EMAIL']    = $noteurExterne['EMAIL_NOTEUR'];
                $jsonDepExtTmp[$question['ID_THEME'] . '-' . $question['ID_QUEST']]['CODE_STE'] = $noteurExterne['SOC_NOTEUR'];
                $jsonDepExtTmp[$question['ID_THEME'] . '-' . $question['ID_QUEST']]['ORIGIN']   = 'E';

                $payload = [
                    'ID_NOTEUR' => $question['COD_NOTEUR'],
                    'EMAIL_NOTEUR' => $noteurExterne['EMAIL_NOTEUR'],
                    'exp' => time() + 60 * 60 * 60 * 60
                ];

                $url = $_SERVER['HTTP_ORIGIN'] . $router->generateUri('Evaluation.Evaluation.saisieDeReponse', [
                    'jwt' => \Firebase\JWT\JWT::encode($payload, $keyJWT, 'HS256'),
                    'idFrs' => $idFrs,
                    'idCamp' => $idCamp,
                ]);

                $jsonDepExtTmp[$question['ID_THEME'] . '-' . $question['ID_QUEST']]['LINK'] = $url;

                $jsonDepExt = array_merge($jsonDepExt, $jsonDepExtTmp);
            } else {
                $hastutil = new Hastutil($this->pdo);
                $noteurHA = $hastutil->find(['CODE' => $question['COD_NOTEUR']], ['NOM', 'EMAIL']);

                $jsonDepExtTmp[$question['ID_THEME'] . '-' . $question['ID_QUEST']]['NOM']     = $noteurHA['NOM'];
                $jsonDepExtTmp[$question['ID_THEME'] . '-' . $question['ID_QUEST']]['EMAIL']   = $noteurHA['EMAIL'];
                $jsonDepExtTmp[$question['ID_THEME'] . '-' . $question['ID_QUEST']]['SOCIETE'] = $noteurHA['CODE_STE'];
                $jsonDepExtTmp[$question['ID_THEME'] . '-' . $question['ID_QUEST']]['COD_LNG'] = $noteurHA['COD_LNG'];
                $jsonDepExtTmp[$question['ID_THEME'] . '-' . $question['ID_QUEST']]['ORIGIN']  = 'I';
                $jsonDepExtTmp[$question['ID_THEME'] . '-' . $question['ID_QUEST']]['LINK']    = $contenaire->get('base') . 'index.php';

                $jsonDepExt = array_merge($jsonDepExt, $jsonDepExtTmp);
            }
        }

        $dependanceActif[] = [
            'ID_THEME' => $question['ID_THEME'],
            'ID_QUEST' => $question['ID_QUEST'],
            'COD_NOTEUR' => $question['COD_NOTEUR'],
            'NOTEUR_EXTERNE' => $question['NOTEUR_EXTERNE'],
        ];
    }

    /**
     * dependanceGestion
     *
     * @param  string $idCamp
     * @param  string $codeFrs
     * @param  bool $activerQuestion
     * @param  array<mixed> $dependanceDesactif
     * @param  array<mixed> $dependanceActif
     * @return void
     */
    public function dependanceGestion(string $idCamp, string $codeFrs, bool $activerQuestion = true, array $dependanceDesactif = [], array $dependanceActif = []): void
    {
        $this->evaluationRepository->setActifQuestionDependante($idCamp, $codeFrs, $activerQuestion, $dependanceDesactif, $dependanceActif);

        foreach ($activerQuestion ? $dependanceActif : $dependanceDesactif as $dep) {
            if ($this->evaluationRepository->getCampNotStatusTermine($idCamp, $codeFrs, true, Sql::toBool($dep['NOTEUR_EXTERNE']), $dep['COD_NOTEUR'])['count']) {
                $this->evaluationRepository->updateCampNotStatusTermine($idCamp, $codeFrs, Sql::toBool($dep['NOTEUR_EXTERNE']), $dep['COD_NOTEUR']);
            } else {
                if (count($this->evaluationRepository->getQuesionForReponseForm($dep['COD_NOTEUR'], $codeFrs, $idCamp, (Sql::toBool($dep['NOTEUR_EXTERNE']) ? 1 : 0)))) {
                    $this->evaluationRepository->updateCampNotStatusTermine($idCamp, $codeFrs, Sql::toBool($dep['NOTEUR_EXTERNE']), $dep['COD_NOTEUR']);
                }
            }
        }
    }


    /**
     * controleThemeEtQuestionPourSaisie
     *
     * @param  array<mixed> $listeThemeCampTmp
     * @param  array<mixed> $listeQuestion
     * @param  array<mixed> $listeQuestionPropose
     * @param  string $idFrs
     * @param  string $idcamp
     * @param  int $externe
     * @param  bool $canEdit
     * @param  mixed $user
     * @return void
     */
    public function controleThemeEtQuestionPourSaisie(&$listeThemeCampTmp, &$listeQuestion, &$listeQuestionPropose, $idFrs, $idcamp, $externe, &$canEdit = true, $user = false)
    {
        $user = $user ? $user : ($_SESSION['Session_Login'] ?? '');

        if ($canEdit) {
            Fichier::createFichierTmp($_SESSION['Session_Login'] . ' ' . $idcamp . '_DepSaisieRep', (string) json_encode([]));
        }

        $canEdit = $this->evaluationRepository->getCanEdit(
            $user,
            $idFrs,
            $idcamp,
            $externe === 1 ? true : false
        );

        if (Sql::toBool($canEdit['TERMINE'] ?? false) || $canEdit == false) {
            $canEdit = false;
        } else {
            $canEdit = true;
        }

        // si l'utilisateur est le dépouilleur alors il peut voir les réponses de tout le monde
        // $userIsStripper = ((new CampEnt($this->pdo))->find(['ID_CAMP' => $idcamp], ['CREEEPAR'])['CREEEPAR'] == $user);
        $listeQuestion  = (new Evaluation($this->pdo))->getQuesionForReponseForm($user, $idFrs, $idcamp, $externe, (($idFrs == $user) ? true : false), false);

        $listeQuestionPropose = [];
        foreach ($listeQuestion as $question) {
            // $listeQuestionPropose[($question['ID_PERE']?$question['ID_PERE']:$question['ID_THEME'])][] = $question;
            $listeQuestionPropose[$question['ID_THEME']][] = $question;
        }

        $arbo                 = (new Evaluation($this->pdo))->getArboQuestion($idcamp);
        $listeQuestionPropose = $this->treeBibliotheque('', $listeQuestionPropose, $arbo);

        $listeThemeCamp    = $this->evaluationRepository->getThemeParUser($idcamp);
        $listeThemeCampTmp = [];
        foreach ($listeThemeCamp as $theme) {
            $listeThemeCampTmp[$theme['ID_THEME']] = $theme;
        }
    }

    /**
     * treeBibliotheque
     *
     * @param  mixed $parent
     * @param  mixed $array
     * @param  mixed $arbo
     * @param  mixed $i
     * @param  mixed $del
     * @return array<mixed>
     */
    public function treeBibliotheque($parent, $array, $arbo, $i = 0, $del = [])
    {
        $result = array();

        foreach ($arbo as $noeud) {
            if ($parent == trim($noeud['ID_PERE'])) {
                $result[] = array_merge([
                    'ID_THEME' => $noeud['ID_THEME'],
                    'LIB_THEME' => $noeud['LIB_THEME'],
                    'ID_QUEST' => $array[$noeud['ID_THEME']]['ID_QUEST'] ?? '',
                    'children' => $this->treeBibliotheque($noeud['ID_THEME'], $array, $arbo, $i)
                ], $array[$noeud['ID_THEME']] ?? []);

                // $result[$noeud['ID_PERE']]['children'] = $this->treeBibliotheque($noeud['ID_THEME'], $array, $arbo, $i);

                // $result = array_merge($result[$noeud['ID_PERE']], $array[$noeud['ID_THEME']] ?? []);
            }
        }
        return $result;
    }

    /**
     * deleteKey
     *
     * @param  mixed $result
     * @return void
     */
    public function deleteKey(&$result)
    {
        foreach ($result as $res) {
            if ($this->childernExsiste($res) == false) {
                unset($res);
            }
        }
    }


    /**
     * childernExsiste
     *
     * @param  mixed $res
     * @param  mixed $existe
     * @return bool
     */
    public function childernExsiste($res, $existe = false): bool
    {
        foreach ($res as $r) {
            if (count($r['children'] ?? []) && (!isset($r['ID_QUEST']) || $r['ID_QUEST'] == '')) {
                return true;
            } else {
                if (count($r['children'] ?? [])) {
                    $this->childernExsiste($r['children'], $existe);
                }
            }
        }
        return false;
    }

    /**
     * getDependanceForPopup
     *
     * @param  string $idCamp
     * @return string
     */
    public function getDependanceForPopup(ITrad $trad, string $idCamp): string
    {
        $contentExite = [];
        $depExiste = false;
        $html = '<br /><br >' . $trad->t('Attention, vous avez des dépendances dans les thèmes suivants') . $trad->colon() . '<br >';

        if ($jsonDep = Fichier::getContentFile($_SESSION['Session_Login'] . ' ' . $idCamp . '_DepSaisieRep')) {
            $jsonDep = json_decode($jsonDep, true);
        } else {
            $jsonDep = [];
        }
        foreach ($jsonDep as $dep) {
            $themeParent = $this->evaluationRepository->getGrandPereTheme($dep['LIB_THEME'], $idCamp);
            if (isset($themeParent['LIB_THEME']) && !isset($contentExite[$themeParent['LIB_THEME']])) {
                $depExiste                               = true;
                $contentExite[$themeParent['LIB_THEME']] = 1;
                $html .= '<br > -' . $themeParent['LIB_THEME'];
            }
        }
        if ($depExiste == true) {
            return $html;
        } else {
            return '';
        }
    }

    /**
     * getError
     *
     * @param  string $idFrs
     * @param  string $idCamp
     * @param  bool $externe
     * @return string
     */
    public function getError($idFrs, $idCamp, ITrad $trad, bool $externe): ?string
    {
        $error         = '';
        $listeQuestion = $this->evaluationRepository->getQuesionForReponseForm($_SESSION['Session_Login'], $idFrs, $idCamp, ($externe ? 1 : 0));

        $campQstR = new CampQstR($this->pdo);

        foreach ($listeQuestion as $question) {
            $listeRep = $campQstR->findAll(['ID_CAMP' => $idCamp, 'ID_THEME' => $question['ID_THEME'], 'ID_QUEST' => $question['ID_QUEST']]);
            if ($listeRep) {
                foreach ($listeRep as $rep) {
                    if ($rep['ID_REP'] == ($question['REP_TAB'] ?? 0)) {
                        // si la réponse sélectionnée attend un commentaire obligatoire et le non applicable n'a pas été coché, erreur
                        if (Sql::toBool($rep['COM_OBLIG']) && $question['COMMENTAIRE'] == '' && !Sql::toBool($question['OUVNONAPPL'])) {
                            $error .= '<br /> - ' . Trad::strBuild($trad->t('Le commentaire doit être renseigné pour la question @1@ (@2@).'), $question['LIB_QUEST'], $question['LIB_THEME']);
                        }
                    }
                }
            }
            switch ($question['TYPE_REP']) {
                case 'T':
                    if (!Sql::toBool($question['OUVNONAPPL']) && Sql::toBool($question['QST_OBLIG']) && !Sql::toBool($question['TERMINE']) && Sql::toBool($question['QUEST_ACTIF'])) {
                        if (!$question['REP_TAB']) {
                            $error .= '<br /> - ' . Trad::strBuild($trad->t('La question @1@ (@2@) doit comporter une réponse.'), $question['LIB_QUEST'], $question['LIB_THEME']);
                        }
                    }
                    break;
                case 'O':
                    if (!Sql::toBool($question['OUVNONAPPL']) && Sql::toBool($question['QST_OBLIG']) && !Sql::toBool($question['TERMINE']) && Sql::toBool($question['QUEST_ACTIF'])) {
                        if ($question['REP_OUV'] == '') {
                            $error .= '<br /> - ' . Trad::strBuild($trad->t('La question @1@ (@2@) doit comporter une réponse.'), $question['LIB_QUEST'], $question['LIB_THEME']);
                        }
                    }

                    break;
                case 'N':
                    if (!Sql::toBool($question['OUVNONAPPL']) && Sql::toBool($question['QST_OBLIG']) && !Sql::toBool($question['TERMINE']) && Sql::toBool($question['QUEST_ACTIF'])) {
                        if ($question['REP_NUM'] == '') {
                            $error .= '<br /> - ' . Trad::strBuild($trad->t('La question @1@ (@2@) doit comporter une réponse.'), $question['LIB_QUEST'], $question['LIB_THEME']);
                        }
                    }
                    break;
                case 'L':
                    if (!Sql::toBool($question['OUVNONAPPL']) && Sql::toBool($question['QST_OBLIG']) && Sql::toBool($question['QUEST_ACTIF'])) {
                        if ((Sql::toBool($question['REP_LOG']) == false) && (Sql::toBool($question['TERMINE']) == false)) {
                            $error .= '<br /> - ' . Trad::strBuild($trad->t('La question @1@ (@2@) doit comporter une réponse.'), $question['LIB_QUEST'], $question['LIB_THEME']);
                        }
                    }
                    break;
                default:
                    break;
            }
        }

        return $error;
    }

    /**
     * validationQuestionnaire
     *
     * @param  string $idCamp
     * @param  string $idFrs
     * @param  bool $externe
     * @param  mixed $router
     * @param  mixed $contenaire
     * @param  string $jwt
     * @return void
     */
    public function validationQuestionnaire(string $idCamp, string $idFrs, bool $externe = false, $router = [], $contenaire = [], $jwt = ''): void
    {
        $this->evaluationRepository->depouilleurOrEvaluateurHasNotedWhileAnswering($idCamp, $idFrs);
        $this->evaluationRepository->validationQuestionnaire($idCamp, $idFrs, $externe);

        $campaignService = new CampaignService($this->pdo, $this->trad);

        if ($jsonDepExt = Fichier::getContentFile($_SESSION['Session_Login'] . ' ' . $idCamp . '_DepSaisieRepExterne')) {
            $jsonDepExt = json_decode($jsonDepExt, true);
        } else {
            $jsonDepExt = [];
        }

        $jsonDepExtTmp = [];
        foreach ($jsonDepExt as $json) {
            if (isset($json[0]) && is_array($json[0])) {
                $jsonDepExtTmp[] = $json[0];
            } else {
                $jsonDepExtTmp[] = $json;
            }
        }

        if (\count($jsonDepExtTmp) > 0) {
            $campaignService->sendMailToRaters((int) $idCamp, $contenaire, $router, $jsonDepExtTmp, $jwt);
        }

        // on vérifie que l'évaluation d'un fournisseur n'est pas terminée (tous les évaluateurs ont répondu)
        if ($this->evaluationRepository->checkThatSupplierAssessmentIsComplete($idCamp, $idFrs)) {
            // si l'évaluation d'un fournisseur est terminée, on met à jour son statut dans CAMP_LST_FOUR
            $this->evaluationRepository->updateSupplierStatus($idCamp, $idFrs);
        }

        // suppression des cookies
        unlink((new ParseBase1())->getRep()->tmp . $_SESSION['Session_Login'] . ' ' . $idCamp . '_DepSaisieRepExterne');
        unlink((new ParseBase1())->getRep()->tmp . $_SESSION['Session_Login'] . ' ' . $idCamp . '_DepSaisieRep');
    }

    /**
     * Summary of controleThemeEtQuestionPourDepouilleur
     * @param mixed $listeThemeCampTmp
     * @param mixed $listeQuestion
     * @param mixed $listeQuestionPropose
     * @param mixed $idcamp
     * @param mixed $canEdit
     * @param mixed $user
     * @return bool
     */
    public function controleThemeEtQuestionPourDepouilleur(&$listeThemeCampTmp, &$listeQuestion, &$listeQuestionPropose, $idcamp, &$canEdit = true, $user = false)
    {
        $user = $user ?: ($_SESSION['Session_Login'] ?? '');

        $listeQstDepouilleur = $this->evaluationRepository->listeQuestionDepouilleur(
            $idcamp,
        );

        if (count($listeQstDepouilleur) == 0) {
            return false;
        }

        $listeQuestion = (new Evaluation($this->pdo))->getAllQuesionForDepouilleur($user, $idcamp);

        $listeQuestionPropose = [];
        foreach ($listeQuestion as &$question) {
            // $listeQuestionPropose[($question['ID_PERE']?$question['ID_PERE']:$question['ID_THEME'])][] = $question;
            if ($question['NOTE'] == '0' && !Sql::toBool($question["OUV_NOTE"])) {
                $question['NOTE'] = '';
            }
            $listeQuestionPropose[$question['ID_THEME']][] = $question;
        }

        $arbo                 = (new Evaluation($this->pdo))->getArboQuestion($idcamp);
        $listeQuestionPropose = $this->treeBibliotheque('', $listeQuestionPropose, $arbo);

        $listeThemeCamp    = $this->evaluationRepository->getThemeParUser($idcamp);
        $listeThemeCampTmp = [];
        foreach ($listeThemeCamp as $theme) {
            $listeThemeCampTmp[$theme['ID_THEME']] = $theme;
        }
        return true;
    }
}
