<?php

namespace Modules\Consultation\Controller;

use Entity\Model\Paramnum;
use Helpers\Additional\Specifique\Specifique;
use Modules\ProjetAchat\Repository\Modele;
use Skeleton\Controller\Controller;
use Helpers\Trad\Trad;
use Helpers\Ariane\Ariane;
use Entity\Model\Langues;
use Helpers\Outil\Sql;
use Helpers\Validator\Validator;
use GuzzleHttp\Psr7\Response;
use Helpers\ChampsSupplementaire\ChampSupp;
use Entity\Model\AoEntet;
use Modules\GlobalApplication\WebService\DocRattaches;
use Helpers\Outil\Date;
use Entity\Model\Docatt;
use Modules\Consultation\Repository\AoEvent;
use Modules\Consultation\Repository\GestionConsultation;
use Helpers\Ariane\ArianeSub;
use Modules\GlobalApplication\Repository\DocumentsRattaches;
use Modules\Consultation\Service\ConsultationService;
use Helpers\Outil\Roles;
use Entity\Model\AoDocAttendus;
use Modules\Consultation\Repository\Consultation;
use Modules\Consultation\Repository\Reponse;
use Entity\Model\AoRep;
use Entity\Model\AoRepPijo;
use Entity\Model\AoRepQst;
use Entity\Model\AoRepSl;
use Entity\Model\AoRetParLigne;
use Modules\ProjetAchat\Repository\Action;
use Modules\ProjetAchat\Service\ActionService;
use Entity\Model\DoarEtatAv;
use Entity\Model\DoarType;
use Entity\Model\DoarOpe;
use Modules\ProjetAchat\Service\ModeleService;
use Modules\ProjetAchat\Service\ModeleProjetService;
use Entity\Model\AoQstTh;
use Entity\Model\NoReserv;
use Modules\GlobalApplication\Repository\BddObjects;
use Entity\Model\AoFour;
use Helpers\Fichier\Fichier;
use Helpers\Pagination\PaginatorGestion;
use Helpers\Securite\Securite;
use Modules\Ajax\Repository\Listes;
use Modules\Consultation\MenuContextuel\GestionMenuContextuel;
use Helpers\Parametres\Constante;
use Modules\Consultation\MenuContextuel\FournisseurMenuContextuel;

class ConsultationController extends Controller
{
    private \Helpers\Pagination\PaginatorGestion $paginator;

    /**
     * init
     *
     * @return void
     */
    public function init(): void
    {
        $this->paginator = new PaginatorGestion();
    }

    public function detailsAction() : string
    {
        $idAO = $this->request->getAttribute('idAO');
        $onglet = $this->request->getAttribute('onglet');
        $post = $this->request->getParsedBody();

        $trad = $this->getTranslationService();

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

        $gestionConsu = new GestionConsultation($this->pdo);
        $consultation = $gestionConsu->getInfoAo($idAO);
        if (empty($consultation)) {
            throw new \Exception('Invalid AO #'.$idAO);
        }

        ArianeSub::init();
        /** @phpstan-ignore-next-line */
        ArianeSub::generate(0, 0, $trad->t('Fournisseurs'), $this->router->generateUri('Consultation.Consultation.details', ['idAO' => $idAO, 'onglet' => 'Fournisseur']), ($onglet=='Fournisseur' || $onglet=='')? 1:0, [], 'ongletFrs');
        /** @phpstan-ignore-next-line */
        ArianeSub::generate(0, 1, $trad->t('Postes'), $this->router->generateUri('Consultation.Consultation.details', ['idAO' => $idAO, 'onglet' => 'Ligne']), ($onglet=='Ligne'? 1:0), [], 'ongletLigne', sql::boolSql($consultation['COMP_LIGNE'])? '':'style="display:none"');
        /** @phpstan-ignore-next-line */
        ArianeSub::generate(0, 2, $trad->t('Pièces jointes'), $this->router->generateUri('Consultation.Consultation.details', ['idAO' => $idAO, 'onglet' => 'PJ']), ($onglet=='PJ'? 1:0), [], 'ongletPJ', sql::boolSql($consultation['COMP_PJ'])? '':'style="display:none"');
        /** @phpstan-ignore-next-line */
        ArianeSub::generate(0, 3, $trad->t('Clauses'), $this->router->generateUri('Consultation.Consultation.details', ['idAO' => $idAO, 'onglet' => 'Clause']), ($onglet=='Clause'? 1:0), [], 'ongletClause', sql::boolSql($consultation['COMP_CLAUSE'])? '':'style="display:none"');
        /** @phpstan-ignore-next-line */
        ArianeSub::generate(0, 4, $trad->t('Questionnaire'), $this->router->generateUri('Evaluation.BibliothequeDeQuestions.gestionBibliotheque', ['mode' => 'AO', 'idCamp' => $idAO]), 0, [], 'ongletQst', sql::boolSql($consultation['COMP_QUEST'])? '':'style="display:none"');
        /** @phpstan-ignore-next-line */
        ArianeSub::generate(0, 5, $trad->t('Documents attendus'), $this->router->generateUri('Consultation.Consultation.details', ['idAO' => $idAO, 'onglet' => 'DocAtt']), ($onglet=='DocAtt'? 1:0), [], 'ongletDocAtt', sql::boolSql($consultation['COMP_DOC_ATT'])? '':'style="display:none"');
        /** @phpstan-ignore-next-line */
        ArianeSub::generate(0, 6, $trad->t('Documents internes'), $this->router->generateUri('Consultation.Consultation.details', ['idAO' => $idAO, 'onglet' => 'DocInt']), ($onglet=='DocInt'? 1:0), [], 'ongletDocInt', sql::boolSql($consultation['COMP_DOC_INT'])? '':'style="display:none"');

        $actionRepo = new Action($this->pdo);
        $listeIdProjet = $actionRepo->checkLienExterneProjetExist($idAO, 'NO_AO');
        
        if ($listeIdProjet) {
            ArianeSub::generate(0, 7, $trad->t('Projet lié'), $this->router->generateUri('Consultation.Consultation.details', ['idAO' => $idAO, 'onglet' => 'projetLie']), ($onglet=='projetLie'? 1:0), [], 'ongletProjet');
        }
        
        $droit = [
            'HA_AO_ADM' => Roles::droitsUtilisateur($this->pdo, 'HA_AO_ADM', $_SESSION["Session_Login"]),
            'HA_AO_CMV' => Roles::droitsUtilisateur($this->pdo, 'HA_AO_CMV', $_SESSION["Session_Login"]),
            'HA_AO_TRA' => Roles::droitsUtilisateur($this->pdo, 'HA_AO_TRA', $_SESSION["Session_Login"]),
            'HA_AO_SUP' => Roles::droitsUtilisateur($this->pdo, 'HA_AO_SUP', $_SESSION["Session_Login"]),
            'HA_AO_SRF' => Roles::droitsUtilisateur($this->pdo, 'HA_AO_SRF', $_SESSION["Session_Login"]),
        ];
        $canEdit = ($droit['HA_AO_ADM'] || ($droit['HA_AO_CMV'] && $consultation['ACH'] == $_SESSION["Session_Login"])) && $consultation['DTE_VALID_AO'] == '00000000';

        $aoEvent = new AoEvent($this->pdo);
        $AOEventCreat = $aoEvent->getNameCreate($idAO);
        
        if ($onglet=='Fournisseur' || $onglet=='') {
            $this->paginator->generate(0, 'CODE_FOU');
            $listeFournisseur = $gestionConsu->getListeFourniss($idAO, $post);

            $infoPagination = $this->paginator->getInfoPagination();

            $reponseRepo = new Reponse($this->pdo);

            $menuContextuel = new FournisseurMenuContextuel($this->pdo, $this->router, $this->getTranslationService(), $droit);
            foreach ($listeFournisseur as &$frs) {
                //on récupere la liste des réponses fournisseur, si c'est un fournisseur oxalink avec au moins 1 contact valide, on n'affique que les réponses validé
                $reponseFrs = $reponseRepo->getLastReponseAo($frs['NO_AO'], $frs['CODE_FOU'], (Sql::boolSql($frs['GEREPORTAIL']) == true && $frs['ctcOxalinkActif'] != 0));
                
                if ($reponseFrs) {
                    $frs['listeReponse'] = $reponseFrs;
                    
                    $frs['EVE_REP'] = $reponseFrs[0]['EVE_REP']??'';
                    $frs['DTE_REP'] = $reponseFrs[0]['DTE_REP']??'';
                    $frs['C_V'] = $reponseFrs[0]['C_V']??'';
                }
                if (trim($frs['FIC_ACC_CONF_SIGNE'])) {
                    $path_info = pathinfo($frs['FIC_ACC_CONF_SIGNE']);
                    $frs['FILE_ACC_CONF'] = 'Consult_'.$idAO.'_'.$frs['CODE_FOU'].'.'. $path_info['extension'];
                }
                
                $frs['menuContextuel'] =  $menuContextuel->generate($idAO, $consultation, $frs, $canEdit);
            }

            $typeFournisseur = [
                'F' => $trad->t('Fournisseur'),
                'G' => $trad->t('Groupement'),
            ];

            $typeReponse= [
                'C' => $trad->t('Conforme'),
                'V' => $trad->t('Variante'),
            ];
        } elseif ($onglet=='Ligne') {
            $ligneConsultation = $gestionConsu->listeLigneConsultation($idAO);

            $aoQstTh = new AoQstTh($this->pdo);

            $poidsAPRIX = $aoQstTh->find(['NO_AO' => $idAO, 'ID_THEME' => 'APRIX'])['POIDS']??null;
        } elseif ($onglet=='PJ') {
            $listPJ = $gestionConsu->getListPJ($idAO);
        } elseif ($onglet=='DocAtt') {
            $AoDocAttendus = new AoDocAttendus($this->pdo);
            $listeDocAttendu = $AoDocAttendus->fetchAll([], ['filter_egal_NO_AO' => (int)$idAO, 'tri_NUM_ORDRE' => 'asc']);
        } elseif ($onglet=='DocInt' || $onglet=='docInt') {
            $onglet = 'DocInt';
            $post['NO_DA'] = 'AO_ENTET';
            $idDoc = str_pad($idAO, 9, '0', STR_PAD_LEFT);

            $docAtt = new DocumentsRattaches($this->pdo);
            $listeDocument= $docAtt->detail($idDoc, $post);
        } elseif ($onglet=='Clause') {
            $listClause = $gestionConsu->getListClause($idAO);
        } elseif ($onglet=='projetLie') {
            $DoarEtatAv = new DoarEtatAv($this->pdo);
            $listeTMP = $DoarEtatAv->fetchAll();

            foreach ($listeTMP as $item) {
                $ListeEtatAv[$item['ID']] = $item['LIB'];
            }

            $DoarType = new DoarType($this->pdo);
            $listeTMP = $DoarType->fetchAll();

            foreach ($listeTMP as $item) {
                $listeType[$item['ID']] = $item['LIB'];
            }

            $DoarOpe = new DoarOpe($this->pdo);
            $listeTMP = $DoarOpe->fetchAll();

            foreach ($listeTMP as $item) {
                $ListeOpe[$item['CODE_OPE']] = $item['LIB'];
            }

            $projetService = new ModeleProjetService($this->pdo);
            $listeStatus = $projetService->listeStatut($trad);
        }

        $listeProjet = (new Modele($this->pdo))->listLinkedProjet(
            array_column($listeIdProjet, 'ID_OBJET')
        );


        if (array_key_exists('DA_CreatModif', $_SESSION) && $_SESSION['DA_CreatModif'] ||Roles::GetALL()) {
            $P2PActive = 1;
        } else {
            $P2PActive =0;
        }

        $menuContextuel = new GestionMenuContextuel($this->pdo, $this->router, $trad, $droit);
        $menuContextuel = $menuContextuel->generate($consultation, false);

        $enCours = ($consultation['DTE_VALID_AO'] != '00000000');
        
        return $this->renderer->render('@Consultation/Consultation/details', [
            'idAO'                => $idAO,
            'pathBack'            => ariane::getBackPath(),
            'menuActive'          => $_SESSION['typeMenu'] == 'P2P'? 'eproc':'Consultations',
            'menuLeft'            => 'gestionAO',
            'consultation'        => $consultation,
            'AOEventCreat'        => $AOEventCreat,
            'login'               => $_SESSION["Session_Login"],

            'onglet'              => $onglet,
            'typeFournisseur'     => $typeFournisseur??[],
            'listeFournisseur'    => $listeFournisseur??[],
            'ligneConsultation'   => $ligneConsultation??[],
            'listeClause'         => $listClause??[],
            'listePJ'             => $listPJ??[],
            'listeDocAttendu'     => $listeDocAttendu??[],
            'listeDocument'       => $listeDocument??[],
            'canEdit'             => $canEdit,
            'canEditEnCours'      => ($droit['HA_AO_ADM'] || ($droit['HA_AO_CMV'] && $consultation['ACH'] == $_SESSION["Session_Login"])),
            'enCours'             => $enCours,
            'idForDoc'            => $idDoc??'',
            'typeReponse'         => $typeReponse??[],
            'ListeEtatAv'         => $ListeEtatAv??[],
            'listeType'           => $listeType??[],
            'ListeOpe'            => $ListeOpe??[],
            'listeProjet'         => $listeProjet,
            'listeStatut'         => $listeStatus??[],
            'poidsAPRIX'          => $poidsAPRIX??null,
            'droit'               => $droit,
            'P2PActive'           => $P2PActive,

            'infoPagination'      => $infoPagination ?? [],
            'menuContextuel'      => $menuContextuel,
            'container'           => $this->contenaire,
        ]);
    }

    public function creatEditAction() : string
    {
        $idAO = $this->request->getAttribute('idAO');
        $origine = $this->request->getAttribute('origine');
        $idOrigine = $this->request->getAttribute('idOrigine');
        $post = $this->request->getParsedBody();

        $consultation = [];

        $trad = $this->getTranslationService();

        $listeRepo = new Listes($this->pdo);
        $listeGrpSoc = $listeRepo->findGroupedCompanies();

        $paramCode = (new Paramnum($this->pdo))->getNodeNum('AO');

        $listeRFI_Q = [
            'I' => $trad->t('Information'),
            'Q' => $trad->t('Cotation'),
        ];

        if ($listeGrpSoc) {
            $liste_SG = [
                'S' => $trad->t('Société'),
                'G' => $trad->t('Groupe de société')
            ];
        } else {
            $liste_SG = [
                'S' => $trad->t('Société')
            ];
        }

        $listeTypeDelais = [
            'D' => $trad->t('Date'),
            'J' => $trad->t('Jour'),
            'T' => $trad->t('Texte'),
        ];


        $langueEntity = new Langues($this->pdo);
        $listeLangueTmp = $langueEntity->fetchAll();

        $listeLangue = [];
        foreach ($listeLangueTmp as $langue) {
            $listeLangue[$langue['COD_LNG']] = $langue['LIBELLE'];
        }

        // si on viens de créer l'accord de confidentialité, on récupère le formulaire
        if (isset($post['postAo'])) {
            $fileName = null;
            if (isset($post['arrayDoc'])) {
                $arrayDoc = serialize($post['arrayDoc']);
                $fileName = $post['arrayDoc']['file_name'];
            }
            parse_str($post['postAo'], $post);

            $consultation = $post;

            if ($post['TYPE_SG'] == 'S') {
                $consultation['CODE_STE'] = $consultation['S_CODE_STE'];
            } else {
                $consultation['CODE_STE'] = $consultation['G_CODE_STE'];
            }
            if ($fileName) {
                $consultation['fileName'] = $fileName;
            }
        // si on viens d'une duplication
        } elseif ($idAO != 'noId' || in_array($origine, ['AO_ENTET','AO_MODELE'])) {
            if ($idAO != 'noId') {
                $idFind = $idAO;
            } else {
                $idFind = $idOrigine;
            }

            $aoEntetEntity = new AoEntet($this->pdo);
            $consultation = $aoEntetEntity->find($idFind);

            $docAttEntity = new Docatt($this->pdo);
            $infoDoc = $docAttEntity->find([
                'NO_DA' => 'AO_ENTET',
                'COD_ENR' => str_pad($idFind, 9, '0', STR_PAD_LEFT),
                'NO_ORDRE' => $consultation['ACC_CONF_NODOC']
            ]);

            if (!empty($infoDoc)) {
                $consultation['fileName'] = $infoDoc['NOM_ORI']??'';
                $newPath = Fichier::copyFileFicPJ($infoDoc['NOM_FIC'], true);
                
                // TODO : simplify and improve security
                $arrayDoc = serialize([
                    "langue"        => $_SESSION['Session_Langue'],
                    "new_name"      => $newPath["new_name"],
                    "file_name"     => $consultation['fileName'],
                    "typeObjet"     => 'AO_ENTET',
                    "refObjet"      => '$refObjet',
                    "typePj"        => $infoDoc['TYPE_PJ'],
                    "titreDoc"      => $infoDoc['TITRE'],
                    "auteur"        => $infoDoc['AUTEUR'],
                    "centre"        => $infoDoc['CENTRE'],
                    "dateParu"      => $infoDoc['DT_PARUT'],
                    "dateVali"      => $infoDoc['DT_VALID'],
                    "PJCommande"    => sql::boolSql($infoDoc['PJ_CDE']),
                    "commentaire"   => Sql::getMemo($this->pdo, $infoDoc['NM_COMM']),
                ]);
            }

            
            
            $consultation['DEL_REP'] = Date::dateConverte($consultation['DEL_REP']);
            $consultation['TITRE'] = Sql::getMemo($this->pdo, $consultation['NM_TITRE']);
            $consultation['DESCR'] = Sql::getMemo($this->pdo, $consultation['NM_COMENT']);

            if ($consultation['RFI_Q'] == '') {
                $consultation['RFI_Q'] = 'Q';
            }

            if ($consultation['TYPE_SG'] == '') {
                $consultation['TYPE_SG'] = 'S';
            }

            if ($idAO == 'noId') {
                $consultation['NO_AO'] = '';
            }
        } else {
            $consultation['CODE_STE']   = $_SESSION['Session_SocUsrProfil'];
            $consultation['EMETTEUR']   = $_SESSION['Session_CodeCtrEmetteur'];
            $consultation['ACH']        = $_SESSION['Session_Login'];
            $consultation['DEVISE']     = $_SESSION['DEVISE_BASE'];
            $consultation['COD_LNG']    = $_SESSION['Session_Langue'];
            $consultation['RFI_Q'] = 'Q';
        }

        if ($origine=='DA') {
        }

        if ($idAO != 'noId') {
            $titre = Trad::strBuild($trad->t('Modification de la Consultation n°@1@'), $idAO);
            Ariane::generate(1, $trad->t('Modification Consultation'));
        } else {
            if ($origine=='AO_ENTET' || $origine == 'AO_MODELE') {
                $titre = Trad::strBuild($trad->t('Duplication de la consultation n°@1@'), $idOrigine);
                Ariane::generate(1, $trad->t('Dupliquer Consultation'));
            } else {
                $titre = $trad->t('Création d\'une Consultation');
                Ariane::generate(1, $trad->t('Création Consultation'));
            }
        }

        $documentInternesSpecifique = Specifique::specifique(
            '\\Html\\Consultation\\Duplication',
            'setDefaultValue'
        );

        if (is_string($documentInternesSpecifique)) {
            $consultation['COMP_DOC_INT'] = $documentInternesSpecifique;
        }


        return $this->renderer->render('@Consultation/Consultation/creatEdit', [
            'origine' => $origine,
            'idOrigine' => $idOrigine,
            'idAO' => $idAO,
            'pathBack' => ariane::getBackPath(),
            'titre' => $titre,
            'listeRFI_Q' => $listeRFI_Q,
            'listeLangue' => $listeLangue,
            'listeTypeDelais' => $listeTypeDelais,
            'Consultation' => $consultation,
            'paramCode' => $paramCode,
            'menuActive' => $_SESSION['typeMenu'] == 'P2P'? 'eproc':'Consultations',
            'menuLeft' => 'gestionAO',
            'arrayDoc' => $arrayDoc??'',
            'liste_SG' => $liste_SG,
        ]);
    }

    public function validationAction()
    {
        $idAO = $this->request->getAttribute('idAO');
        $origine = $this->request->getAttribute('origine');
        $idOrigine = $this->request->getAttribute('idOrigine');
        $post = $this->request->getParsedBody();

        $aoEntetEntity = new AoEntet($this->pdo);

        $trad = $this->getTranslationService();

        $validator = $this->createValidator();

        $validator->isCheck($post['AO_PUBLIC']);

        $validator->isStringAvecEspace($trad->t('Objet'), $post['OBJET_AO'], 0, 60);
        $validator->isStringAvecEspace($trad->t('Titre'), $post['TITRE'], 0, 3000);
        if ($post['TYPE_SG']=='S') {
            $validator->zoom('Societe', $post['S_CODE_STE'], $trad->t('Société'), $this->pdo);
            $post['CODE_STE'] = $post['S_CODE_STE'];
        } else {
            $validator->zoom('GrpSociete', $post['G_CODE_STE'], $trad->t('Groupe de Sociétés'), $this->pdo);
            $post['CODE_STE'] = $post['G_CODE_STE'];
        }
        $validator->zoom('Hastutil', $post['ACH'], $trad->t('Acheteur'), $this->pdo);
        $validator->zoom('Hastutil', $post['PRESCRIPTEUR'], $trad->t('Prescripteur'), $this->pdo);
        $validator->zoom('Centre', $post['EMETTEUR'], $trad->t('Centre émetteur'), $this->pdo);
        $validator->zoom('Devise', $post['DEVISE'], $trad->t('Devise'), $this->pdo);
        $validator->zoom('Famille', $post['CODE_FAM'], $trad->t('Famille'), $this->pdo, true);

        $validator->isDate($post['DEL_REP'], date('Ymd'), '', false, $trad->t('Réponse attendue pour le'));
        //$validator->isDateGreaterThanToday($post['DEL_REP'], $trad->t('Réponse attendue pour le'));
        $validator->isCheck($post['ACC_CONF']);

        $validator->isFloat($trad->t('Budget global'), $post['BUDG_ENT'], Constante::formatMontant);

        $validator->isCheck($post['COMP_PJ']);
        $validator->isCheck($post['COMP_DOC_ATT']);
        $validator->isCheck($post['COMP_DOC_INT']);
        $validator->isCheck($post['COMP_QUEST']);
        $validator->isCheck($post['COMP_CLAUSE']);

        if ($post['RFI_Q'] == 'Q') {
            $validator->isCheck($post['REPDEV']);
            $validator->isCheck($post['VARIANTE']);
            $post['COMP_LIGNE'] = true;
        } else {
            $post['REPDEV'] = 0;
            $post['VARIANTE'] = 0;
            $post['COMP_LIGNE'] = false;
        }

        if ($idAO != 'noId') {
            $idAO = ChampSupp::autoCompletCodeEnr($idAO);
            $validator->validatorCS('AO_ENTET', $idAO, $post, $this->pdo);
        } elseif ($idOrigine) {
            $idOrigineCS = ChampSupp::autoCompletCodeEnr($idOrigine);
            $validator->validatorCS('AO_ENTET', $idOrigineCS, $post, $this->pdo);
        } else {
            $validator->validatorCS('AO_ENTET', '', $post, $this->pdo);
        }

        $initDoa = false;
        $consultation = new ConsultationService($this->pdo, $this->getTranslationService());

        if ($validator->isValid()) {
            $consultation = new ConsultationService($this->pdo, $this->getTranslationService());
            $docAttWebService = new DocRattaches();

            if ($idAO == 'noId') {
                $consultationWSDL = new \Modules\Consultation\WebService\Consultation();
                $xmlResult = $consultationWSDL->getNumConsultation($post['CODE_STE']);
                $reponse = new \SimpleXMLElement($xmlResult->responseData);
                
                if ($reponse->Retour == "O") {
                    $post['NO_AO'] = (string)$reponse->NumAO;
                    
                    $noReserv = new NoReserv($this->pdo);
                    $noReserv->delete(['NO_AO' => $post['NO_AO']]);
                } else {
                    return new Response(200, [], $this->renderer->render('@popup-erreur/ErreurXml', [
                        'ErreurValid'    => $reponse,
                    ]));
                }
                
                $idMemoTitre = Sql::updateMemo($this->pdo, '', $post['TITRE']);
                $idMemoDescr = Sql::updateMemo($this->pdo, '', $post['DESCR']);
                
                $aoEntetEntity->insert([
                    'RFI_Q'                 => $post['RFI_Q'],
                    'NO_AO'                 => $post['NO_AO'],
                    'TYPE_SG'               => $post['TYPE_SG'],
                    'numerique_AO_PUBLIC'   => Sql::setBoolSql($post['AO_PUBLIC']),
                    'OBJET_AO'              => $post['OBJET_AO'],
                    'NM_TITRE'              => $idMemoTitre,
                    'NM_COMENT'            => $idMemoDescr,
                    'CODE_STE'              => $post['CODE_STE'],
                    'ACH'                   => $post['ACH'],
                    'PRESCRIPTEUR'          => $post['PRESCRIPTEUR'],
                    'EMETTEUR'              => $post['EMETTEUR'],
                    'DEVISE'                => $post['DEVISE'],
                    'DEL_REP'               => $post['DEL_REP'],
                    'numerique_ACC_CONF'    => Sql::setBoolSql($post['ACC_CONF']),
                    'BUDG_ENT'              => $post['BUDG_ENT'],
                    'DTE_AO'                => date('Ymd'),
                    'COD_LNG'               => $post['COD_LNG'],
                    'numerique_COMP_LIGNE'  => Sql::setBoolSql($post['COMP_LIGNE']),
                    'numerique_COMP_PJ'      => Sql::setBoolSql($post['COMP_PJ']),
                    'numerique_COMP_DOC_ATT' => Sql::setBoolSql($post['COMP_DOC_ATT']),
                    'numerique_COMP_DOC_INT' => Sql::setBoolSql($post['COMP_DOC_INT']),
                    'numerique_COMP_QUEST'   => Sql::setBoolSql($post['COMP_QUEST']),
                    'numerique_COMP_CLAUSE'  => Sql::setBoolSql($post['COMP_CLAUSE']),
                    'numerique_REPDEV'      => Sql::setBoolSql($post['REPDEV']),
                    'numerique_VARIANTE'    => Sql::setBoolSql($post['VARIANTE']),
                    'CODE_FAM'              => $post['CODE_FAM'],
                    'TYPEDEL'               => $post['TYPEDEL'],
                ]);
                
                $idCS = str_pad((string) $post['NO_AO'], 9, '0', STR_PAD_LEFT);
                ChampSupp::ajouterCS($post, $this->pdo, $idCS);

                if (($origine??'')=='DA') {
                    //$idOrigine;
                } elseif (($origine??'')=='DOA') {
                    $initDoa = true;
                } elseif (($origine??'')=='AO_ENTET' || ($origine??'') == 'AO_MODELE') {
                    $consultation->duplicateComposant($idOrigine, $post['NO_AO'], 'COMP_FOURNISS');
                    // attention le setBoolSql c'est pour les requete SQL
                    if (Sql::boolSql($post['COMP_LIGNE']) == true) {
                        $consultation->duplicateComposant($idOrigine, $post['NO_AO'], 'COMP_LIGNE', false, $post['CODE_STE']);
                    }
                    if (Sql::boolSql($post['COMP_PJ']) == true) {
                        $consultation->duplicateComposant($idOrigine, $post['NO_AO'], 'COMP_PJ');
                    }
                    if (Sql::boolSql($post['COMP_DOC_ATT']) == true) {
                        $consultation->duplicateComposant($idOrigine, $post['NO_AO'], 'COMP_DOC_ATT');
                    }
                    
                    if (Sql::boolSql($post['COMP_DOC_INT']) == true) {
                        $consultation->duplicateComposant($idOrigine, $post['NO_AO'], 'COMP_DOC_INT', (($post['arrayDoc']??'') != '' || ($post['ACC_CONF'] && empty($post['fileName'])))? true:false);
                    }
                    if (Sql::boolSql($post['COMP_QUEST']) == true) {
                        $consultation->duplicateComposant($idOrigine, $post['NO_AO'], 'COMP_QUEST');
                    }
                    if (Sql::boolSql($post['COMP_CLAUSE']) == true) {
                        $consultation->duplicateComposant($idOrigine, $post['NO_AO'], 'COMP_CLAUSE');
                    }
                }

                $aoQstThEntity = new AoQstTh($this->pdo);

                if (!$aoQstThEntity->find(['NO_AO' => $post['NO_AO'], 'ID_THEME' => 'APRIX'])) {
                    $aoQstThEntity->insert([
                        'NO_AO' => $post['NO_AO'],
                        'ID_THEME' => 'APRIX',
                        'ID_PERE' => '',
                        'LIB_THEME' => 'PRIX',
                        'POIDS' => 1,
                        'NM_COM' => '',
                        'NM_ORDRE' => 1]);
                }

                $idAO = $post['NO_AO'];

                $aoEvent = new AoEvent($this->pdo);
                $aoEvent->rqInsertEventAO($idAO, 'CRE');
            } else {
                $initDoa = true;

                $post['NO_AO'] = $idAO;
                $saveConsultation = $aoEntetEntity->find($idAO);

                $idMemoTitre = Sql::updateMemo($this->pdo, $saveConsultation['NM_TITRE'], $post['TITRE']);
                $idMemoDescr = Sql::updateMemo($this->pdo, $saveConsultation['NM_COMENT'], $post['DESCR']);

                $aoEntetEntity->update([
                    //'TYPE_SG'               => 'S',
                    'numerique_AO_PUBLIC'   => Sql::setBoolSql($post['AO_PUBLIC']),
                    'OBJET_AO'              => $post['OBJET_AO'],
                    //'CODE_STE'              => $post['CODE_STE'],
                    'ACH'                   => $post['ACH'],
                    'PRESCRIPTEUR'          => $post['PRESCRIPTEUR'],
                    'EMETTEUR'              => $post['EMETTEUR'],
                    'DEVISE'                => $post['DEVISE'],
                    'DEL_REP'               => $post['DEL_REP'],
                    'numerique_ACC_CONF'    => Sql::setBoolSql($post['ACC_CONF']),
                    'BUDG_ENT'              => $post['BUDG_ENT'],
                    'COD_LNG'               => $post['COD_LNG'],
                    'numerique_COMP_LIGNE'  => Sql::setBoolSql($post['COMP_LIGNE']),
                    'numerique_COMP_PJ'      => Sql::setBoolSql($post['COMP_PJ']),
                    'numerique_COMP_DOC_ATT' => Sql::setBoolSql($post['COMP_DOC_ATT']),
                    'numerique_COMP_DOC_INT' => Sql::setBoolSql($post['COMP_DOC_INT']),
                    'numerique_COMP_QUEST'   => Sql::setBoolSql($post['COMP_QUEST']),
                    'numerique_COMP_CLAUSE'  => Sql::setBoolSql($post['COMP_CLAUSE']),
                    'NM_TITRE'              => $idMemoTitre,
                    'NM_COMENT'            => $idMemoDescr,
                    'numerique_REPDEV'      => Sql::setBoolSql($post['REPDEV']),
                    'numerique_VARIANTE'    => Sql::setBoolSql($post['VARIANTE']),
                    'CODE_FAM'              => $post['CODE_FAM'],
                ], $idAO);

                champSupp::updateCS($post, $this->pdo);

                //Si l'accord de confidentialité était coché auparavant ET qu'un nouveau document a été saisie (arrayDoc) OU que l'accord a été décoché (ACC_CONF) alors on supprime le document
                /** @phpstan-ignore-next-line */
                if (trim($saveConsultation['ACC_CONF_NODOC']) !== '' && (($post['arrayDoc']??'')!='' || !$post['ACC_CONF']) || empty($post['fileName'])) {
                    $docAttEntity = new Docatt($this->pdo);
                    $infoDoc = $docAttEntity->find([
                        'NO_DA' => 'AO_ENTET',
                        'COD_ENR' => ChampSupp::autoCompletCodeEnr($idAO),
                        'TITRE' => 'Accord de confidentialité'
                    ]);
                    if ($infoDoc) {
                        $docAttWebService->SuppresionDocAtt([
                            'Langue' => $_SESSION['Session_Langue'],
                            'id' => 'AO_ENTET',
                            'refObjet' => $idAO,
                            'numOrdre' => $infoDoc['NO_ORDRE'],
                        ]);
                    }
                    
                    $aoEntetEntity->update(['ACC_CONF_NODOC' => ''], $idAO);
                }
            }
            
            if ($initDoa) {
                $actionRepo = new Action($this->pdo);

                $listeDoa = [];
                if (($origine??'')=='DOA') {
                    $listeDoa[] = $idOrigine;
                } else {
                    $listeIdProjet = $actionRepo->checkLienExterneProjetExist($idAO, 'NO_AO');

                    foreach ($listeIdProjet as $projet) {
                        $listeDoa[] = $projet['ID_OBJET'];
                    }
                }

                $bddObjectRepo = new BddObjects($this->pdo);
                $arrayFindValue = $aoEntetEntity->find($post['NO_AO']);

                foreach ($listeDoa as $idOrigine) {
                    $infoChampsForUpdate = $actionRepo->getIdChampsForUpdate($idOrigine, 'AO_ENTET', 'NO_AO');

                    $actionService = new ActionService($this->pdo);
                    $actionService->insertData($idOrigine, $infoChampsForUpdate['ID_DONNEE'], 0, ['value' => $post['NO_AO'], 'ID_DATA' => $infoChampsForUpdate['ID_DATA']]);

                    $infoStruct = $actionRepo->getInfoStructLie($idOrigine, $infoChampsForUpdate['ID_DONNEE']);
                    $listeData = $actionRepo->getInfoData('noId', $infoChampsForUpdate['ID_DONNEE'], null, true);
                    $keyData = 'OBJET';

                    foreach ($listeData as $data) {
                        $bddOject = $bddObjectRepo->getInfoChamp($infoStruct['OBJET'], $data[$keyData]);

                        $value = $bddObjectRepo->convertChamp($bddOject, $arrayFindValue[$data[$keyData]]??'');

                        $actionService->insertData($idOrigine, $infoChampsForUpdate['ID_DONNEE'], 0, ['value' => $value, 'ID_DATA' => $data['ID_DATA']]);
                    }

                    if (($origine??'')=='DOA') {
                        $listStruct = $actionRepo->getListDataLie($idOrigine, 'AO_FOUR');

                        foreach ($listStruct as $struct) {
                            $infoDataSelected = $actionRepo->getListeExternalObject($idOrigine, $struct['ID_DONNEE']);

                            foreach ($infoDataSelected as $ligneInfoData) {
                                $consultation->addFourniss($post['NO_AO'], 'F', $ligneInfoData['VALEUR']);
                            }
                        }
                    }
                }
            }

            if ($post['arrayDoc']??'') {
                $arrayDoc = unserialize($post['arrayDoc'], ["allowed_classes" => false]);
                Securite::controleExistanceOrDie($arrayDoc, 'refObjet');
        
                $arrayDoc['refObjet'] = ChampSupp::autoCompletCodeEnr($post['NO_AO']);

                $xmlResult= $docAttWebService->NouveauDocAtt($arrayDoc);

                $xmlResult = new \SimpleXMLElement($xmlResult->responseData);

                if ($xmlResult->Statut== "O") {
                    $aoEntetEntity->update(['ACC_CONF_NODOC' => $xmlResult->NumOrdre], $idAO);
                } else {
                    return new Response(200, [

                    ], json_encode(['erreur' => $xmlResult->MsgErreur, 'statut' => $xmlResult->Statut]));
                }
            }

            return new Response(443, [

            ], (string) \json_encode([
                'statut' => 'O',
                'path' => $this->router->generateUri('Consultation.Consultation.details', ['idAO' => $idAO]),
            ]));
        } else {
            return $this->renderer->render('@popup-erreur/ErreurCreation', [
                'ErreurValid' => $validator->getError(),
                'desactiveRow' => true,
            ]);
        }
    }

    public function ajaxUpdateCompAction()
    {
        $idAO = $this->request->getAttribute('idAO');
        $post = $this->request->getParsedBody();

        $consultationService = new ConsultationService($this->pdo, $this->getTranslationService());

        if ($post['COMPOSANT']=='ongletLigne') {
            $composant = 'COMP_LIGNE';
        } elseif ($post['COMPOSANT']=='ongletPJ') {
            $composant = 'COMP_PJ';
        } elseif ($post['COMPOSANT']=='ongletDocAtt') {
            $composant = 'COMP_DOC_ATT';
        } elseif ($post['COMPOSANT']=='ongletDocInt') {
            $composant = 'COMP_DOC_INT';
        } elseif ($post['COMPOSANT']=='ongletClause') {
            $composant = 'COMP_CLAUSE';
        } elseif ($post['COMPOSANT']=='ongletQst') {
            $composant = 'COMP_QUEST';
        } else {
            $composant = '';
        }
        $aoEntete = new AoEntet($this->pdo);
        $infoEntete = $aoEntete->find($idAO);

        $consultationService->deleteComposant($idAO, $composant, false, $infoEntete['ACC_CONF_NODOC']);

        $aoEntete->update([
            'numerique_'.$composant => ($post['STATUT']=='show'? '0x54':'0x46')
        ], $idAO);

        return new Response(200);
    }

    public function deleteAction()
    {
        $idAO = $this->request->getAttribute('idAO');

        /** delete entete **/
        $aoEntet = new AoEntet($this->pdo);
        $infoEntete = $aoEntet->find($idAO);
        $aoEntet->delete($idAO);
        sql::deleteMemos($this->pdo, $infoEntete['NM_TITRE']);
        sql::deleteMemos($this->pdo, $infoEntete['NM_COMENT']);

        $consultationService = new ConsultationService($this->pdo, $this->getTranslationService());

        $aoFour = new AoFour($this->pdo);
        $listeFrs = $aoFour->findAll(['NO_AO' => $idAO]);

        // on delete tout les onglet de la consultation
        $consultationService->deleteComposant($idAO, 'COMP_FOURNISS');
        $consultationService->deleteComposant($idAO, 'COMP_LIGNE');
        $consultationService->deleteComposant($idAO, 'COMP_PJ');
        $consultationService->deleteComposant($idAO, 'COMP_DOC_ATT');
        $consultationService->deleteComposant($idAO, 'COMP_DOC_INT');
        $consultationService->deleteComposant($idAO, 'COMP_CLAUSE');
        $consultationService->deleteComposant($idAO, 'COMP_QUEST');

        $aoRep = new AoRep($this->pdo);
        $aoRepPijo = new AoRepPijo($this->pdo);
        $aoRepQst = new AoRepQst($this->pdo);
        $aoRepSl = new AoRepSl($this->pdo);
        $aoRetParLigne = new AoRetParLigne($this->pdo);

        // on delete toute les réponses de la consultation
        $aoRep->delete(['NO_AO' => $idAO]);
        $aoRepPijo->delete(['NO_AO' => $idAO]);
        $aoRepQst->delete(['NO_AO' => $idAO]);
        $aoRepSl->delete(['NO_AO' => $idAO]);
        $aoRetParLigne->delete(['NO_AO' => $idAO]);

        $idCS = str_pad($idAO, 9, '0', STR_PAD_LEFT);
        ChampSupp::deleteCS('AO_ENTET', $idCS, $this->pdo);

        $actionRepo = new Action($this->pdo);
        $listeIdProjet = $actionRepo->checkLienExterneProjetExist($idAO, 'NO_AO');

        // on supprime les liens consultation/projet achat
        foreach ($listeIdProjet as $projet) {
            $actionRepo->deleteLiensExterne($projet['ID_OBJET'], $projet['ID_DONNEE']);
            $listeDonnee = $actionRepo->getListDataLie($projet['ID_OBJET'], 'AO_FOUR');
            
            foreach ($listeFrs as $frs) {
                foreach ($listeDonnee as $donnee) {
                    $champsKeyUnique = $actionRepo->getIdChampsForUpdate($projet['ID_OBJET'], 'FOURNISS', 'CODE', $donnee['ID_DONNEE']);
                    
                    $actionRepo->suppresionLienTableSecondaire($projet['ID_OBJET'], $donnee['ID_DONNEE'], $champsKeyUnique['ID_DATA'], 'AO_FOUR', $frs['CODE_FOU']);
                }
            }
        }

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

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

        if (!$post) {
            $post['tri_DTE'] = 'desc';
            $post['tri_HEURE'] = 'desc';
        }

        $trad = $this->getTranslationService();

        $listeLibelleEvent = $this->getLibelleEvenement($this->pdo);

        $aoEvent = new AoEvent($this->pdo);
        $listeEvent = $aoEvent->getListeEvent($idAO, $post);

        $paginator = new \Helpers\Pagination\Paginator();
        $infopagination = $paginator->generate($listeEvent, 50, $post, $this->renderer);

        Ariane::generate(1, $trad->t('Liste des évènements'));

        return $this->renderer->render('@Consultation/Consultation/suivi', [
            'idAO' => $idAO,

            'pathBack' => ariane::getBackPath(),
            'menuActive' => $_SESSION['typeMenu'] == 'P2P'? 'eproc':'Consultations',
            'menuLeft' => 'gestionAO',
            'trad' => $trad,

            'listeLibelleEvent' => $listeLibelleEvent,
            'listeEvent' => $listeEvent,
            'post' => $post,
            'infoPagination' => $infopagination,
        ]);
    }

    public function popupBlocNoteAction()
    {
        $idAO = $this->request->getAttribute('idAO');
        $post = $this->request->getParsedBody();

        $trad = $this->getTranslationService();

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

        $consultationRepo = new Consultation($this->pdo);
        $infoBlocNote = $consultationRepo->getBlocNote($idAO);

        if ($post && isset($post['contmemo'])) {
            $validator = $this->createValidator();
            $validator->isStringAvecEspace($trad->t('Bloc-note'), $post['contmemo'], 0, 3000);

            if ($validator->isValid()) {
                $idMemo = sql::updateMemo($this->pdo, $infoBlocNote['NODEMEMO']??null, $post['contmemo']);

                $consultationRepo->insertBnote($idAO, $idMemo);

                return new Response(200);
            } else {
                return new Response(443, [], $validator->getError());
            }
        }

        $droit = [
            'HA_AO_ADM' => Roles::droitsUtilisateur($this->pdo, 'HA_AO_ADM', $_SESSION["Session_Login"]),
            'HA_AO_CMV' => Roles::droitsUtilisateur($this->pdo, 'HA_AO_CMV', $_SESSION["Session_Login"]),
        ];


        return $this->renderer->render('@Consultation/Consultation/blocknote', [
            'canEdit' => ($droit['HA_AO_ADM'] || ($droit['HA_AO_CMV'] && $consultation['ACH'] == $_SESSION["Session_Login"])),
            'idAO' => $idAO,
            'post' => $infoBlocNote,
        ]);
    }

    public function popupStepBarAction() : string
    {
        $idAO = $this->request->getAttribute('idAO');
        $idFrs = $this->request->getAttribute('idFrs');
        $typeFG = $this->request->getAttribute('typeFG');

        $aoFour = new AoFour($this->pdo);
        $infoFou = $aoFour->find(['NO_AO' => $idAO, 'CODE_FOU' => $idFrs, 'TYPE_FG' => $typeFG]);

        $aoEventRepo = new AoEvent($this->pdo);
        $dateEnvoieAccord = $aoEventRepo->getLastDate($idAO, $idFrs, $typeFG, 'ENV', 'Demande de signature de l\'accord de confidentialité');
        $dateAjoutAccordSigne = $aoEventRepo->getLastDate($idAO, $idFrs, $typeFG, 'ACS');
        $dateAccordValider = $aoEventRepo->getLastDate($idAO, $idFrs, $typeFG, 'ACV');
        $dateEnvoie = $aoEventRepo->getLastDate($idAO, $idFrs, $typeFG, 'ENV');

        return $this->renderer->render('@Consultation/Consultation/popupStepBar', [
            'idFrs' => $idFrs,
            'infoFou' => $infoFou,
            'dateEnvoieAccord' => $dateEnvoieAccord['DTE']??'',
            'dateAjoutAccordSigne' => $dateAjoutAccordSigne['DTE']??'',
            'dateAccordValider' => $dateAccordValider['DTE']??'',
            'dateEnvoie' => $dateEnvoie['DTE']??''
        ]);
    }

//_____________________________________________________________________________
// Sub-routine

    /**
    * @return array<string>
    */
    public function getLibelleEvenement(\PDO $pdo) : array
    {
        $trad = $this->getTranslationService();

        $arrayReturn = [
            'CRE' => $trad->t('Création'),
            'SUP' => $trad->t('Suppression'),
            'VAL' => $trad->t('Validation préparation AO'),
            'CHX' => $trad->t('Choix fournisseur'),
            'ENV' => $trad->t('Envoi au fournisseur'),
            'REP' => $trad->t('Validation de la saisie de réponse fournisseur'),
            'SIG' => $trad->t('Signature préparation AO'),
            'SCH' => $trad->t('Signature choix fournisseur'),
            'DEV' => $trad->t('Dévalidation préparation'),
            'DCH' => $trad->t('Dévalidation choix fournisseur'),
            'AJF' => $trad->t('Ajout fournisseur après validation'),
            'SUF' => $trad->t('Suppression fournisseur après validation'),
            'ACS' => $trad->t('Signature accord de confidentialité'),
            'ACV' => $trad->t('Validation accord confidentialité'),
            'ACR' => $trad->t('Accord de confidentialité refusé'),
            'REL' => $trad->t('Relance fournisseur'),
        ];

        return $arrayReturn;
    }
}
