<?php

namespace Modules\Evaluation\Controller;

use Entity\Model\CampAsso;
use Entity\Model\CampEnt;
use Entity\Model\CampEve;
use Entity\Model\CampGrpNot;
use Entity\Model\CampLstFour;
use Entity\Model\CampLstNotCamp;
use Entity\Model\CampLstNotFour;
use Entity\Model\CampLstNotGrp;
use Entity\Model\CampNotFin;
use Entity\Model\CampQstDep;
use Entity\Model\CampQstQ;
use Entity\Model\CampQstR;
use Entity\Model\CampQstTh;
use Entity\Model\CampSoc;
use Entity\Model\Periodes;
use GuzzleHttp\Psr7\Response;
use Helpers\Ariane\Ariane;
use Helpers\Ariane\ArianeSub;
use Helpers\ExportTo\Outils;
use Helpers\Fichier\Fichier;
use Helpers\Filter\FiltreAvance\Generator;
use Helpers\Filter\FiltreAvance\GeneratorCs;
use Helpers\Outil\Date;
use Helpers\Outil\Outils as OutilOutils;
use Helpers\Outil\Roles;
use Helpers\Outil\Sql;
use Helpers\Pagination\PaginatorGestion;
use Helpers\Trad\Trad;
use Modules\Evaluation\MenuContextuel\CampaignMenuContextuel;
use Modules\Evaluation\Service\ExportService;
use Skeleton\Controller\Controller;
use Modules\Evaluation\MenuContextuel\GestionMenuContextuel;
use Modules\Evaluation\Repository\Association;
use Modules\Evaluation\Repository\Campaign;
use Modules\Evaluation\Repository\Category;
use Modules\Evaluation\Repository\Evaluation;
use Modules\Evaluation\Service\CampaignService;
use Modules\Evaluation\Validator\CampaignValidator;
use Modules\Fournisseur\Repository\GestFourniss;
use PDO;
use PhpOffice\PhpSpreadsheet\IOFactory;

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

    private CampaignService $campaignService;
    private Campaign $repository;
    private PDO $pdoWithoutODBC;
    /**
     * init
     * gestion des droits
     *
     * @return void
     */
    public function init()
    {
        $this->pdoWithoutODBC = $this->contenaire->get('PDO.oxasql.withoutODBC');

        $this->campaignService = new CampaignService(
            $this->pdo,
            $this->getTranslationService(),
            $this->pdoStorage,
            $this->pdoWithoutODBC
        );

        $this->repository = new Campaign(
            $this->pdo,
            $this->pdoStorage,
            $this->pdoWithoutODBC
        );

        $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 indexAction(): string
    {
        $post = $this->request->getParsedBody();
        $trad = $this->getTranslationService();

        $categoryList = $this->_getCategories();
        $listePeriodes = $this->_getPeriodes();
        $listePeriodes[''] = $this->getTranslationService()->t('Toutes');

        $paginatorManagement = new PaginatorGestion();
        $paginatorManagement->generate('15', 'ID_CAMP', 'DESC');

        if ($this->droits['HA_CEVAVIS'] && !$this->droits['HA_CEVALCM']) {
            $post['filter_STATUT'] = 'T';
        }

        $campaignList = $this->repository->campaignList($post);

        $menuContextuel = new GestionMenuContextuel($this->pdo, $this->router, $trad, $this->droits);
        foreach ($campaignList as &$campaign) {
            $campaign['closingMessage'] = Trad::strBuild($trad->t('Voulez-vous clôturer la campagne @1@ ?'), $campaign['ID_CAMP']);

            $campaign['menuContextuel'] = $menuContextuel->generate($campaign);
        }

        Ariane::generate(0, $trad->t('Gestion'), $post, PaginatorGestion::getNbrArticle());
        $infoPagination = PaginatorGestion::getInfoPagination();

        $advancedFilter = new Generator($post);
        $advancedFilter->setFiltre('acc.DATE_DEB', 'date', 'Date de début');
        $advancedFilter->setFiltre('acc.DATE_FIN', 'date', 'Date de fin');

        $statusList = [
            '' => $trad->t('Tous'),
            'E' => $trad->t('En cours'),
            'A' => $trad->t('En attente de clôture'),
            'P' => $trad->t('En préparation'),
            'T' => $trad->t('Terminée'),
        ];

        return $this->renderer->render('@Evaluation/Campaign/index', [
            'campaignList' => $campaignList,
            'categoryList' => $categoryList,
            'statusList' => $statusList,
            'listePeriodes' => $listePeriodes,
            'filtreAvance' => $advancedFilter->getFiltres(),
            'initFiltreAvance' => $advancedFilter->getInit(),
            'post' => $post,
            'menuActive' => $_SESSION['typeMenu'] == 'S2C' ? 'Consultations' : 'Evaluations',
            // 'menuLeft'          => 'ratings',
            'infoPagination' => $infoPagination,
            'titre' => $trad->t('Campagnes d\'évaluation'),
            'droits' => $this->droits,
            'deleteMessage' => $trad->t('Voulez-vous supprimer la campagne @1@ ?'),
        ]);
    }

    /**
     * etatAvancementAction
     *
     * @return string
     */
    public function etatAvancementAction(): string
    {
        $post = $this->request->getParsedBody();
        $id = $this->request->getAttribute('id');

        $trad = $this->getTranslationService();

        $paginator = new PaginatorGestion();
        $paginator->generate(0, 'COD_NOTEUR');

        $evaluationRepository = new Evaluation($this->pdo);
        $listeNotationEnCours = $evaluationRepository->getUserByCampagne(
            $id,
            ['groupByType' => true] + $post
        );

        $campaignData = $this->campaignService
            ->campaignDetail(
                $id,
                $this->router,
                $this->droits
            );

        Ariane::generate(1, $trad->t('Etat d\'avancement par utilisateur'), $post, PaginatorGestion::getNbrArticle());

        $infoPagination = PaginatorGestion::getInfoPagination();

        return $this->renderer->render('@Evaluation/Campaign/etatAvancement', [
            'menuActive' => $_SESSION['typeMenu'] == 'S2C' ? 'Consultations' : 'Evaluations',
            'menuLeft' => 'ratings',
            'post' => $post,
            'campStat' => [
                'countTermine' => intval($listeNotationEnCours[0]['Stat_countTermine'] ?? 0),
                'count' => intval($listeNotationEnCours[0]['Stat_count'] ?? 0),
            ],
            'listeNotationEnCours' => $listeNotationEnCours,
            'infoPagination' => $infoPagination,
            'idCamp' => $id,
            'date' => $campaignData['DTECREAT'],
            'par' => $campaignData['CREATOR'],
            'campagne' => $campaignData,
        ]);
    }

    /**
     * etatAvancementAction
     * L'écran qui vas nous afficher la liste des fournisseur pour une campagne en question
     *
     * @return string
     */
    public function etatAvancementByFournissAction(): string
    {
        $post = $this->request->getParsedBody();
        $id = $this->request->getAttribute('id');

        $trad = $this->getTranslationService();

        $paginator = new PaginatorGestion();
        $paginator->generate(0, 'CODE_FOU');

        $listeFournissByIdCamp =
            (new Evaluation($this->pdo))
            ->getFournisseurByCamp($id, $post);

        $campaignData = $this->campaignService
            ->campaignDetail(
                $id,
                $this->router,
                $this->droits
            );

        Ariane::generate(1, $trad->t('Etat d\'avancement par fournisseur'), $post, PaginatorGestion::getNbrArticle());

        $infoPagination = PaginatorGestion::getInfoPagination();

        return $this->renderer->render('@Evaluation/Campaign/etatAvancementByFourniss', [
            'menuActive' => $_SESSION['typeMenu'] == 'S2C' ? 'Consultations' : 'Evaluations',
            'menuLeft' => 'ratings',
            'post' => $post,
            'campagne' => $campaignData,
            'campStat' => [
                'countTermine' => intval($listeFournissByIdCamp[0]['Stat_countTermine'] ?? 0),
                'count' => intval($listeFournissByIdCamp[0]['Stat_count'] ?? 0),
            ],
            'listeFournissByIdCamp' => $listeFournissByIdCamp,
            'infoPagination' => $infoPagination,
            'idCamp' => $id,
            'date' => $campaignData['DTECREAT'],
            'par' => $campaignData['CREATOR'],
        ]);
    }
    /**
     * detailEtatAvancementAction
     *
     * @return string
     */
    public function detailEtatAvancementAction(): string
    {
        $id = $this->request->getAttribute('id');
        $user = $this->request->getAttribute('user');
        $externe = $this->request->getAttribute('externe');
        $post = $this->request->getParsedBody();

        $paginator = new PaginatorGestion();
        $paginator->generate(0, 'COD_NOTEUR');

        $listeNotationEnCours = (new Evaluation($this->pdo))->getDetailUserByCampagne($id, $user, $externe, $post);

        $infoPagination = PaginatorGestion::getInfoPagination();

        return $this->renderer->render('@Evaluation/Campaign/detailEtatAvancement', [
            'menuActive' => $_SESSION['typeMenu'] == 'S2C' ? 'Consultations' : 'Evaluations',
            'menuLeft' => 'ratings',
            'post' => $post,
            'listeNotationEnCours' => $listeNotationEnCours,
            'infoPagination' => $infoPagination,
            'idCamp' => $id,
        ]);
    }

     /**
     * detailEtatAvancementAction
     * Ici on vas afficher dans la loupe la liste des noteurs depuis la loupe de l'écran Etat d'avancement par fournisseur
     *
     * @return string
     */
    public function detailEtatAvancementByFournissAction(): string
    {
        $id = $this->request->getAttribute('id');
        $fourniss = $this->request->getAttribute('fourniss');
        $post = $this->request->getParsedBody();

        $paginator = new PaginatorGestion();
        $paginator->generate(0, 'COD_NOTEUR');

        $listeNotationEnCours = (new Evaluation($this->pdo))->getUserByCampagne(
            $id,
            ['filter_egal_CODE_FOU' => $fourniss] + $post
        );

        $infoPagination = PaginatorGestion::getInfoPagination();

        return $this->renderer->render('@Evaluation/Campaign/detailEtatAvancementByFourniss', [
            'menuActive' => $_SESSION['typeMenu'] == 'S2C' ? 'Consultations' : 'Evaluations',
            'menuLeft' => 'ratings',
            'post' => $post,
            'listeNotationEnCours' => $listeNotationEnCours,
            'infoPagination' => $infoPagination,
            'idCamp' => $id,
        ]);
    }

    /**
     * detailEtatAvancementByCampagneAction
     *
     * @return string
     */
    public function detailEtatAvancementByCampagneAction(): string
    {
        $id = $this->request->getAttribute('id');
        $type = $this->request->getAttribute('type');
        $post = $this->request->getParsedBody();

        $paginator = new PaginatorGestion();
        $paginator->generate(0, 'CODE_FOU');

        $listeNotationEnCours = (new Evaluation($this->pdo))->getFournisseurByCamp($id, $post);

        $infoPagination = PaginatorGestion::getInfoPagination();

        return $this->renderer->render('@Evaluation/Campaign/detailEtatAvancement', [
            'menuActive' => $_SESSION['typeMenu'] == 'S2C' ? 'Consultations' : 'Evaluations',
            'menuLeft' => 'ratings',

            'post' => $post,
            'listeNotationEnCours' => $listeNotationEnCours,
            'infoPagination' => $infoPagination,
            'idCamp' => $id,
            'contexte' => 'campagne',
            'type' => $type
        ]);
    }

    /**
     * createditAction
     *
     * @return string
     */
    public function createditAction()
    {
        $post = $this->request->getParsedBody();
        $id = $this->request->getAttribute('id');
        $trad = $this->getTranslationService();

        $categoryList = $this->_getCategories();
        $periodCodes = $this->_getPeriodes();

        if ($id) {
            $action = 'modification';
            $campaign = $this->campaignService
                ->campaignDetail(
                    $id,
                    $this->router,
                    $this->droits
                );

            $companiesList = array_column(
                (new CampSoc($this->pdo))
                    ->findAll(
                        ['ID_CAMP' => $id],
                        ['CODE_STE']
                    ),
                'CODE_STE'
            );

            $campaign['SOCIETE'] = \implode('/', $companiesList);
            $ariane = $trad->t('Modification campagne');
        } else {
            $action = 'creation';
            $ariane = $trad->t('Nouvelle campagne');
        }

        Ariane::generate(1, $ariane);

        return $this->renderer->render('@Evaluation/Campaign/createdit', [
            'menuActive' => $_SESSION['typeMenu'] == 'S2C' ? 'Consultations' : 'Evaluations',
            'menuLeft' => 'ratings',
            'post' => $post,
            'title' => $trad->t('Campagnes d\'évaluation'),
            'categoryList' => $categoryList,
            'campaign' => $campaign ?? '',
            'action' => $action,
            'periodCodes' => $periodCodes,
            'droits' => $this->droits,
            'deleteMessage' => $trad->t('Voulez-vous supprimer la campagne @1@ ?'),
        ]);
    }

    /**
     * duplicateAction
     *
     * @return string
     */
    public function duplicateAction()
    {
        $campaignToDuplicateId = $this->request->getAttribute('id');
        $post = $this->request->getParsedBody();
        $trad = $this->getTranslationService();

        $categoryList = $this->_getCategories();
        $periodCodes = $this->_getPeriodes();

        $campEnt = new CampEnt($this->pdo);

        $campaignToDuplicate = $campEnt->find([
            'ID_CAMP' => $campaignToDuplicateId
        ]);

        // si la campagne dupliquée ne concerne pas toutes les sociétés, on va récupérer la liste des sociétés concernées
        if (! Sql::toBool($campaignToDuplicate['TOUTESTE'])) {
            $companiesList = array_column(
                (new CampSoc($this->pdo))
                    ->findAll(
                        ['ID_CAMP' => $campaignToDuplicateId],
                        ['CODE_STE']
                    ),
                'CODE_STE'
            );
            $campaignToDuplicate['SOCIETE'] = \implode('/', $companiesList);
        }

        $subtitle = Trad::strBuild($trad->t('Duplication de la campagne @1@'), $campaignToDuplicate['LIBELLE']);

        Ariane::generate(1, $trad->t('Duplication campagne'));

        // on redirige vers l'écran de modification de l'entête de la campagne nouvellement créée
        return $this->renderer->render('@Evaluation/Campaign/createdit', [
            'menuActive' => $_SESSION['typeMenu'] == 'S2C' ? 'Consultations' : 'Evaluations',
            'id' => $campaignToDuplicateId,
            'menuLeft' => 'create',
            'subtitle' => $subtitle,
            'post' => $post,
            'title' => $trad->t('Campagnes d\'évaluation'),
            'categoryList' => $categoryList,
            'campaign' => $campaignToDuplicate ?? '',
            'action' => 'duplication',
            'periodCodes' => $periodCodes,
            'droits' => $this->droits,
        ]);
    }

    /**
     * validateAction
     *
     * @return string|Response
     */
    public function validateAction()
    {
        $post = $this->request->getParsedBody();
        $id = $this->request->getAttribute('id');
        $action = $this->request->getAttribute('action');

        $trad = $this->getTranslationService();

        $campEvent = new CampEve($this->pdo);
        $campEnt = new CampEnt($this->pdo);
        $validator = $this->createValidator();

        if (!$action) {
            if ($id) {
                $action = 'modification';
            } else {
                $action = 'creation';
            }
        }

        $validator->isStringAvecEspace($trad->t("Libellé"), $post['LIBELLE'], 1, 120);
        $validator->isStringAvecEspace($trad->t("Description"), $post['DESCRIPTION'], 0, 3000);
        Date::dateToSql($post['DTEFIN_PREVUE']);
        Date::dateToSql($post['DTEDEB_PREVUE']);
        if ($post['DTEFIN_PREVUE'] == '') {
            $validator->setError($trad->t('La date de fin prévue ne peut pas être vide.'));
        } else {
            if ($post['DTEFIN_PREVUE'] < $post['DTEDEB_PREVUE']) {
                $validator->setError($trad->t('La date de fin prévue ne peut pas être antérieur à la date de début prévue.'));
            }
            $validator->isDateGreaterThanToday($post['DTEFIN_PREVUE'], $trad->t('Date de fin prévue'));
        }

        if ($post['DTEDEB_PREVUE'] == '') {
            $validator->setError($trad->t('La date de début prévue ne peut pas être vide.'));
        } else {
            if ($post['DTEDEB_PREVUE'] > $post['DTEFIN_PREVUE']) {
                $validator->setError($trad->t('La date de début prévue ne peut pas être supérieure à la date de fin prévue.'));
            }
            if ($post['DTEDEB_PREVUE'] < \date('Ymd')) {
                $validator->setError($trad->t('La date de début prévue est dans le passé.'));
            }
        }

        if ($post['HEUREDEB_PREVUE'] == '') {
            $validator->setError($trad->t('L\'heure de début prévue ne peut pas être vide.'));
        } else {
            $validator->isHourWithSecondeCC($trad->t('Heure de début prévue'), $post['HEUREDEB_PREVUE']);
        }
   
        if (!isset($post['HEUREFIN_PREVUE']) || $post['HEUREFIN_PREVUE'] == '') {
            $validator->setError($trad->t('L\'heure de fin prévue ne peut pas être vide.'));
        } else {
            $validator->isHourWithSecondeCC($trad->t('Heure de fin prévue'), $post['HEUREFIN_PREVUE']);
        }

        if (($post['DTEDEB_PREVUE'] == $post['DTEFIN_PREVUE'])
            && (str_replace(':', '', $post['HEUREFIN_PREVUE']) < str_replace(':', '', $post['HEUREDEB_PREVUE']))
        ) {
            $validator->setError($trad->t('L\'heure de fin ne peut être inférieure à l\'heure de début.'));
        }
       
        if (!sql::toBool($post['TOUTESTE'] ?? false) && $post['societe'] == '') {
            $validator->setError($trad->t('Veuillez sélectionner au moins une société.'));
        }

        if ($post['COD_PER'] == '') {
            $validator->setError($trad->t('La période est obligatoire, veuillez la renseigner'));
        }

        if (sql::toBool($post['TOUTESTE'] ?? false)) {
            unset($post['societe']);
        }

        if (!$validator->isValid()) {
            return $this->renderer->render('@popup-erreur/ErreurCreation', [
                'ErreurValid' => $validator->getError(),
            ]);
        } else {
            switch ($action) {
                case 'creation':
                    $post['ID_CAMP'] = intval($this->repository->getMaxIdCamp()['MAX_ID']) + 1;

                    if (isset($post['societe']) && $post['societe'] != '') {
                        $companies = \explode('/', $post['societe']);
                        $this->repository->companiesMultiInsert($post['ID_CAMP'], $companies);
                    }
                    $this->repository->campaignNew($post);
                    $orderNumber = intval($campEvent->find(['ID_CAMP' => $post['ID_CAMP']], ['MAX(NUM_ORDR)'], [], PDO::FETCH_ASSOC)['']) + 1;
                    $campEvent->insert([
                        'ID_CAMP' => $post['ID_CAMP'],
                        'NUM_ORDR' => $orderNumber,
                        'DTE_EVE' => \date('Ymd'),
                        'HEU_EVE' => \date('His'),
                        'ID_USER' => $_SESSION['Session_Login'],
                        'COD_EVE' => 'CRE',
                        'COMMENTAIRE' => $trad->t('Création de la campagne'),
                    ]);
                    return new Response(443, [], (string) \json_encode([
                        'path' => $this->router->generateUri('Evaluation.Campaign.detail', ['id' => $post['ID_CAMP']])
                    ]));

                case 'duplication':
                    $post['ID_CAMP'] = intval($this->repository->getMaxIdCamp()['MAX_ID']) + 1;

                    if (isset($post['societe']) && $post['societe'] != '') {
                        $companies = \explode('/', $post['societe']);
                        $this->repository->companiesMultiInsert($post['ID_CAMP'], $companies);
                    }

                    $campaignToDuplicate = $this->campaignService
                        ->campaignDetail(
                            $id,
                            $this->router,
                            $this->droits
                        );

                    // on commence par créer l'entête de la nouvelle campagne
                    $this->repository->campaignNew($post);

                    // puis on duplique les éléments des autres tables
                    $this->repository->duplicateCampaign($id, $post['ID_CAMP']);

                    // on crée l'évènement création avec le commentaire indiquant qu'il s'agit d'une duplication
                    $orderNumber = intval($campEvent->find(['ID_CAMP' => $post['ID_CAMP']], ['MAX(NUM_ORDR)'], [], PDO::FETCH_ASSOC)['']) + 1;
                    $campEvent->insert([
                        'ID_CAMP' => $post['ID_CAMP'],
                        'NUM_ORDR' => $orderNumber,
                        'DTE_EVE' => \date('Ymd'),
                        'HEU_EVE' => \date('His'),
                        'ID_USER' => $_SESSION['Session_Login'],
                        'COD_EVE' => 'CRE',
                        'COMMENTAIRE' => Trad::strBuild($trad->t('Duplication de la campagne @1@'), $campaignToDuplicate['LIBELLE']),
                    ]);
                    return new Response(443, [], (string) \json_encode([
                        'path' => $this->router->generateUri('Evaluation.Campaign.detail', ['id' => $post['ID_CAMP']])
                    ]));

                case 'modification':
                    (new CampSoc($this->pdo))->delete([
                        'ID_CAMP' => $id
                    ]);

                    if (isset($post['societe']) && $post['societe'] != '') {
                        $companies = \explode('/', $post['societe']);
                        $this->repository->companiesMultiInsert($id, $companies);
                    }

                    $campEnt->update([
                        'LIBELLE' => $post['LIBELLE'],
                        'DESCRIPT' => $post['DESCRIPTION'],
                        'TOUTESTE' => sql::toBool($post['TOUTESTE'] ?? false),
                        'ID_GRILLE' => $post['CATEGORIE'],
                        'COD_PER' => $post['COD_PER'],
                        'DTEFIN_PREVUE' => $post['DTEFIN_PREVUE'],
                        'DTEDEB_PREVUE' => $post['DTEDEB_PREVUE'],
                        'HEUREDEB_PREVUE' => str_replace(':', '', $post['HEUREDEB_PREVUE']),
                        'HEUREFIN_PREVUE' => str_replace(':', '', $post['HEUREFIN_PREVUE']),
                    ], [
                        'ID_CAMP' => $id
                    ]);

                    return new Response(443, [], (string) \json_encode([
                        'path' => $this->router->generateUri('Evaluation.Campaign.detail', ['id' => $id])
                    ]));

                default:
                    return new Response(443, [], (string) \json_encode([
                        'path' => $this->router->generateUri('Evaluation.Campaign.index')
                    ]));
            }
        }
    }

    public function suppressionAction()
    {
        $id = $this->request->getAttribute('id');
        $campEnt = new CampEnt($this->pdo);
        $campEve = new CampEve($this->pdo);
        $trad = $this->getTranslationService();

        $campaign = $this->campaignService
            ->campaignDetail(
                $id,
                $this->router,
                $this->droits
            );

        $campaignStatus = $campEnt->find([
            'ID_CAMP' => $id
        ], ['STATUT'], [], PDO::FETCH_ASSOC)['STATUT'];

        switch ($campaignStatus) {
            case 'E':
                $status = $trad->t('En cours');
                break;
            case 'T':
                $status = $trad->t('Terminée');
                break;
            case 'P':
                $status = $trad->t('En préparation');
                break;
            default:
                $status = '';
                break;
        }

        if ($campaignStatus != 'P') {
            return new Response(443, [], $this->renderer->render('@popup-erreur/erreurAlerteEtAvertissement', [
                'params' => [
                    'alerte' => Trad::strBuild($trad->t('Vous ne pouvez pas supprimer une campagne dont le statut est "@1@".'), $status),
                ],
            ]));
        }

        $orderNumber = intval($campEve->find(['ID_CAMP' => $id], ['MAX(NUM_ORDR)'], [], PDO::FETCH_ASSOC)['']) + 1;

        $campEve->insert([
            'ID_CAMP' => $id,
            'NUM_ORDR' => $orderNumber,
            'DTE_EVE' => \date('Ymd'),
            'HEU_EVE' => \date('His'),
            'ID_USER' => $_SESSION['Session_Login'],
            'COD_EVE' => 'SUP',
            'COMMENTAIRE' => Trad::strBuild($trad->t('Suppression de la campagne @1@ par @2@'), $campaign['LIBELLE'], $_SESSION['Session_Login'])
        ]);

        $campEnt->delete([
            'ID_CAMP' => $id,
        ]);
        (new CampAsso($this->pdo))->delete([
            'ID_CAMP' => $id,
        ]);
        (new CampGrpNot($this->pdo))->delete([
            'ID_CAMP' => $id,
        ]);
        (new CampLstFour($this->pdo))->delete([
            'ID_CAMP' => $id,
        ]);
        (new CampLstNotCamp($this->pdo))->delete([
            'ID_CAMP' => $id,
        ]);
        (new CampLstNotFour($this->pdo))->delete([
            'ID_CAMP' => $id,
        ]);
        (new CampLstNotGrp($this->pdo))->delete([
            'ID_CAMP' => $id,
        ]);
        (new CampSoc($this->pdo))->delete([
            'ID_CAMP' => $id,
        ]);
        (new CampQstDep($this->pdo))->delete([
            'ID_CAMP' => $id,
        ]);
        (new CampQstQ($this->pdo))->delete([
            'ID_CAMP' => $id,
        ]);
        (new CampQstR($this->pdo))->delete([
            'ID_CAMP' => $id,
        ]);
        (new CampQstTh($this->pdo))->delete([
            'ID_CAMP' => $id,
        ]);

        return new Response(200, [], (string) \json_encode([
            'statut' => 'O',
            'path' => $this->router->generateUri('Evaluation.Campaign.index'),
            'pathOnlyRedirect' => true,
        ]));
    }

    public function detailAction()
    {
        $trad = $this->getTranslationService();

        $id = $this->request->getAttribute('id');
        $tab = $this->request->getAttribute('tab');

        Ariane::generate(1, $trad->t('Détails campagne'));

        ArianeSub::init();
        ArianeSub::generate(0, 0, $trad->t('Fournisseurs'), $this->router->generateUri('Evaluation.Campaign.detail', ['id' => $id, 'tab' => 'fournisseur']), ($tab ?? '') !== ''
            ? ($tab == 'fournisseur'
                ? 1
                : 0)
            : 1);
        ArianeSub::generate(0, 1, $trad->t('Questionnaire'), $this->router->generateUri('Evaluation.BibliothequeDeQuestions.gestionBibliotheque', ['mode' => 'campagne', 'idCamp' => $id]));
        ArianeSub::generate(0, 2, $trad->t('Évaluateurs'), $this->router->generateUri('Evaluation.Rater.informations', ['id' => $id, 'mode' => 'campaign']));

        $campaignDetail = $this->campaignService
            ->campaignDetail(
                $id,
                $this->router,
                $this->droits
            );
        $modeSaisieRep = false;

        if ($campaignDetail['STATUT']) {
            $modeSaisieRep = true;
        }

        if ($tab == 'fournisseur' || $tab == '') {
            $supplierList = $this->repository->campaignSupplierList($id, $modeSaisieRep);

            $menuContextuel = new CampaignMenuContextuel($this->pdo, $this->router, $this->getTranslationService());

            foreach ($supplierList as &$supplier) {
                $supplier['menuContextuel'] = $menuContextuel->generate($id, $supplier['CODE_FOU'], $supplier['RS']);
            }

            $paginatorManagement = new PaginatorGestion();
            $paginatorManagement->generate('5', 'RS', 'DESC');

            $infoPagination = PaginatorGestion::getInfoPagination();

            $typeFournisseur = [
                'F' => $trad->t('Fournisseur'),
                'G' => $trad->t('Groupement'),
            ];
        } elseif ($tab == 'Assocations/indexV2') {
            return $this->redirect('Evaluation.Association.index', ['id' => $id, 'mode' => 'campaign']);
        }

        $companiesList = array_column(
            (new CampSoc($this->pdo))
                ->findAll(
                    ['ID_CAMP' => $id],
                    ['CODE_STE']
                ),
            'CODE_STE'
        );

        return $this->renderer->render('@Evaluation/Campaign/detail', [
            'id' => $id,
            'tab' => $tab ?? '',
            'title' => $trad->t('Campagnes d\'évaluation'),
            'pathBack' => ariane::getBackPath(),
            'menuActive' => $_SESSION['typeMenu'] == 'S2C' ? 'Consultations' : 'Evaluations',
            'menuLeft' => 'ratings',
            'campaign' => $campaignDetail,
            'supplierList' => $supplierList ?? [],
            'companiesList' => $companiesList,
            'typeFournisseur' => $typeFournisseur ?? [],
            'infoPagination' => $infoPagination ?? '',
            'droits' => $this->droits,
            'deleteMessage' => $trad->t('Voulez-vous supprimer la campagne @1@ ?'),
        ]);
    }

    public function exportAction(): string
    {
        $post = $this->request->getParsedBody();
        $exportService = new ExportService($this->pdo, $this->getTranslationService());

        $campaignList = $this->repository->campaignList($post);
        $campaignList = $exportService->formatValues($campaignList, 'gestion');

        $tab = $exportService->getExportCol('gestion');

        Outils::gestionEmailAsync2(
            "export_liste_campagnes",
            $campaignList,
            $this->JWTKEY,
            $this->router,
            $this->getTranslationService(),
            $tab
        );

        return 'ok';
    }

    public function supplierListAction(): string
    {
        $campaignId = $this->request->getAttribute('id');
        $post = $this->request->getParsedBody();
        $associationsRepo = new Association($this->pdo);
        $trad = $this->getTranslationService();

        Ariane::generate(2, $trad->t('Ajout fournisseur'));

        $selectList = [];
        if (!$post) {
            $post['tri_RS'] = 'asc';
        } else {
            foreach ($post as $key => $value) {
                if (strpos($key, 'save_selected_frs_') === 0) {
                    $selectList[$key] = $value;
                }
            }
        }

        $campaign = $this->campaignService
            ->campaignDetail(
                $campaignId,
                $this->router,
                $this->droits
            );

        $paginatorManagement = new PaginatorGestion();
        $paginatorManagement->generate('10', 'RS', 'ASC');

        $supplierList = $this->repository->supplierList($campaignId, $post);

        $infopagination = PaginatorGestion::getInfoPagination();

        $trad = $this->getTranslationService();

        // on traduit le type de fournisseur (les libellés existent déjà dans l'export des textes, il s'agit de 'Tous', 'Prospect' et 'Référencé')
        // foreach ($supplierList as &$supplier) {
        //     $supplier['TYPE'] = $trad->t($supplier['TYPE']);
        // }

        /* Filtres */
        // on définit les différents types de fournisseurs pour le select des filtres
        $supplierTypes = [
            '' => $trad->t('Tous'),
            'P' => $trad->t('Prospect'),
            'R' => $trad->t('Référencé'),
            'O' => $trad->t('Occasionnel'),
        ];

        // on définit les règles de filtrage numériques
        $numericRules = [
            '' => $trad->t('Tous'),
            'E' => $trad->t('égal à'),
            'G' => $trad->t('supérieur à'),
            'L' => $trad->t('inférieur à'),
            'B' => $trad->t('entre'),
        ];

        // on définit les règles de filtrage pour les chiffres d'affaires
        $turnoverRules = [
            '' => $trad->t('Tous'),
            'E' => $trad->t('égal à'),
            'G' => $trad->t('supérieur à'),
            'L' => $trad->t('inférieur à'),
            'B' => $trad->t('entre'),
        ];

        // pour les chiffres d'affaires générés, on peut choisir 'commandé', 'réalisé' ou 'facturé'
        $turnoverTypes = [
            '' => $trad->t('Tous'),
            'C' => $trad->t('Commandé'),
            'R' => $trad->t('Réalisé'),
            'F' => $trad->t('Facturé'),
        ];

        // on définit les règles de filtrage pour les documents
        $documentRules = [
            '' => $trad->t('Sans les filtres de campagne'),
            'F' => $trad->t('Avec les filtres de campagne'),
        ];

        // on récupère les filtres de campagne (éléments concernés) pour filtrer les appels d'offres, commandes et factures
        $tempCampaignFilters = $associationsRepo->getAssociationsById($campaignId);
        $campaignFilters = [
            '' => $trad->t('Choisissez un filtre'),
            'ALL' => $trad->t('Tous')
        ];
        foreach ($tempCampaignFilters as $filter) {
            $campaignFilters[$filter['TYPE_OBJ']] = $filter['LIBELLE'];
        }

        // ArianeSub::generate(1, 0, $trad->t('Ajout fournisseur'), $this->router->generateUri('Evaluation.Campaign.supplierList', ['id' => $campaignId]), 1);

        /* Chargement du tableau de filtrage */
        $listeTypeFourniss   = (new GestFourniss($this->pdo))->listeTypeFournisseur();
        $tabTypeFourniss[''] = $trad->t('Tous les fournisseurs');

        for ($i = 0; $i < count($listeTypeFourniss); $i++) {
            $tabTypeFourniss[$listeTypeFourniss[$i]['LIBELLE']] = $listeTypeFourniss[$i]['LIBELLE'];
        }

        /* Filtre avancées */
        $filtreAvance = new GeneratorCs($post, 'FOURNISS', 'F.CODE', $this->pdo, $trad);

        $filtreAvance->setFiltre('F.NO_SIRET', 'text', $trad->t('N° de SIRET'));
        $filtreAvance->setFiltre('F.NO_TVA_IC', 'text', $trad->t('N° de TVA IC'));
        $filtreAvance->setFiltre('F.DTE_AGREM', 'date', $trad->t('Date d’agrément'));
        $filtreAvance->setFiltre('F.ENSCOMM', 'text', $trad->t('Enseigne commerciale'));
        $filtreAvance->setFiltre('F.CA_MIN_ST', 'numeric', $trad->t('CA Minimum sous-traitant'));
        $filtreAvance->setFiltre('F.CA_MAX_ST', 'numeric', $trad->t('CA Maximum sous-traitant'));
        $filtreAvance->setFiltre('PARTENAIRE', 'bool', $trad->t('Est partenaire'), '', null, null, 'vide');
        $filtreAvance->setFiltre('F.GEREPORTAIL', 'bool', $trad->t('Fournisseur OXA.LINK ?'), '', null, null, 'bdd');
        $filtreAvance->setFiltre('F.FOURPREF', 'bool', $trad->t('Fournisseur Préferentiel ?'), '', null, null, 'bdd');
        $filtreAvance->setFiltre('F.MODE_PAIE', 'liste', $trad->t('Mode de paiement'), '', 'Ajax.liste.modePaiement', 'Modepaie');
        $filtreAvance->setFiltre('F.COND_PAIE', 'liste', $trad->t('Conditions de paiement'), '', 'Ajax.liste.conditionPaiement', 'CondPaie');
        $filtreAvance->setFiltre('F.ID_EXT', 'text', $trad->t('identifiant externe'));

        $filtreAvance->setFiltre('F.TYP_TVA', 'liste', $trad->t('Type de tva'), '', 'Ajax.liste.typeTVA', 'typeTVA');
        $filtreAvance->setFiltre('F.DEFTYPDOC', 'liste', $trad->t('Type de document'), '', 'Ajax.liste.typeDoc', 'typeDoc');
        $filtreAvance->setFiltre('F.MNTMINFAC', 'numeric', $trad->t('Minimum de facturation'));
        $filtreAvance->setFiltre('F.AUTOCC', 'bool', $trad->t('Autorisé à Cde eProc'), '', null, null, 'bdd');
        $filtreAvance->setFiltre('F.NOCCGEN', 'bool', $trad->t('interdire à Cde eProc sur articles hors catalogue'), '', null, null, 'bdd');
        $filtreAvance->setFiltre('F.SEUILEPDIF', 'bool', $trad->t('Seuils Cde eProc différents Catalogue / hors catalogue ?'), '', null, null, 'bdd');
        $filtreAvance->setFiltre('F.RFRACT', 'bool', $trad->t('Règle de franco active ?'), '', null, null, 'bdd');
        $filtreAvance->setFiltre('F.MNTMINFRA', 'numeric', $trad->t('Minimum de franco'));

        $filtreAvance->setFiltre('F.FRPOBLIG', 'bool', $trad->t('Frais de port obligatoire ?'), '', null, null, 'bdd');
        $filtreAvance->setFiltre('F.NO_DUNS', 'text', $trad->t('DUNS Number'));
        $filtreAvance->setFiltre('F.FRANCTVA', 'bool', $trad->t('Achat systématique en franchise de TVA ?'), '', null, null, 'bdd');
        $filtreAvance->setFiltre('F.NOT_MANU', 'bool', $trad->t('Notation manuelle systématique'), '', null, null, 'bdd');
        $filtreAvance->setFiltre('F.NAUTOSFA', 'bool', $trad->t('Pas d alimentation automatique des Sous-Familles'), '', null, null, 'bdd');
        $filtreAvance->setFiltre('F.RECEP_AUTO', 'bool', $trad->t('Réception automatique des cdes'), '', null, null, 'bdd');
        $filtreAvance->setFiltre('F.RS_REGL', 'text', $trad->t('Raison sociale de règlement'));
        $filtreAvance->setFiltre('F.RS_REGL', 'text', $trad->t('Raison sociale de règlement'));
        $filtreAvance->setFiltre('F.ZONE_LIB1', 'text', $trad->t('Zone libre 1'));
        $filtreAvance->setFiltre('F.ZONE_LIB2', 'text', $trad->t('Zone libre 2'));
        $filtreAvance->setFiltre('F.CODE_PAYS', 'liste', $trad->t('Pays'), '', 'Ajax.liste.pays', 'Pays');
        $filtreAvance->setFiltre('F.FOURPRIN', 'liste', $trad->t('Groupement'), '', 'Ajax.liste.grpfou', 'Grpfou');

        return $this->renderer->render('@Evaluation/Campaign/Fournisseur/list', [
            'id' => $campaignId,
            'menuActive' => $_SESSION['typeMenu'] == 'P2P' ? 'eproc' : 'Evaluations',
            'menuLeft' => 'ratings',
            'post' => $post,
            'campaign' => $campaign,
            'listeFrs' => $supplierList,
            'infoPagination' => $infopagination,
            'listeSelectInput' => $selectList,
            'droits' => $this->droits,
            'supplierTypes' => $supplierTypes,
            'numericRules' => $numericRules,
            'turnoverRules' => $turnoverRules,
            'turnoverTypes' => $turnoverTypes,
            'documentRules' => $documentRules,
            'campaignFilters' => $campaignFilters,
            'initFiltreAvance' => $filtreAvance->getInit(),
            'filtreAvance' => $filtreAvance->getFiltres(),
            'deleteMessage' => $trad->t('Voulez-vous supprimer la campagne @1@ ?'),
            'tabTypeFourniss' => $tabTypeFourniss,
            'listeEtat' => [
                ''           => $trad->t('Tous les fournisseurs'),
                'VALIDE'     => $trad->t('Fournisseur valide'),
                'NON_VALIDE' => $trad->t('Fournisseur non valide'),
            ],
        ]);
    }

    public function addSupplierAction(): Response
    {
        $campaignId = $this->request->getAttribute('id');
        $post = $this->request->getParsedBody();

        $suppliers = [];
        foreach (array_keys($post) as $key) {
            if (strpos($key, 'save_selected_frs_') === 0) {
                $supplier = substr($key, 18);
                $suppliers[] = $supplier;
            }
        }

        $this->repository->supplierMultiInsert($campaignId, $suppliers);

        return new Response(200, [], (string) \json_encode([]));
    }

    public function supplierImportIndexAction(): string
    {
        $trad = $this->getTranslationService();

        $campaignId = $this->request->getAttribute('id');
        $campaign = $this->campaignService
            ->campaignDetail(
                $campaignId,
                $this->router,
                $this->droits
            );


        ArianeSub::generate(1, 0, $trad->t('Import fournisseurs'), $this->router->generateUri('Evaluation.Campaign.supplierImportIndex', ['id' => $campaignId]), 1);

        return $this->renderer->render('@Evaluation/Campaign/detail', [
            'menuActive' => $_SESSION['typeMenu'] == 'S2C' ? 'Consultations' : 'Evaluations',
            'menuLeft' => 'ratings',
            'campaign' => $campaign,
            'tab' => 'Suppliers/import',
            'id' => $campaignId,
            'droits' => $this->droits,
        ]);
    }

    /**
     * supplierImportAction
     *
     * @return  string|Response
     */
    public function supplierImportAction()
    {
        $post = $this->request->getParsedBody();
        $campaignId = $this->request->getAttribute('id');

        $trad = $this->getTranslationService();

        $file = $this->request->getUploadedFiles();

        if ($file) {
            $filename = $file['importFile']->getClientFilename();
            $fileSize = $file['importFile']->getSize();
        } else {
            $filename = null;
            $fileSize = 0;
        }

        $validator = $this->createValidator();
        $validator->fileCheck($trad->t('Fichier d\'import'), $filename ?? '', ['xls', 'xlsx', 'csv'], '', $fileSize);

        if (! $validator->isValid()) {
            return $this->renderer->render('@popup-erreur/ErreurCreation', [
                'ErreurValid' => $validator->getError(),
                'desactiveRow' => true,
            ]);
        }

        // on enregistre le fichier d'import dans les fichiers temporaires
        $newPath = Fichier::UploadDocAtt($filename);
        $file['importFile']->moveTo($newPath["racine"] . $newPath["new_name"]);
        $newName = $newPath["racine"] . $newPath["new_name"];

        // on récupère les valeurs des colonnes qui nous intéressent (ici la première uniquement)
        $spreadsheet = IOFactory::load($newName);
        $sheet = $spreadsheet->getSheet(0);
        $totalRows = $sheet->getHighestRow();

        try {
            $arrayImport = [];
            foreach ($sheet->getRowIterator(1, $totalRows) as $row) {
                foreach ($row->getCellIterator('A', 'A') as $cell) {
                    $value = $cell->getCalculatedValue();
                    $arrayImport[] = $value;
                }
            }
        } catch (\PhpOffice\PhpSpreadsheet\Exception $e) {
            return $this->renderer->render('@popup-erreur/ErreurCreation', [
                'ErreurValid' => 'Unreadable spreadsheet',
                'desactiveRow' => true,
            ]);
        }

        // on élimine les doublons avant l'import
        // $arrayImport = \array_unique($arrayImport);

        // on vérifie les codes fournisseur reçus et on retourne le compte de fournisseurs OK, la liste des fournisseurs qui n'existent pas et la liste des fournisseurs qui étaient déjà enregistrés dans la campagne
        $import = $this->repository->importCampaignSuppliers($campaignId, $arrayImport);
        $missingSuppliers = $import['missingSuppliers'];
        $alreadyRegisteredSuppliers = $import['alreadyRegisteredSuppliers'] ?? [];
        $totalImportedSuppliers = $import['count'];

        // import par lot de 500 fournisseurs (append dans un fichier pour les logs)
        // faire un helper pour l'insert table temp
        // gérer l'entity dans le helper

        return new Response(443, [], (string) \json_encode([
            'statut' => 'O',
            'path' => $this->router->generateUri('Evaluation.Campaign.supplierImportSummary', ['id' => $campaignId]),
            'postGestion' => [
                'missingSuppliers' => $missingSuppliers,
                'alreadyRegisteredSuppliers' => $alreadyRegisteredSuppliers,
                'totalImportedSuppliers' => $totalImportedSuppliers,
            ],
        ]));
    }

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

        $trad = $this->getTranslationService();

        $campaignId = $this->request->getAttribute('id');
        $campaign = $this->campaignService
            ->campaignDetail(
                $campaignId,
                $this->router,
                $this->droits
            );


        $alreadyRegisteredSuppliers = $post['alreadyRegisteredSuppliers'] ?? [];
        $missingSuppliers = $post['missingSuppliers'] ?? [];
        $totalImportedSuppliers = $post['totalImportedSuppliers'];

        if ($totalImportedSuppliers > 0) {
            $message = Trad::strBuild($trad->t('Nombre de fournisseurs importés depuis le fichier : @1@'), $totalImportedSuppliers);
        } else {
            $message = $trad->t('Aucun fournisseur n\'a été importé.');
        }

        ArianeSub::generate(1, 0, $trad->t('Récapitulatif import'), $this->router->generateUri('Evaluation.Campaign.supplierImportSummary', ['id' => $campaignId]), 1);

        return $this->renderer->render('@Evaluation/Campaign/detail', [
            'menuActive' => $_SESSION['typeMenu'] == 'S2C' ? 'Consultations' : 'Evaluations',
            'menuLeft' => 'ratings',
            'tab' => 'Suppliers/summary',
            'missingSuppliers' => $missingSuppliers,
            'alreadyRegisteredSuppliers' => $alreadyRegisteredSuppliers,
            'message' => $message,
            'id' => $campaignId,
            'campaign' => $campaign,
            'droits' => $this->droits,
        ]);
    }

    /**
     * supplierRemoveAction
     * retire un fournisseur des tables des fournisseurs d'une campagne et des noteurs par fournisseur d'une campagne
     *
     * @return Response
     */
    public function supplierRemoveAction()
    {
        $campaignId = $this->request->getAttribute('id');
        $supplier = $this->request->getAttribute('supplier');
        $campLstFour = new CampLstFour($this->pdo);
        $campLstNotFour = new CampLstNotFour($this->pdo);

        $campLstFour->delete([
            'ID_CAMP' => $campaignId,
            'CODE_FOU' => $supplier,
        ]);

        $campLstNotFour->delete([
            'ID_CAMP' => $campaignId,
            'CODE_FOU' => $supplier,
        ]);

        return new Response(200, [], (string) \json_encode([]));
    }

    /**
     * validationAction
     *
     * @return Response|string
     */
    public function validationAction()
    {
        $post = $this->request->getParsedBody();
        $id = $this->request->getAttribute('id');
        $confirm = $this->request->getAttribute('confirm');

        $validator = new CampaignValidator($this->pdo, $this->getTranslationService());
        $contexteDetail = false;
        if (!isset($post['page']) || $post['page'] == '') {
            $contexteDetail = true;
        }
        $post['post']['page'] = $post['page'] ?? '';
        $post['post']['contexteDetail'] = $contexteDetail;
        $post['post'] = json_encode($post['post']);

        $trad = $this->getTranslationService();

        if ($validator->validationCheck($id)) {
            if ($confirm) {
                $erreurReturn = $this->campaignService->validationCampaign($id, $confirm == 1 ? true : false);
                $statut = $confirm == 2 ? 1 : $erreurReturn['errorValidation'];
                switch ($statut) {
                    case 1:
                        if ($confirm == 2) {
                            $this->campaignService->sendMailToRaters($id, $this->contenaire, $this->router, [], $this->JWTKEY);
    
                            return new Response(200, ['Content-Type' => 'application/json'], json_encode([
                                'statut' => 'E',
                                'path' => $this->router->generateUri('Evaluation.Campaign.index'),
                                'pathOnlyRedirect' => true
                                // 'responseText' => $this->renderer->render('@popup-erreur/ErreurCreation', ['ErreurValid' =>  Trad::strBuild($trad->t('La campagne @1@ a bien été validée.'), $id)]),
                            ]));
                        }
    
                        $missingRaters = $this->campaignService->sendMailToRaters($id, $this->contenaire, $this->router, [], $this->JWTKEY);
    
                        $alert = Trad::strBuild($trad->t('La campagne @1@ a bien été validée.'), $id);
    
                        if (\count($missingRaters) > 0) {
                            $alert .= '<br> ' . $trad->t('N\'ayant pas d\'adresse email, certains évaluateurs n\'ont pas été prévenus') . ' : ' . ' </br>';
                            foreach ($missingRaters as $rater) {
                                $alert .= (!Sql::toBool($rater['ORIGIN'])
                                    ? $rater['RS']
                                    : ($rater['NOM'] == ''
                                        ? $trad->t('Nom manquant')
                                        : $rater['NOM'])) . ' (' . $rater['COD_NOTEUR'] . ') ';
                            }
                        }
    
                        return new Response(200, [], $this->renderer->render('@Evaluation/Popup/erreurAlerteEtAvertissement', [
                            'params' => [
                                'alerte' => $alert,
                                'titrePopup' => Trad::strBuild($trad->t('validation de la campagne @1@'), $id),
                                'typePopup' => 'ok'
                            ],
                            'page' => $post['page'],
                            'post' => $post['post'],
                            'id' => $id,
                            'statut' => 'O',
                            'contexteDetail' => $contexteDetail
                        ]));
                    case 0:
                        switch ($erreurReturn['erreurCode']) {
                            case '1':
                                return new Response(200, [], json_encode([
                                    'statut' => 'E',
                                    'responseText' => $this->renderer->render('@popup-erreur/ErreurCreation', ['ErreurValid' => Trad::strBuild($trad->t('Le statut de la campagne @1@ est incorrect.'), $id)]),
                                ]));
                            case '5':
                                $error = $this->gestionErrorValidationCampaign($erreurReturn['result'], $trad->t('Le thème @1@ pour le fournisseur @2@ n\'a pas de question.'), $erreurReturn['erreurCode']);
    
                                return new Response(200, [], $this->renderer->render('@Evaluation/Popup/erreurAlerteEtAvertissement', [
                                    'params' => [
                                        'alerte' => $error['erreurBloquant'],
                                        'titrePopup' => $trad->t('Erreur'),
                                        'avertissement' => $error['erreurNonBloquant'],
                                    ],
                                    'pathURL' => $this->router->generateUri('Evaluation.Campaign.validation', ['id' => $id, 'confirm' => 2]),
                                    'statut' => $error['statutErrorGlobal'],
                                    'div' => 'liste-campagnes',
                                    'form' => 'filtre_campagne',
                                    'page' => $post['page'],
                                    'post' => $post['post'],
                                    'id' => $id
                                ]));
                            case '6':
                                $error = $this->gestionErrorValidationCampaign($erreurReturn['result'], $trad->t('La question "@1@" dans le thème @2@ n\'a pas d\'association.'), $erreurReturn['erreurCode']);
    
                                return new Response(200, [], $this->renderer->render('@Evaluation/Popup/erreurAlerteEtAvertissement', [
                                    'params' => [
                                        'alerte' => $error['erreurBloquant'],
                                        'titrePopup' => $trad->t('Erreur'),
                                        'avertissement' => $error['erreurNonBloquant'],
                                    ],
                                    'pathURL' => $this->router->generateUri('Evaluation.Campaign.validation', ['id' => $id, 'confirm' => 2]),
                                    'statut' => $error['statutErrorGlobal'],
                                    'div' => 'liste-campagnes',
                                    'form' => 'filtre_campagne',
                                    'page' => $post['page'],
                                    'post' => $post['post'],
                                    'id' => $id
                                ]));
    
                            case '7':
                                $error = $this->campaignService->gestionErrorValidationCampaign($erreurReturn['result'], $trad->t('La question "@1@" dans le thème @2@ pour le fournisseur @3@ n\'a pas d\'évaluateur.'), $erreurReturn['erreurCode']);
                                return new Response(200, [], $this->renderer->render('@Evaluation/Popup/erreurAlerteEtAvertissement', [
                                    'params' => [
                                        'alerte' => $error['erreurBloquant'],
                                        'titrePopup' => $trad->t('Erreur'),
                                        'avertissement' => $error['erreurNonBloquant'],
                                    ],
                                    'pathURL' => $this->router->generateUri('Evaluation.Campaign.validation', ['id' => $id, 'confirm' => 2]),
                                    'statut' => $error['statutErrorGlobal'],
                                    'div' => 'liste-campagnes',
                                    'form' => 'filtre_campagne',
                                    'page' => $post['page'],
                                    'post' => $post['post'],
                                    'id' => $id
                                ]));
    
                            case '8':
                                $error = $this->campaignService->gestionErrorValidationCampaign($erreurReturn['result'], $trad->t('La tableau de réponses de la question "@1@" dans le thème @2@ n\'est pas renseigné.'), $erreurReturn['erreurCode']);
                                return new Response(200, [], $this->renderer->render('@Evaluation/Popup/erreurAlerteEtAvertissement', [
                                    'params' => [
                                        'alerte' => $error['erreurBloquant'],
                                        'titrePopup' => $trad->t('Erreur'),
                                        'avertissement' => $error['erreurNonBloquant'],
                                    ],
                                    'pathURL' => $this->router->generateUri('Evaluation.Campaign.validation', ['id' => $id, 'confirm' => 2]),
                                    'statut' => $error['statutErrorGlobal'],
                                    'div' => 'liste-campagnes',
                                    'form' => 'filtre_campagne',
                                    'page' => $post['page'],
                                    'post' => $post['post'],
                                    'id' => $id
                                ]));
                            default:
                                $errorBloquante = '';
    
                                $res = explode('|', $erreurReturn['erreurCode']);
                                foreach ($res as $r) {
                                    switch ($r) {
                                        case '2':
                                            $errorBloquante .= Trad::strBuild($trad->t('La société n\'est pas renseignée dans la campagne @1@.'), $id) . "<br/>";
                                            break;
                                        case '3':
                                            $errorBloquante .= Trad::strBuild($trad->t('Les fournisseurs ne sont pas renseignés dans la campagne @1@.'), $id) . "<br/>";
                                            break;
                                        case '4':
                                            $errorBloquante .= Trad::strBuild($trad->t('Les questions ne sont pas renseignées dans la campagne @1@.'), $id) . "<br/>";
                                            break;
                                    }
                                }
                                return new Response(200, [], $this->renderer->render('@Evaluation/Popup/erreurAlerteEtAvertissement', [
                                    'params' => [
                                        'alerte' => $errorBloquante,
                                        'titrePopup' => $trad->t('Erreur'),
                                        'avertissement' => '',
                                    ],
                                    'pathURL' => '',
                                    'statut' => 'B',
                                    'div' => 'liste-campagnes',
                                    'form' => 'filtre_campagne',
                                    'page' => $post['page'],
                                    'post' => $post['post'],
                                    'id' => $id
                                ]));
                        }
                }
            }
    
            return $this->renderer->render('@Evaluation/Popup/PopupConfirmValidation', [
                'message' => Trad::strBuild($trad->t('Êtes-vous sûr(e) de vouloir valider la campagne @1@ ?'), $id),
                'demandeDeConfirmation' => $confirm ? false : true,
                'form' => 'filtre_campagne',
                'page' => $post['page'] ?? '',
                'post' => $post['post'],
                'contexteDetail' => $contexteDetail,
                'id' => $id
            ]);
        } else {
            return new Response(200, [], $this->renderer->render('@Evaluation/Popup/erreurAlerteEtAvertissement', [
                'params' => [
                    'alerte' => $validator->getError(),
                    'titrePopup' => $trad->t('Erreur'),
                ],
                'statut' => 'E',
                'div' => 'liste-campagnes',
                'form' => 'filtre_campagne',
                'page' => $post['page'],
                'post' => $post['post'],
                'id' => $id
            ]));
        }
    }

    /**
     * devalidationAction
     * permet de dévalider une campagne, si les conditions sont réunies
     *
     * @return Response
     */
    public function devalidationAction()
    {
        $id = $this->request->getAttribute('id');
        $post = $this->request->getParsedBody();

        $erreurReturn = $this->campaignService->devaliderCampagne($id);

        $trad = $this->getTranslationService();

        switch ($erreurReturn['errorValidation']) {
            case '0':
                return new Response(443, [], $this->renderer->render('@popup-erreur/erreurAlerteEtAvertissement', [
                    'params' => [
                        'alerte' => $trad->t('Le statut de la campagne est incorrect.'),
                    ],
                    'statut' => 'B',
                ]));
            case '1':
                return new Response(443, [], $this->renderer->render('@popup-erreur/erreurAlerteEtAvertissement', [
                    'params' => [
                        'alerte' => $trad->t('Attention il y a des réponses fournisseur terminées.'),
                    ],
                    'statut' => 'B',
                ]));
            case '2':
                if (isset($post['post']['contexteDetail']) && $post['post']['contexteDetail'] == "true") {
                    $path = $this->router->generateUri('Evaluation.Campaign.detail', ['id' => $id]);
                } else {
                    $path = $this->router->generateUri('Evaluation.Campaign.index');
                }

                return new Response(200, [], (string) \json_encode([
                    'path' => $path
                ]));
        }

        return new Response();
    }

    public function popupConfirmationDevalidationAction(): string
    {

        $post = $this->request->getParsedBody();
        $contexteDetail = false;
        if (!isset($post['page']) || $post['page'] == '') {
            $contexteDetail = true;
        }

        $post['post']['contexteDetail'] = $contexteDetail;

        $path = $post['Path'];
        $message = $post['Message'];
        $entity = $post['Entity'];
        $div = $post['div'];
        $form = $post['form'] ?? '';
        return $this->renderer->render('@Evaluation/Popup/PopupConfirmDevalidation', [
            'message' => $message,
            'pathURL' => $path,
            'entity' => $entity,
            'div' => $div,
            'form' => $form,
            'post' => json_encode($post['post'])
        ]);
    }

    public function resultatCampagneAction(): string
    {
        $id_campagne = $this->request->getAttribute('id');
        $post = $this->request->getParsedBody();

        $trad = $this->getTranslationService();

        Ariane::generate(1, $trad->t('Résultats campagne'));

        $campagne = (new CampEnt($this->pdo))->find($id_campagne);

        $listeTmp = (new CampLstFour($this->pdo))->findAll(['ID_CAMP' => $id_campagne]);

        $noteGlobal = (new CampNotFin($this->pdo))->find(['ID_CAMP' => $id_campagne, 'ID_THEME' => '', 'CODE_FOU' => ($post['choixFrs'] ?? '')]);

        $listeTheme = $this->repository->getResultatCampaign($id_campagne, ($post['choixFrs'] ?? ''));

        $listeFrs[''] = $trad->t('Cumulé');
        foreach ($listeTmp as $frs) {
            $listeFrs[$frs['CODE_FOU']] = OutilOutils::convertLibelleGlobal($this->pdo, 'FOURNISS', '', $frs['CODE_FOU'], true);
        }

        return $this->renderer->render('@Evaluation/Campaign/Resultat', [
            'menuActive' => $_SESSION['typeMenu'] == 'S2C' ? 'Consultations' : 'Evaluations',
            'menuLeft' => 'ratings',
            'post' => $post,
            'listeFrs' => $listeFrs,
            'idCamp' => $id_campagne,
            'campagne' => $campagne,
            'noteGlobal' => $noteGlobal,
            'listeTheme' => $listeTheme,
        ]);
    }

    /**
     * clotureAction
     *
     * @return string|Response
     */
    public function clotureAction()
    {
        $id = $this->request->getAttribute('id');
        $confirm = $this->request->getAttribute('confirm');
        $post = $this->request->getParsedBody();

        if (!empty($post)) {
            $post['post']['page'] = $post['page'] ?? '';
            $post['post'] = json_encode($post['post']);
        }

        $trad = $this->getTranslationService();


        if ($confirm) {
            $erreurReturn = $this->campaignService->closeCampaign($id, $confirm == 2 ? true : false);
            $statut = $confirm == 2 ? 0 : $erreurReturn[0]['STATUT'];

            switch ($statut) {
                case '0':
                    if ($confirm == 2) {
                        return new Response(200, [], $this->renderer->render('@Evaluation/Popup/erreurAlerteEtAvertissement', [
                            'params' => [
                                'alerte' => Trad::strBuild($trad->t('La campagne @1@ a bien été cloturée.'), $id),
                                'path' => $this->router->generateUri('Evaluation.Campaign.index'),
                                'typePopup' => 'ok'
                            ],
                            'statut' => 'O',
                            'page' => $post['page'],
                            'post' => $post['post']
                        ]));
                    }
                    return new Response(200, [], $this->renderer->render('@Evaluation/Popup/erreurAlerteEtAvertissement', [
                        'params' => [
                            'alerte' => Trad::strBuild($trad->t('La campagne @1@ a bien été cloturée.'), $id),
                            'path' => $this->router->generateUri('Evaluation.Campaign.index'),
                            'typePopup' => 'ok'
                        ],
                        'statut' => 'O',
                        'page' => $post['page'],
                        'post' => $post['post']
                    ]));

                case '1':
                    return new Response(200, [], $this->renderer->render('@Evaluation/Popup/erreurAlerteEtAvertissement', [
                        'params' => [
                            'alerte' => Trad::strBuild($trad->t('Le statut de la campagne @1@ est incorrect.'), $id),
                        ],
                        'page' => $post['page'],
                        'post' => $post['post']
                    ]));
                case '2':
                    $erreurNonBloquant = '';
                    $erreurBloquant = '';
                    $statutErrorGlobal = '';

                    $listeBloquantFournisseur = [];
                    $listeBloquantExterne = [];
                    $listeBloquantInterne = [];

                    $listeNonBloquantFournisseur = [];
                    $listeNonBloquantExterne = [];
                    $listeNonBloquantInterne = [];

                    $erreursBloquantFournisseur = false;
                    $erreursBloquantExterne = false;
                    $erreursBloquantInterne = false;

                    $erreursNonBloquantFournisseur = false;
                    $erreursNonBloquantExterne = false;
                    $erreursNonBloquantInterne = false;

                    // on prépare plusieurs listes d'erreurs possibles
                    $erreurListeFournisseurs = $trad->t('Plusieurs fournisseurs n\'ont pas terminé leur évaluation : <br/>');
                    $erreurListeExterne = $trad->t('Plusieurs évaluateurs externes n\'ont pas terminé leur évaluation : <br/>');
                    $erreurListeInterne = $trad->t('Plusieurs évaluateurs internes n\'ont pas terminé leur évaluation : <br/>');

                    foreach ($erreurReturn as $erreur) {
                        if ($erreur['BLOQUANT'] == 'O') {
                            $statutErrorGlobal = 'B';
                            if ($erreur['NOT_FOUR'] == 'O') {
                                if (!isset($listeBloquantFournisseur[$erreur['RS']])) {
                                    $listeBloquantFournisseur[$erreur['RS']] = $erreur['CODE_FOU'];
                                }
                                $erreursBloquantFournisseur = true;
                            } elseif ($erreur['NOTEUR_EXTERNE'] == 'O') {
                                if (!isset($listeBloquantExterne[$erreur['COD_NOTEUR']])) {
                                    $listeBloquantExterne[$erreur['COD_NOTEUR']] = $erreur['COD_NOTEUR'];
                                }
                                $erreursBloquantExterne = true;
                            } else {
                                if (!isset($listeBloquantInterne[$erreur['COD_NOTEUR']])) {
                                    $listeBloquantInterne[$erreur['COD_NOTEUR']] = $erreur['COD_NOTEUR'];
                                }
                                $erreursBloquantInterne = true;
                            }
                        } else {
                            if ($erreur['NOT_FOUR'] == 'O') {
                                if (!isset($listeNonBloquantFournisseur[$erreur['RS']])) {
                                    $listeNonBloquantFournisseur[$erreur['RS']] = $erreur['CODE_FOU'];
                                }
                                $erreursNonBloquantFournisseur = true;
                            } elseif ($erreur['NOTEUR_EXTERNE'] == 'O') {
                                if (!isset($listeNonBloquantExterne[$erreur['COD_NOTEUR']])) {
                                    $listeNonBloquantExterne[$erreur['COD_NOTEUR']] = $erreur['COD_NOTEUR'];
                                }
                                $erreursNonBloquantExterne = true;
                            } else {
                                if (!isset($listeNonBloquantInterne[$erreur['COD_NOTEUR']])) {
                                    $listeNonBloquantInterne[$erreur['COD_NOTEUR']] = $erreur['COD_NOTEUR'];
                                }
                                $erreursNonBloquantInterne = true;
                            }
                        }
                    }

                    if ($erreursNonBloquantExterne) {
                        $this->campaignService->getExternalRatersNames($listeNonBloquantExterne);
                    }

                    if ($erreursBloquantFournisseur) {
                        foreach ($listeBloquantFournisseur as $k => $fou) {
                            $erreurListeFournisseurs .= ' - ' . $fou . ' (' . $k . ')<br/>';
                        }
                        $erreurBloquant .= $erreurListeFournisseurs;
                    }

                    if ($erreursBloquantExterne) {
                        foreach ($listeBloquantExterne as $v) {
                            $erreurListeExterne .= ' - ' . $v . '<br/>';
                        }
                        $erreurBloquant .= $erreurListeExterne;
                    }

                    if ($erreursBloquantInterne) {
                        foreach ($listeBloquantInterne as $v) {
                            $erreurListeInterne .= ' - ' . $v . '<br/>';
                        }
                        $erreurBloquant .= $erreurListeInterne;
                    }

                    if ($erreursNonBloquantFournisseur) {
                        foreach ($listeNonBloquantFournisseur as $k => $fou) {
                            $erreurListeFournisseurs .= ' - ' . $fou . ' (' . $k . ')<br/>';
                        }
                        $erreurNonBloquant .= $erreurListeFournisseurs;
                    }

                    if ($erreursNonBloquantInterne) {
                        foreach ($listeNonBloquantInterne as $v) {
                            $erreurListeInterne .= ' - ' . $v . '<br/>';
                        }
                        $erreurNonBloquant .= $erreurListeInterne;
                    }

                    if ($erreursNonBloquantExterne) {
                        foreach ($listeNonBloquantExterne as $v) {
                            $erreurListeExterne .= ' - ' . $v . '<br/>';
                        }
                        $erreurNonBloquant .= $erreurListeExterne;
                    }

                    if ($erreurBloquant != '') {
                        $pathUrl = '';
                    } else {
                        $pathUrl = $this->router->generateUri('Evaluation.Campaign.cloture', ['id' => $id, 'confirm' => 2]);
                    }


                    

                    return new Response(200, [], $this->renderer->render('@Evaluation/Popup/erreurAlerteEtAvertissement', [
                        'params' => [
                            'alerte' => $erreurBloquant,
                            'avertissement' => $erreurNonBloquant,
                            'titrePopup' => Trad::strBuild($trad->t('Clôture de la campagne n°@1@'), $id),
                        ],
                        'messageInformatif' => $trad->t('Pour accéder au détail des fournisseurs par évaluateur, cliquez').'
                            <a href="'.$this->router->generateUri('Evaluation.Campaign.etatAvancement', ['id' => $id]).'">'.$trad->t('ici').'</a>',
                        'pathURL' => $pathUrl,
                        'statut' => $statutErrorGlobal,
                        'div' => 'page',
                        'page' => $post['page'],
                        'post' => $post['post']
                    ]));
            }
        }

        return $this->renderer->render('@Evaluation/Popup/PopupConfirmClose', [
            'message' => Trad::strBuild($trad->t('Voulez-vous clôturer la campagne @1@ ?'), $id),
            'demandeDeConfirmation' => $confirm ? false : true,
            'id' => $id,
            'div' => 'liste-campagnes',
            'page' => $post['page'] ?? '',
            'post' => $post['post'] ?? [],
        ]);
    }

    /**
     * resumeRatersAction
     *
     * @return Response
     */
    public function resumeRatersAction(): Response
    {
        $campaignId = $this->request->getAttribute('id');

        $trad = $this->getTranslationService();

        $missingRaters = $this->campaignService->sendMailToRaters($campaignId, $this->contenaire, $this->router, [], $this->JWTKEY, true);

        $info = $trad->t('Les évaluateurs de la campagne ont été relancés par email.');
        $alert = '';

        if (\count($missingRaters) > 0) {
            $alert .= '<br> ' . $trad->t('N\'ayant pas d\'adresse email, certains évaluateurs n\'ont pas été prévenus') . ' : ' . ' </br>';
            foreach ($missingRaters as $rater) {
                $alert .= (!Sql::toBool($rater['ORIGIN'])
                    ? $rater['RS']
                    : ($rater['NOM'] == ''
                        ? $trad->t('Nom manquant')
                        : $rater['NOM'])) . ' (' . $rater['COD_NOTEUR'] . ') ';
            }
        }

        return new Response(200, [], $this->renderer->render('@Evaluation/Popup/erreurAlerteEtAvertissement', [
            'params' => [
                'info' => $info,
                'avertissement' => $alert,
                'titrePopup' => $trad->t('Relance évaluateurs'),
                'typePopup' => $alert == '' ? 'ok' : ''
            ],
            'statut' => $alert == '' ? 'O' : '',
        ]));
    }

    //_____________________________________________________________________________
    // Sub-routine

    /**
     * gestionErrorValidationCampaign
     *
     * @param  mixed $erreurReturn
     * @param  mixed $traduction
     * @param  mixed $erreurCode
     * @return array<mixed>
     */
    public function gestionErrorValidationCampaign($erreurReturn, $traduction, $erreurCode)
    {
        $erreurNonBloquant = '';
        $erreurBloquant = '';
        $statutErrorGlobal = '';
        $trad = $this->getTranslationService();

        foreach ($erreurReturn as $erreur) {
            if (($erreur['BLOQUANT'] ?? '') == 'N') {
                $statutErrorGlobal = 'B';
                switch ($erreurCode) {
                    case '5':
                        $erreurNonBloquant .= Trad::strBuild($traduction, $erreur['theme'] ?? $erreur['LIB_THEME'], $erreur['fournisseur'] ?? '') . '<br/>';
                        break;
                    case '6':
                        $erreurNonBloquant .= Trad::strBuild($traduction, $erreur['question'] ?? $erreur['LIB_QUEST'], $erreur['theme'] ?? $erreur['LIB_THEME']) . '<br/>';
                        break;
                    case '7':
                        $erreurNonBloquant .= Trad::strBuild($traduction, $erreur['question'] ?? $erreur['LIB_QUEST'], $erreur['theme'] ?? $erreur['LIB_THEME'], $erreur['fournisseur'] ?? '') . '<br/>';
                        break;
                    case '8':
                        $erreurNonBloquant .= Trad::strBuild($traduction, $erreur['question'] ?? $erreur['LIB_QUEST'], $erreur['theme'] ?? $erreur['LIB_THEME']) . '<br/>';
                        break;
                }
            } else {
                switch ($erreurCode) {
                    case '5':
                        $erreurNonBloquant .= Trad::strBuild($traduction, $erreur['theme'] ?? $erreur['LIB_THEME'], $erreur['fournisseur'] ?? '') . '<br/>';
                        break;
                    case '6':
                        $erreurNonBloquant .= Trad::strBuild($traduction, $erreur['question'] ?? $erreur['LIB_QUEST'], $erreur['theme'] ?? $erreur['LIB_THEME']) . '<br/>';
                        break;
                    case '7':
                        if ($erreur['TYPE'] == 'C') {
                            $erreurNonBloquant .= Trad::strBuild(
                                $trad->t('La question "@1@" dans le thème @2@ pour le fournisseur @3@ ne renvoie aucun résultat.'),
                                $erreur['question'] ?? $erreur['LIB_QUEST'],
                                $erreur['theme'] ?? $erreur['LIB_THEME'],
                                $erreur['fournisseur'] ?? ''
                            ) . '<br/>';
                        } else {
                            $erreurNonBloquant .= Trad::strBuild($traduction, $erreur['question'] ?? $erreur['LIB_QUEST'], $erreur['theme'] ?? $erreur['LIB_THEME'], $erreur['fournisseur'] ?? '') . '<br/>';
                        }
                        break;
                    case '8':
                        $erreurNonBloquant .= Trad::strBuild($traduction, $erreur['question'] ?? $erreur['LIB_QUEST'], $erreur['theme'] ?? $erreur['LIB_THEME']) . '<br/>';
                        break;
                }
                $statutErrorGlobal = 'B';
            }
        }

        return [
            'erreurNonBloquant' => $erreurNonBloquant,
            'erreurBloquant' => $erreurBloquant,
            'statutErrorGlobal' => $statutErrorGlobal,
        ];
    }

    /**
     * _getCategories
     *
     * @return array<mixed>
     */
    private function _getCategories(): array
    {
        $categoryListTemp = (new Category($this->pdo, $this->pdoStorage))->categoryList();
        $categoryList = [
            '' => $this->getTranslationService()->t('Aucune')

        ];
        foreach ($categoryListTemp as $category) {
            $categoryList[$category['ID_GRILLE']] = $category['LIB_GRILLE'];
        }

        return $categoryList;
    }

    /**
     * _getPeriodes
     *
     * @return array<mixed>
     */
    private function _getPeriodes(): array
    {
        $periodes = (new Periodes($this->pdo))->fetchAll();

        $listePeriodes = [
            '' => $this->getTranslationService()->t('Sélectionnez une période.')
        ];

        foreach ($periodes as $per) {
            $listePeriodes[$per['CODE_PER']] = $per['LIBELLE'];
        }

        return $listePeriodes;
    }
}
