<?php

namespace Modules\Consultation\Service;

use Entity\Model\AoFour;
use Entity\Model\AoLigne;
use Entity\Model\AoPijo;
use Entity\Model\AoClaus;
use Entity\Model\AoQstTh;
use Entity\Model\AoRepSl;
use Entity\Model\Hastutil;
use Helpers\Trad\ITrad;
use Modules\Evaluation\Repository\BibliothequeDeQuestions;
use Helpers\Outil\Sql;
use Entity\Model\Docatt;
use Modules\Consultation\Repository\Consultation;
use Entity\Model\AoQstQ;
use Entity\Model\AoQstR;
use Helpers\Fichier\Fichier;
use Helpers\Trad\Trad;
use Entity\Model\AoEntet;
use Modules\Consultation\Repository\AoEvent;
use Entity\Model\AoRetParLigne;
use Entity\Model\AoDocAttendus;
use Entity\Model\AoPlann;
use Entity\Model\OxalinkUser;
use Helpers\ChampsSupplementaire\ChampSupp;
use Modules\Consultation\Repository\GestionConsultation;
use Modules\Consultation\Repository\Reponse;
use Modules\ProjetAchat\Service\ActionService;
use Helpers\Outil\Mail;
use Helpers\Outil\Outils;
use Helpers\Outil\Date;

class ConsultationService
{
    private \PDO $pdo;
    private ITrad $trad;

    public function __construct(\PDO $pdo, ITrad $trad)
    {
        $this->pdo = $pdo;
        $this->trad = $trad;
    }
    
    public function deleteComposant(string $idAO, string $composant, bool $all = true, bool $accordConf = false) : void
    {
        if ($composant=='COMP_FOURNISS') {
            /** delete fournisseur **/
            $aoFour = new AoFour($this->pdo);
            $aoFour->delete(['NO_AO' => $idAO]);
        } elseif ($composant=='COMP_LIGNE') {
            /** delete ligne **/
            $aoLigne = new AoLigne($this->pdo);
            $allLigne = $aoLigne->fetchAll([], ['filter_egal_NO_AO' => $idAO]);
            $aoLigne->delete(['NO_AO' => $idAO]);
            
            foreach ($allLigne as $ligne) {
                Sql::deleteMemos($this->pdo, $ligne['NM_DCOMP']);
                sql::deleteMemos($this->pdo, $ligne['NM_ST_AV']);
            }
        } elseif ($composant=='COMP_PJ') {
            /** delete PJ **/
            $aoPJ = new AoPijo($this->pdo);
            $allPj = $aoPJ->fetchAll([], ['filter_egal_NO_AO' => $idAO]);
            $aoPJ->delete(['NO_AO' => $idAO]);
            
            foreach ($allPj as $pj) {
                unlink($_SESSION['chemin_pj'].$pj['NOM_FIC']);
            }
        } elseif ($composant=='COMP_DOC_ATT') {
            /** delete doc attendu **/
            $aoDocAttendu = new AoDocAttendus($this->pdo);
            $aoDocAttendu->delete(['NO_AO' => $idAO]);
        } elseif ($composant=='COMP_DOC_INT') {
            /** delete doc interne + file + memo **/
            $docAtt = new Docatt($this->pdo);
            $listeDoc = $docAtt->fetchAll([], ['filter_egal_NO_DA' => 'AO_ENTET', 'filter_egal_COD_ENR' => str_pad($idAO, 9, '0', STR_PAD_LEFT)]);
            
            foreach ($listeDoc as $doc) {
                $docAtt->delete([
                    'NO_DA' => 'AO_ENTET',
                    'COD_ENR' => str_pad($idAO, 9, '0', STR_PAD_LEFT)
                ]);
                if ($all || $doc['NO_ORDRE'] != $accordConf) {
                    unlink($_SESSION['chemin_pj'].$doc['NOM_FIC']);
                    sql::deleteMemos($this->pdo, $doc['NM_COMM']);
                }
            }
        } elseif ($composant=='COMP_CLAUSE') {
            /** delete clause + memo **/
            $aoClause = new AoClaus($this->pdo);
            $listeClause = $aoClause->fetchAll([], ['filter_egal_NO_AO' => $idAO]);
            $aoClause->delete(['NO_AO' => $idAO]);
            
            foreach ($listeClause as $clause) {
                sql::deleteMemos($this->pdo, $clause['NM_PARAG']);
            }
        } elseif ($composant=='COMP_QUEST') {
            /** delete Question (AO_QST_TH - AO_QST_R - AO_QST_Q) + memo **/
            $aoQstTh = new AoQstTh($this->pdo);
            $themePere = $aoQstTh->fetchAll([], ['filter_egal_NO_AO' => $idAO, 'filter_egal_ID_PERE' => '']);
            
            $bibliotheque = new BibliothequeDeQuestions($this->pdo);
            foreach ($themePere as $theme) {
                if ($theme['ID_THEME'] != 'APRIX' || $all) {
                    $bibliotheque->deleteTheme('AO', $idAO, $theme['ID_THEME']);
                }
            }
        }
    }
    
    public function duplicateComposant(string $idAOOrigine, string $idNewAo, string $composant, bool $newAccord = false, string $societe = '') : void
    {
        $consultationRepo = new Consultation($this->pdo);
        if ($composant=='COMP_FOURNISS') {
            $consultationRepo->duplicateFrsAO($idAOOrigine, $idNewAo);
            
            $consultationRepo = new Consultation($this->pdo);
            $listeAoFour = $consultationRepo->getListeFrsAo($idNewAo);
            $aoFourRepo = new AoFour($this->pdo);
    
            foreach ($listeAoFour as $frs) {
                if (Sql::boolSql($frs['GEREPORTAIL'])) {
                    $ctcFound = $consultationRepo->getOxalinkUser($frs['CODE_FOU'], $frs['EMAILCONT']);
    
                    if (!$ctcFound) {
                        $ctcUpdate = $consultationRepo->getOxalinkUser($frs['CODE_FOU']);
    
                        if ($ctcUpdate) {
                            $aoFourRepo->update([
                                'NOM_CTCT'   => $ctcUpdate['NOM'],
                                'TEL_CTCT'   => $ctcUpdate['TEL'],
                                'FAX_CTCT'   => $ctcUpdate['FAX'],
                                'POR_CTCT'   => $ctcUpdate['TELPORT'],
                                'EMAILCONT'  => $ctcUpdate['EMAIL'],
                            ], ['NO_AO' => $idNewAo, 'CODE_FOU' => $frs['CODE_FOU']]);
                        }
                    }
                } else {
                    $ctcFound = $consultationRepo->getContactFrs($frs['CODE_FOU'], $frs['EMAILCONT']);
                    
                    if (!$ctcFound) {
                        $ctcUpdate = $consultationRepo->getContactFrs($frs['CODE_FOU']);
    
                        if ($ctcUpdate) {
                            $aoFourRepo->update([
                                'NOM_CTCT'   => $ctcUpdate['NOM'],
                                'TEL_CTCT'   => $ctcUpdate['TEL'],
                                'FAX_CTCT'   => $ctcUpdate['FAX'],
                                'POR_CTCT'   => $ctcUpdate['TELPORT'],
                                'EMAILCONT'  => $ctcUpdate['EMAIL'],
                            ], ['NO_AO' => $idNewAo, 'CODE_FOU' => $frs['CODE_FOU']]);
                        }
                    }
                }
            }
        } elseif ($composant=='COMP_LIGNE') {
            $aoLigne = new AoLigne($this->pdo);
            $listeLigne = $aoLigne->fetchAll([], ['filter_egal_NO_AO' => $idAOOrigine]);
            
            foreach ($listeLigne as $ligne) {
                $memoDesComp = sql::updateMemo($this->pdo, '', sql::getMemo($this->pdo, $ligne['NM_DCOMP']));
                $memoStAv = sql::updateMemo($this->pdo, '', sql::getMemo($this->pdo, $ligne['NM_ST_AV']));
                
                if (!$societe) {
                    $societe = $ligne['CODE_STE'];
                }
                
                $aoLigne->insert([
                    'NO_AO' => $idNewAo,
                    'NO_PO' => $ligne['NO_PO'],
                    'NO_DA' => $ligne['NO_DA'],
                    'NO_PO_DA' => $ligne['NO_PO_DA'],
                    'CHIF_EXEC' => $ligne['CHIF_EXEC']??'',
                    'CODE_ART' => $ligne['CODE_ART']??'',
                    'DES' => $ligne['DES']??'',
                    'QTE' => $ligne['QTE']??'',
                    'DELAI' => $ligne['DELAI']??'',
                    'UNITE' => $ligne['UNITE']??'',
                    'NM_DCOMP' => $memoDesComp,
                    'BUDGET' => $ligne['BUDGET']??'',
                    'CODE_STE' => $societe,
                    'SSFAMILLE' => $ligne['SSFAMILLE']??'',
                    'NM_ST_AV' => $memoStAv,
                    'numerique_ST_APLIG' => Sql::setBoolSql(sql::boolSql($ligne['ST_APLIG'])),
                    'TITREST' => $ligne['TITREST']??'',
                    'COD_FAB' => $ligne['COD_FAB']??'',
                    'COD_GAM' => $ligne['COD_GAM']??'',
                    'REF_FAB' => $ligne['REF_FAB']??'',
                    'PRIX_REF' => $ligne['PRIX_REF']??'',
                ]);
            }
        } elseif ($composant=='COMP_PJ') {
            $aoPJ = new AoPijo($this->pdo);
            $allPj = $aoPJ->fetchAll([], ['filter_egal_NO_AO' => $idAOOrigine]);

            foreach ($allPj as $pj) {
                $newFile = Fichier::copyFileFicPJ($pj['NOM_FIC']);
                $aoPJ->insert([
                    'NO_AO' => $idNewAo,
                    'NO_ORDRE' => $pj['NO_ORDRE'],
                    'TYPE_PJ' => $pj['TYPE_PJ'],
                    'TITRE' => $pj['TITRE'],
                    'numerique_COPIE' => Sql::setBoolSql(sql::boolSql($pj['COPIE'])),
                    'numerique_LECTURE' => Sql::setBoolSql(sql::boolSql($pj['LECTURE'])),
                    'numerique_IMP_PJ' => Sql::setBoolSql(sql::boolSql($pj['IMP_PJ'])),
                    'numerique_IMP_TITRE' => Sql::setBoolSql(sql::boolSql($pj['IMP_TITRE'])),
                    'NOM_FIC' => $newFile['newPath'],
                    'NOM_ORI' => $pj['NOM_ORI'],
                    'FIC_PDF' => $pj['FIC_PDF'],
                ]);
            }
        } elseif ($composant=='COMP_DOC_ATT') {
            $aoDocAttendu = new AoDocAttendus($this->pdo);
            
            $listeDoc = $aoDocAttendu->fetchAll([], ['filter_egal_NO_AO' => $idAOOrigine]);
            
            foreach ($listeDoc as $doc) {
                $aoDocAttendu->insert([
                    'NO_AO' => $idNewAo,
                    'NUM_ORDRE' => $doc['NUM_ORDRE'],
                    'CODE_DOC' => $doc['CODE_DOC'],
                    'TITRE_DOC' => $doc['TITRE_DOC'],
                    'COMMENTAIRE' => $doc['COMMENTAIRE'],
                    'numerique_OBLIGATOIRE' => Sql::setBoolSql(sql::boolSql($doc['OBLIGATOIRE'])),
                ]);
            }
        } elseif ($composant=='COMP_DOC_INT') {
            $aoEntet = new AoEntet($this->pdo);
            $infoConsult = $aoEntet->find($idAOOrigine);
            
            $docAtt = new Docatt($this->pdo);
            $listeDoc = $docAtt->fetchAll([], ['filter_egal_NO_DA' => 'AO_ENTET', 'filter_egal_COD_ENR' => str_pad($idAOOrigine, 9, "0", STR_PAD_LEFT)]);
            
            foreach ($listeDoc as $doc) {
                if ($infoConsult['ACC_CONF_NODOC'] == $doc['NO_ORDRE'] && $newAccord) {
                } else {
                    $idMemo = sql::updateMemo($this->pdo, '', sql::getMemo($this->pdo, $doc['NM_COMM']));
                    
                    $newFile = Fichier::copyFileFicPJ($doc['NOM_FIC']);
                    
                    $docAtt->insert([
                        'NO_DA' => $doc['NO_DA'],
                        'NO_ORDRE' => $doc['NO_ORDRE'],
                        'TYPE_PJ' => $doc['TYPE_PJ'],
                        'TITRE' => $doc['TITRE'],
                        'numerique_COPIE' => sql::setBoolSql(sql::boolSql($doc['COPIE'])),
                        'NOM_FIC' => $newFile['newPath'],
                        'DT_PARUT' => $doc['DT_PARUT'],
                        'DT_VALID' => $doc['DT_VALID'],
                        'COD_ENR' => str_pad($idNewAo, 9, '0', STR_PAD_LEFT),
                        'AUTEUR' => $doc['AUTEUR'],
                        'CENTRE' => $doc['CENTRE'],
                        'NM_COMM' => $idMemo,
                        'NOM_ORI' => $doc['NOM_ORI'],
                        'numerique_FI_TECH' => sql::setBoolSql(sql::boolSql($doc['FI_TECH'])),
                        'CODE_FOU' => $doc['CODE_FOU'],
                        'numerique_NPRELANCE' => sql::setBoolSql(sql::boolSql($doc['NPRELANCE'])),
                        'numerique_PJ_CDE' => sql::setBoolSql(sql::boolSql($doc['PJ_CDE'])),
                        'numerique_GERE_PAR_PARTENAIRE' => sql::setBoolSql(sql::boolSql($doc['GERE_PAR_PARTENAIRE'])),
                        'numerique_DOC_INUTILE' => sql::setBoolSql(sql::boolSql($doc['DOC_INUTILE'])),
                        'CODE_CAT' => $doc['CODE_CAT'],
                        'DTE_DERNREL' => $doc['DTE_DERNREL'],
                        'numerique_CONTRATCDE' => sql::setBoolSql(sql::boolSql($doc['CONTRATCDE'])),
                    ]);
                    
                    if ($infoConsult['ACC_CONF_NODOC'] == $doc['NO_ORDRE']) {
                        $aoEntetEntity = new AoEntet($this->pdo);
                        $aoEntetEntity->update(['ACC_CONF_NODOC' => $doc['NO_ORDRE']], $idNewAo);
                    }
                }
            }
        } elseif ($composant=='COMP_CLAUSE') {
            $aoClause = new AoClaus($this->pdo);
            $listeClause = $aoClause->fetchAll([], ['filter_egal_NO_AO' => $idAOOrigine]);
            
            foreach ($listeClause as $clause) {
                $idMemos = sql::updateMemo($this->pdo, '', sql::getMemo($this->pdo, $clause['NM_PARAG']));
                
                $aoClause->insert([
                    'NO_AO' => $idNewAo,
                    'NO_ORDRE' => $clause['NO_ORDRE'],
                    'NM_PARAG' => $idMemos,
                ]);
            }
        } elseif ($composant=='COMP_QUEST') {
            $aoQstTh = new AoQstTh($this->pdo);
            $themePere = $aoQstTh->fetchAll([], ['filter_egal_NO_AO' => $idAOOrigine]);
            
            foreach ($themePere as $theme) {
                $idMemo = sql::updateMemo($this->pdo, '', sql::getMemo($this->pdo, $theme['NM_COM']));
                
                $aoQstTh->insert([
                    'NO_AO' => $idNewAo,
                    'ID_THEME' => $theme['ID_THEME'],
                    'ID_PERE' => $theme['ID_PERE'],
                    'LIB_THEME' => $theme['LIB_THEME'],
                    'NM_COM' => $idMemo,
                    'NM_ORDRE' => $theme['NM_ORDRE'],
                    'POIDS' => $theme['POIDS'],
                    'THEME_LIE' => $theme['THEME_LIE'],
                ]);
            }
            $aoQstQ = new AoQstQ($this->pdo);
            $listeQuestion = $aoQstQ->fetchAll([], ['filter_egal_NO_AO' => $idAOOrigine]);
                        
            foreach ($listeQuestion as $question) {
                $idMemo = sql::updateMemo($this->pdo, '', sql::getMemo($this->pdo, $question['NM_COM']));
                $idMemo = sql::updateMemo($this->pdo, '', sql::getMemo($this->pdo, $question['NM_COM']));
                
                $aoQstQ->insert([
                    'NO_AO' => $idNewAo,
                    'ID_THEME' => $question['ID_THEME'],
                    'ID_QUEST' => $question['ID_QUEST'],
                    'G_B_QST_LIE' => $question['G_B_QST_LIE'],
                    'LIB_QUEST' => $question['LIB_QUEST'],
                    'NM_COM' => $idMemo,
                    // @phpstan-ignore-next-line TODO MSA regarder le $ligne['QUEST_FOUR']
                    'numerique_QUEST_FOUR' => Sql::setBoolSql(sql::boolSql($question['QUEST_FOUR'] ?? false)),
                    'TYPE_REP' => $question['TYPE_REP'],
                    'NOTE_FAUX' => $question['NOTE_FAUX'],
                    'NOTE_VRAI' => $question['NOTE_VRAI'],
                    'NUM_FORMAT' => $question['NUM_FORMAT'],
                    'NUM_MIN' => $question['NUM_MIN'],
                    'NUM_MAX' => $question['NUM_MAX'],
                    'POIDS' => $question['POIDS'],
                    'NM_ORDRE' => $question['NM_ORDRE'],
                    'ID_MODEL' => $question['ID_MODEL'],
                ]);
            }
            
            $aoQstR = new AoQstR($this->pdo);
            $listeReponse = $aoQstR->fetchAll([], ['filter_egal_NO_AO' => $idAOOrigine]);
            
            foreach ($listeReponse as $reponse) {
                $idMemo = sql::updateMemo($this->pdo, '', sql::getMemo($this->pdo, $reponse['NM_COM']));
                
                $aoQstR->insert([
                    'NO_AO' => $idNewAo,
                    'ID_THEME' => $reponse['ID_THEME'],
                    'ID_QUEST' => $reponse['ID_QUEST'],
                    'ID_REP' => $reponse['ID_REP'],
                    'TXT_REP' => $reponse['TXT_REP'],
                    'NM_COM' => $idMemo,
                    // @phpstan-ignore-next-line TODO MSA regarder le $ligne['COM_MANUEL']
                    'numerique_COM_MANUEL' => Sql::setBoolSql(sql::boolSql($reponse['COM_MANUEL'] ?? false)),
                    'NOTE' => $reponse['NOTE'],
                ]);
            }
        }
    }
    
    public function validateConsultation(string $idAO) : void
    {
        
        $aoQstQ = new AoQstQ($this->pdo);
        $aoQstQ->update(['G_B_QST_LIE' => ''], ['NO_AO' => $idAO]);
        
        $aoQstTh = new AoQstTh($this->pdo);
        $aoQstTh->update(['THEME_LIE' => ''], ['NO_AO' => $idAO]);
        
        $AoEntet = new AoEntet($this->pdo);
        $consultation = $AoEntet->find($idAO);
        $acheteur = (new Hastutil($this->pdo))->find($consultation['ACH']);
        
        $infoMail = [
            'NAO'           => $idAO,
            'TITREAO'       => sql::getMemo($this->pdo, $consultation['NM_TITRE']),
            'RS_SOC'        => Outils::convertLibelleGlobal($this->pdo, $consultation['TYPE_SG']=='S'? 'Societe':'GrpSociete', '', $consultation['CODE_STE']),
            'OBJETAO'       => $consultation['OBJET_AO'],
            'NOM_ACH'       => $acheteur['NOM'],
            'DTE_VALID_AO'  => Date::dateConverte($consultation['DEL_REP']),
            'URL'           => Sql::paravrac($this->pdo, 'PF_OXALINK', 'URLACCESOXALINK'),
            'DATEREPAO'     => Date::dateConverte($consultation['DEL_REP']),
            'NOMACH'        => $acheteur['NOM'],
        ];
        $consultRepo = new Consultation($this->pdo);
        $listeFrs = $consultRepo->getFrsOxalink($idAO);
        
        foreach ($listeFrs as $frs) {
            if (Sql::boolSql($consultation['ACC_CONF']) == true) {
                Mail::generateMail(
                    $this->pdo,
                    $this->trad,
                    $frs['EMAILCONT'],
                    'EXT_FOU_ACCCONF_LINK',
                    $frs['COD_LNG'],
                    $infoMail,
                    []
                );
                
                $aoEvent = new AoEvent($this->pdo);
                $aoEvent->rqInsertEventAO($idAO, 'ENV', 'Demande de signature de l\'accord de confidentialité', $frs['CODE_FOU'], $frs['TYPE_FG']);
            } else {
                Mail::generateMail(
                    $this->pdo,
                    $this->trad,
                    $frs['EMAILCONT'],
                    'EXT_FOU_LINK',
                    $frs['COD_LNG'],
                    $infoMail,
                    []
                );
                
                $aoEvent = new AoEvent($this->pdo);
                $aoEvent->rqInsertEventAO($idAO, 'ENV', '', $frs['CODE_FOU'], $frs['TYPE_FG']);
            }
        }
        
        $aoEvent = new AoEvent($this->pdo);
        $aoEvent->rqInsertEventAO($idAO, 'VAL');
        
        $noEvent = $aoEvent->getLastOrder($idAO, 'VAL')['MAX_NUM_ORDRE'];
        
        
        $AoEntet->update([
            'DTE_VALID_AO' => date('Ymd'),
            'EVE_VALPREP' => $noEvent,
        ], $idAO);
    }

    /**
     * @return array
     *      arrayRepFrs : Liste des dernières réponse par Frs
     *      arrayCompare : Liste du prix le plus bas pour chaque ligne
     *      arraySelected : Liste des frs selectionné pour chaque ligne (si AO_REP vide, on met le plus bras par défaut)
     *      totalFrs : Cumul des lignes frs
     *      totalSelected : Cumul des lignes selectionné frs
     */
    public function calculeChoixFrs(string $idAO, &$listeFrs) : array
    {
        $aoDocAttendu = new AoDocAttendus($this->pdo);
        $docAttenduActif = $aoDocAttendu->find(['NO_AO' => $idAO, 'OBLIGATOIRE' => 'T']);
        
        $reponseRepo = new Reponse($this->pdo);
        $gestionConsu = new GestionConsultation($this->pdo);
        $ligneConsultation = $gestionConsu->listeLigneConsultation($idAO);
        
        $arrayRepFrs = [];
        $totalFrs = [];
        $totalSelected = [];
        $arrayCompare = [];
        $arraySelected = [];

        $aoRepSl = new AoRepSl($this->pdo);
        
        //On boucle sur tout les fournisseurs
        foreach ($listeFrs as &$frs) {
            //init du calcule par fournisseur
            $totalFrs[$frs['CODE_FOU']] = 0;
            $totalSelected[$frs['CODE_FOU']] = 0;
            //On boucle sur toute les lignes de consultation (par fournisseur)
            foreach ($ligneConsultation as $ligne) {
                $infoRep = $reponseRepo->getInfoRep($idAO, $frs['CODE_FOU'], $frs['TYPE_FG'], $ligne['NO_PO']);

                $listePJ = null;

                if ($infoRep) {
                    $listeRepSl = $aoRepSl->findAll([
                        'NO_AO' => $idAO,
                        'NO_PO_AO' => $ligne['NO_PO'],
                        'DTE_REP' => $infoRep['DTE_REP'],
                        'CODE_FOU' => $infoRep['CODE_FOU'],
                        'TYPE_FG' => $infoRep['TYPE_FG'],
                        'C_V' => $infoRep['C_V'],
                    ]);

                    $totalSousLigne = 0;

                    if ($listeRepSl) {
                        foreach ($listeRepSl as $row) {
                            $totalSousLigne += (float)$row['QTE_PROP'] * (float)$row['PU'];
                        }

                        $infoRep['TOTAL_REPSL'] = $totalSousLigne;
                    }

                    $note = $reponseRepo->getNoteFrs($idAO, $frs['CODE_FOU'], $frs['TYPE_FG'], $infoRep['C_V'], $infoRep['DTE_REP']);
                    
                    $frs['NOTE'] = $note[0];
                    
                    $frs['DTE_REP'] = $infoRep['DTE_REP'];
                    
                    if ($docAttenduActif) {
                        $listePJ = $reponseRepo->getListDocAtt($idAO, $frs['TYPE_FG'], $frs['CODE_FOU'], $infoRep['C_V'], $infoRep['DTE_REP'], true);
                    }
                    
                    $frs['C_V'] = $infoRep['C_V'];
                    $frs['docAbsent'] = $listePJ? true:false;
                    $frs['repDepasse'] = $infoRep['DTELIMIT']<date('Ymd');
                    
                    $arrayRepFrs[$frs['CODE_FOU']][$ligne['NO_PO']] = $infoRep;
                    $totalFrs[$frs['CODE_FOU']] += ((float)$infoRep['QTE']*(float)$infoRep['PU']);
                    
                    //Genere le tableau des prix les plus bas (afin de mettre la case en vert dans la vue)
                    if (isset($arrayCompare[$ligne['NO_PO']])) {
                        if ((float)$infoRep['PU'] == 0) {
                            if ((float)$totalSousLigne && (float)$arrayCompare[$ligne['NO_PO']]['savePU'] > (float)$totalSousLigne) {
                                $arrayCompare[$ligne['NO_PO']] = [
                                    'CODE_FOU' => $frs['CODE_FOU'],
                                    'TYPE_FG' => $frs['TYPE_FG'],
                                    'C_V' => $infoRep['C_V'],
                                    'saveQTE' => $infoRep['QTE'],
                                    'savePU' => $totalSousLigne
                                ];
                            }
                        } else {
                            if (((float) $arrayCompare[$ligne['NO_PO']]['savePU'] > (float)$infoRep['PU'])) {
                                $arrayCompare[$ligne['NO_PO']] = [
                                    'CODE_FOU' => $frs['CODE_FOU'],
                                    'TYPE_FG' => $frs['TYPE_FG'],
                                    'C_V' => $infoRep['C_V'],
                                    'saveQTE' => $infoRep['QTE'],
                                    'savePU' => $infoRep['PU']
                                ];
                            }
                        }
                    } elseif ((float)$infoRep['PU'] != 0) {
                        $arrayCompare[$ligne['NO_PO']] = [
                            'CODE_FOU' => $frs['CODE_FOU'],
                            'TYPE_FG' => $frs['TYPE_FG'],
                            'C_V' => $infoRep['C_V'],
                            'saveQTE' => $infoRep['QTE'],
                            'savePU' => $infoRep['PU']
                        ];
                    } elseif ($totalSousLigne != 0) {
                        $arrayCompare[$ligne['NO_PO']] = [
                            'CODE_FOU' => $frs['CODE_FOU'],
                            'TYPE_FG' => $frs['TYPE_FG'],
                            'C_V' => $infoRep['C_V'],
                            'saveQTE' => $infoRep['QTE'],
                            'savePU' => $totalSousLigne
                        ];
                    }
                    
                    
                    //Genere table de fournisseur au prix le plus bas si aucun fournisseur n'a été séléctionné pour cette ligne
                    if ($infoRep['CODE_FOU'] == '') {
                        $arraySelected[$ligne['NO_PO']] =  $arrayCompare[$ligne['NO_PO']]??'';
                    } else {
                        if ($infoRep['CODE_FOU'] == $frs['CODE_FOU']) {
                            $arraySelected[$ligne['NO_PO']] =  [
                                'CODE_FOU' => $frs['CODE_FOU'],
                                'TYPE_FG' => $frs['TYPE_FG'],
                                'C_V' => $infoRep['C_V'],
                                'saveQTE' => $infoRep['QTE'],
                                'savePU' => $infoRep['PU']
                            ];
                        }
                    }
                }
            }
        }

        //On insère la ligne par defaut si elle n'existe pas déjà
        $aoRetParLigne = new AoRetParLigne($this->pdo);
        /** @var array<mixed> $selected */
        foreach ($arraySelected as $key => $selected) {
            if ($selected['CODE_FOU'] != '') {
                $checkLigne = $aoRetParLigne->find([
                    'NO_AO' => $idAO,
                    'NO_PO' => $key,
                    'CODE_FOU' => $selected['CODE_FOU'],
                    'TYPE_FG' => $selected['TYPE_FG'],
                    'RET_CV' => $selected['C_V']
                ]);
                
                if (!$checkLigne) {
                    $aoRetParLigne->insert([
                        'NO_AO' => $idAO,
                        'NO_PO' => $key,
                        'CODE_FOU' => $selected['CODE_FOU'],
                        'TYPE_FG' => $selected['TYPE_FG'],
                        'RET_CV' => $selected['C_V']
                    ]);
                }
                
                $totalSelected[$selected['CODE_FOU']] += ((float)$selected['saveQTE']*(float)$selected['savePU']);
            }
        }

        $returnArray = [];

        $returnArray = [
            'arrayRepFrs' => $arrayRepFrs,
            'totalFrs' => $totalFrs,
            'totalSelected' => $totalSelected,
            'arrayCompare' => $arrayCompare,
            'arraySelected' => $arraySelected,
        ];
        
        return $returnArray;
    }
    
    public function addFourniss(string $idAO, string $typFG, string $codeFou, string $idRecord = null)
    {
        $aoEntet = new AoEntet($this->pdo);
        $infoEntet = $aoEntet->find($idAO);
        if ($infoEntet && $infoEntet['VALCHXFOU'] != '00000000') {
            return false;
        }
        
        $gestionConsu = new GestionConsultation($this->pdo);
        $reponse = new Reponse($this->pdo);
        $aoFourEntity = new AoFour($this->pdo);
        
        if ($typFG == 'F') {
            $frs = $gestionConsu->getInfoFrs($codeFou);
        } else {
            $frs = $gestionConsu->getInfoGrpFrs($codeFou);
        }
        
        $frsExist = $aoFourEntity->find([
            'NO_AO'     => $idAO,
            'TYPE_FG'   => $typFG,
            'CODE_FOU'  => $frs['CODE']??'',
        ]);
        
        if ($frsExist) {
            return true;
        }
        
        $noCol = $reponse->getMaxCol($idAO);
        
        $aoFourEntity->insert([
            'NO_AO'     => $idAO,
            'CODE_FOU'  => $frs['CODE']??'',
            'NOM_CTCT'  => $frs['NOM']??'',
            'TEL_CTCT'  => $frs['TEL']??'',
            'FAX_CTCT'  => $frs['FAX']??'',
            'POR_CTCT'  => $frs['TELPORT']??'',
            'EMAILCONT'  => $frs['EMAIL']??'',
            'ADR'       => $frs['ADR']??'',
            'VILLE'     => $frs['VILLE']??'',
            'PAYS'      => $frs['CODE_PAYS']??'',
            'CPOSTAL'   => $frs['CPOSTAL']??'',
            'VILLE1'    => $frs['VILLE1']??'',
            'RET_CV'    => 'C',
            'TYPE_FG'   => $typFG,
            'NO_COL'    => ((int)($noCol['MAX_NO_COL']??'0')) +1
        ]);
        
        if ($infoEntet['DTE_VALID_AO'] != '00000000') {
            $aoEvent = new AoEvent($this->pdo);
            $aoEvent->rqInsertEventAO($idAO, 'AJF');
        }

        if ($typFG == 'F') {
            $actionService = new ActionService($this->pdo);
            $actionService->insertInfoConsultToProject($codeFou, (int)$idAO, (int)$idRecord);
        }
    }

    /**
     * @param array<mixed> $article
     */
    public function addArticleToConsult(string $idConsult, $article, bool $articleGenerique = false) : void
    {
        $aoEntet = new AoEntet($this->pdo);
        $infoEntet = $aoEntet->find($idConsult);

        $gestionConsultation = new GestionConsultation($this->pdo);
        $idLigne = (int)$gestionConsultation->getMaxLigneAo($idConsult)['MAX_PO'];
        $idLigne = $idLigne + 1;

        if ($articleGenerique) {
            $prix =  '0';
        } else {
            $prix = $article['PX_ART'];
        }

        $aoLigne = new AoLigne($this->pdo);
        $aoLigne->insert([
            'NO_AO'         => $idConsult,
            'NO_PO'         => $idLigne,
            'NO_DA'         => '',
            'NO_PO_DA'      => '',
            'CODE_ART'      => $article['COD_ART'],
            'DES'           => $article['DES_ART'],
            'NM_DCOMP'      => Sql::updateMemo($this->pdo, '', $article['DES_ART']),
            'QTE'           => 0,
            'UNITE'         => $article['COD_UNIT'],
            'DELAI'         => '00000000',
            'BUDGET'        => '',
            'PRIX_REF'      => $prix,
            'SSFAMILLE'     => $article['COD_SFAM'],
            'COD_FAB'       => $article['COD_FAB'],
            'COD_GAM'       => $article['COD_GAM'],
            'REF_FAB'       => $article['COD_FAB']??'',
            'CODE_STE'      => $infoEntet['CODE_STE'],
        ]);

        $aoPlann = new AoPlann($this->pdo);
        $aoPlann->insert([
            'NO_AO' => $idConsult,
            'NO_PO' => $idLigne,
            'DTE' => '00000000',
            'QTE' => 0,
        ]);

        $champSupp = new ChampSupp($this->pdo);
        $listeCS = $champSupp->getInfoCS('AO_LIGNE');

        foreach ($listeCS as $cs) {
            $valueCS = '';
            if ($cs['TAB_SOUR'] == 'ARTICLES' && $article['COD_ART'] != '') {
                $idCS = $article['COD_ART'];
                $valueCS = ChampSupp::getValueCS($cs['TAB_SOUR'], $idCS, $cs['CHP_SOUR'], $this->pdo);
            } elseif ($cs['TAB_SOUR'] == 'AO_ENTET') {
                $idCS = $champSupp::autoCompletCodeEnr($idConsult, '', 'AO_ENTETE');
                $valueCS = ChampSupp::getValueCS($cs['TAB_SOUR'], $idCS, $cs['CHP_SOUR'], $this->pdo);
            }

            $idCSLigne = $champSupp::autoCompletCodeEnr($idConsult, $idLigne, 'AO_LIGNE');
            $champSupp->insertChampSupp('AO_LIGNE', $idCSLigne, $cs['NUM_FIX'], $valueCS, $this->pdo);
        }
    }

    /**
     * @param array<mixed> $infoEntet
     * @param array<mixed> $article
     */
    public function getPrixRef($infoEntet, $article) : string
    {
        $consultation = new Consultation($this->pdo);
        $prixRef = 0;

        if ($article['REF_FAB'] != '' && $article['COD_FAB'] != '') {
            $prixRef = $consultation->getPrixRef($infoEntet['TYPE_SG'], $infoEntet['CODE_STE'], true, $article);
        }

        if (!$prixRef) {
            $prixRef = $consultation->getPrixRef($infoEntet['TYPE_SG'], $infoEntet['CODE_STE'], false, $article);
        }

        return $prixRef;
    }
}
