<?php

namespace Modules\Consultation\Controller;

use Helpers\Session\Enums\MenuTopEnum;
use Helpers\Session\Session;
use Helpers\Trad\Trad;
use Modules\Consultation\Repository\ConsultationLigneRepo;
use Skeleton\Controller\Controller;
use Modules\Consultation\Repository\GestionConsultation;
use Modules\Consultation\Repository\AoEvent;
use Helpers\Ariane\ArianeSub;
use Entity\Model\Articles;
use GuzzleHttp\Psr7\Response;
use Entity\Model\AoLigne;
use Entity\Model\DaLigne;
use Helpers\ChampsSupplementaire\ChampSupp;
use Helpers\Outil\Sql;
use Entity\Model\AoEntet;
use Entity\Model\AoPlann;
use Helpers\Outil\Date;
use Helpers\Pagination\PaginatorGestion;
use Entity\Model\AoQstTh;
use Entity\Model\Gamme;
use Modules\GlobalApplication\Repository\Societe;
use Helpers\Parametres\Constante;

class ArticlesController extends Controller
{
    public function createEditAction() : string
    {
        $idAO = $this->request->getAttribute('idAO');
        $idLigne = $this->request->getAttribute('idLigne');
        $post = $this->request->getParsedBody();
        
        if (isset($idLigne)) {
            $aoLigne = new AoLigne($this->pdo);
            $article = $aoLigne->find(['NO_AO' => $idAO, 'NO_PO' => $idLigne]);
            $article['DES_COMP'] = sql::getMemo($this->pdo, $article['NM_DCOMP']);
            $article['TITRE_AV_LIGNE'] = sql::getMemo($this->pdo, $article['NM_ST_AV']);
            
            $article['DELAI'] = Date::dateConverte($article['DELAI']);
        }
        
        
        $gestionConsu = new GestionConsultation($this->pdo);
        $consultation = $gestionConsu->getInfoAo($idAO);
        
        $aoEvent = new AoEvent($this->pdo);
        $AOEventCreat = $aoEvent->getNameCreate($idAO);

        $trad = $this->getTranslationService();

        if (isset($article)) {
            $Gamme = new Gamme($this->pdo);
            $gammes = $Gamme->find(['CODEFABR' => $article['CODE_FAB']]);
        }
        
        if ($idLigne) {
            ArianeSub::generate(1, 0, $trad->t('Modification article'), $this->router->generateUri('Consultation.Clause.creatEdit', ['idAO' => $idAO, 'idLigne' => $idLigne]), 1);
        } else {
            ArianeSub::generate(1, 0, $trad->t('Ajouter un article'), $this->router->generateUri('Consultation.Clause.creatEdit', ['idAO' => $idAO]), 1);
        }
                
        return $this->renderer->render('@Consultation/Articles/createEdit', [
            'menuActive'        => Session::verifySessionTypeMenuTop(MenuTopEnum::P2P) ? 'eproc':'Consultations',
            'menuLeft'          => 'gestionAO',
            'idAO'              => $idAO,
            'idLigne'           => $idLigne,
            'post'              => $post,
            'consultation'      => $consultation,
            'AOEventCreat'      => $AOEventCreat,
            'CODE_STE'          => $_SESSION["Session_SocUsr"],
            'article'           => $article??'',
            'gammes'            => $gammes??[]
        ]);
    }
    
    public function ajaxChangeArticleAction(): Response
    {
        $post = $this->request->getParsedBody();
        
        $articleEntity = new Articles($this->pdo);
        $article = $articleEntity->find($post['CODE_ART']);

        $GammeEntity = new Gamme($this->pdo);
        $gammes = $GammeEntity->findAll(['CODEFABR' => $article['CODEFAB']]);
   
        return new Response(200, [], (string) \json_encode([
            'STATUT' => $article? 'O':'E',
            'DES' => $article['DESIGN'],
            'COD_FAB' => $article['CODEFAB'],
            'COD_GAM' => $article['CODEGAM'],
            'SSFAMILLE' => $article['SSFAM'],
            'UNITE' => $article['UNIT'],
            //@phpstan-ignore-next-line
            'GAMMES' => $gammes??[]
        ]));
    }

    public function ajaxChangeGammeAction(): Response
    {
        $post = $this->request->getParsedBody();

        $GammeEntity = new Gamme($this->pdo);
        $gammes = $GammeEntity->findAll(['CODEFABR' => $post['CODE']]);

        return new Response(200, [], (string) \json_encode([
            //@phpstan-ignore-next-line
            'GAMMES' => $gammes??[]
        ]));
    }
    
    public function ajaxChangeDAAction(): Response
    {
        $post = $this->request->getParsedBody();
        
        $daLigne = new DaLigne($this->pdo);
        $da = $daLigne->find(['NO_DA' => $post['NO_DA'], 'NO_PO' => $post['NO_PO']]);
        
        return new Response(200, [], (string) \json_encode([
            'STATUT' => $da? 'O':'E',
            'CODE_ART' => $da['CODE_ART']??'',
            'DES' => $da['DES_SOMM']??'',
            'COD_FAB' => $da['COD_FAB']??'',
            'COD_GAM' => $da['COD_GAM']??'',
            'CHIF_EXEC' => $da['CHIF_EXEC']??'',
            'SSFAMILLE' => $da['SSFAM']??'',
            'UNITE' => $da['UNITE']??'',
            'QTE' => $da['QTE_DEM']??'',
            'REF_FAB' => $da['REF_FAB']??'',
        ]));
    }
    
    public function validateAction()
    {
        $idAO = $this->request->getAttribute('idAO');
        $idLigne = $this->request->getAttribute('idLigne');
        $post = $this->request->getParsedBody();
       
        $aoLigne = new AoLigne($this->pdo);
        $aoPlann = new AoPlann($this->pdo);
        $aoEntet = new AoEntet($this->pdo);
        $infoEntet = $aoEntet->find($idAO);
        
        $trad = $this->getTranslationService();
        
        $validator = $this->createValidator();
       
        if ($post['NO_DA']) {
            $validator->zoom('DaEntet', $post['NO_DA'], $trad->t('DA'), $this->pdo, true);
        }
        $validator->zoom('Articles', $post['CODE_ART'], $trad->t('Code article'), $this->pdo, true);
        $validator->isStringAvecEspace($trad->t('Désignation'), $post['DES'], 1, 60);
        $validator->isStringAvecEspace($trad->t('Désignation compl.'), $post['DES_COMP'], 0, 3000);
        $validator->zoom('fabricant', $post['COD_FAB'], $trad->t('Fabricant'), $this->pdo, true);
        // TODO: COD_GAM NOT FOUND
        $validator->zoom('gamme', $post['COD_GAM'], $trad->t('Gamme'), $this->pdo, true);
        $validator->zoom('sousFamille', $post['SSFAMILLE'], $trad->t('Sous famille'), $this->pdo, false);
        $validator->isStringAvecEspace($trad->t('Réf. fabricant'), $post['REF_FAB'], 0, 30);
        $validator->isFloat($trad->t('Quantité'), $post['QTE'], Constante::formatQTE);
                
        $validator->uniteZoom($post['UNITE'], $trad->t('Unité'), $this->pdo, true, ['ssFamille' => $post['SSFAMILLE']]);
                
        $validator->isFloat($trad->t('Prix référence'), $post['PRIX_REF'], constante::formatPU);

        $validator->isFloat($trad->t('Budget'), $post['BUDGET'], Constante::formatMontant);
        $validator->isDate($post['DELAI'], '', '', true);
        
        $validator->isStringAvecEspace($trad->t('Titre avant le poste'), $post['TITRE_AV_LIGNE'], 0, 3000);
        $validator->isCheck($post['ST_APLIG']);
        $validator->isStringAvecEspace($trad->t('Titre sous-total'), $post['TITREST'], $post['ST_APLIG'], 3000);
        
        $codeCS = '';
        if ($idLigne) {
            $codeCS = ChampSupp::autoCompletCodeEnr($idAO, $idLigne, 'AO_LIGNE');
        }
        $validator->validatorCS('AO_LIGNE', $codeCS, $post, $this->pdo);

        $aoLigneEntity = new AoLigne($this->pdo);
        if ($validator->isValid(true)) {
            if ($idLigne) {
                $article = $aoLigne->find(['NO_AO' => $idAO, 'NO_PO' => $idLigne]);
                $memoDesComp = Sql::updateMemo($this->pdo, $article['NM_DCOMP'], $post['DES_COMP']);
                $memoStAv = Sql::updateMemo($this->pdo, $article['NM_ST_AV'], $post['TITRE_AV_LIGNE']);
                
                $aoLigneEntity->update([
                    'NO_DA' => $post['NO_DA']??0,
                    'NO_PO_DA' => $post['NO_PO_DA']??0,
                    'CHIF_EXEC' => $post['CHIF_EXEC']??'',
                    'CODE_ART' => $post['CODE_ART']??'',
                    'DES' => $post['DES']??'',
                    'QTE' => floatval($post['QTE']??0),
                    'DELAI' => intval($post['DELAI']??0),
                    'UNITE' => $post['UNITE']??'',
                    'NM_DCOMP' => $memoDesComp,
                    'BUDGET' => floatval($post['BUDGET']??0),
                    'CODE_STE' => $infoEntet['CODE_STE'],
                    'SSFAMILLE' => $post['SSFAMILLE']??'',
                    'NM_ST_AV' => $memoStAv,
                    'numerique_ST_APLIG' => Sql::setBoolSql($post['ST_APLIG']),
                    'TITREST' => $post['TITREST']??'',
                    'COD_FAB' => $post['COD_FAB']??'',
                    'COD_GAM' => $post['COD_GAM']??'',
                    'REF_FAB' => $post['REF_FAB']??'',
                    'PRIX_REF' => floatval($post['PRIX_REF']??0),
                ], ['NO_AO' => $idAO, 'NO_PO' => $idLigne]);

                $aoPlann->update([
                    'DTE' => $post['DELAI'],
                    'QTE' => $post['QTE']??'',
                ], [
                    'NO_AO' => $idAO,
                    'NO_PO' => $idLigne,
                ]);
                
                ChampSupp::updateCS($post, $this->pdo);
            } else {
                $gestionConsultation = new GestionConsultation($this->pdo);
                $idLigne = (int) $gestionConsultation->getMaxLigneAo($idAO)['MAX_PO'] + 1;
                $memoDesComp = Sql::updateMemo($this->pdo, '', $post['DES_COMP']);
                $memoStAv = Sql::updateMemo($this->pdo, '', $post['TITRE_AV_LIGNE']);

                $aoLigneEntity->insert([
                    'NO_AO' => $idAO,
                    'NO_PO' => $idLigne,
                    'NO_DA' => $post['NO_DA']??0,
                    'NO_PO_DA' => $post['NO_PO_DA']??0,
                    'CHIF_EXEC' => $post['CHIF_EXEC']??'',
                    'CODE_ART' => $post['CODE_ART']??'',
                    'DES' => $post['DES']??'',
                    'QTE' => floatval($post['QTE']??0),
                    'DELAI' => intval($post['DELAI']??0),
                    'UNITE' => $post['UNITE']??'',
                    'NM_DCOMP' => $memoDesComp,
                    'BUDGET' => floatval($post['BUDGET']??0),
                    'CODE_STE' => $infoEntet['CODE_STE'],
                    'SSFAMILLE' => $post['SSFAMILLE']??'',
                    'NM_ST_AV' => $memoStAv,
                    'numerique_ST_APLIG' => Sql::setBoolSql($post['ST_APLIG']),
                    'TITREST' => $post['TITREST']??'',
                    'COD_FAB' => $post['COD_FAB']??'',
                    'COD_GAM' => $post['COD_GAM']??'',
                    'REF_FAB' => $post['REF_FAB']??'',
                    'PRIX_REF' => floatval($post['PRIX_REF']??0),
                ]);

                $aoPlann->insert([
                    'NO_AO' => $idAO,
                    'NO_PO' => $idLigne,
                    'DTE' => $post['DELAI'],
                    'QTE' => $post['QTE']??'',
                ]);
                /** @phpstan-ignore-next-line */
                $idForCs = ChampSupp::autoCompletCodeEnr($idAO, $idLigne, 'AO_LIGNE');
                ChampSupp::ajouterCS($post, $this->pdo, $idForCs);
            }
            return new Response(443, [
                
            ], (string) \json_encode([
                'statut' => 'O',
                'path' => $this->router->generateUri('Consultation.Consultation.details', ['idAO' => $idAO, 'onglet' => 'Ligne']),
            ]));
        } else {
            return $this->renderer->render('@popup-erreur/ErreurCreation', [
                'ErreurValid' => $validator->getError(),
                'desactiveRow' => true,
            ]);
        }
    }
    
    public function deleteAction()
    {
        $idAO = $this->request->getAttribute('idAO');
        $idLigne = $this->request->getAttribute('idLigne');
        
        $aoFourEntity = new AoLigne($this->pdo);
        $infoLigne = $aoFourEntity->find([
            'NO_AO' => $idAO,
            'NO_PO' => $idLigne,
        ]);
        
        sql::deleteMemos($this->pdo, $infoLigne['NM_DCOMP']);
        sql::deleteMemos($this->pdo, $infoLigne['NM_ST_AV']);
        
        $aoFourEntity->delete([
            'NO_AO' => $idAO,
            'NO_PO' => $idLigne,
        ]);
        
        return new Response(200, [], (string) \json_encode([]));
    }
    
    public function listeLigneDaImportAction() : string
    {
        $idAO = $this->request->getAttribute('idAO');
        $post = $this->request->getParsedBody();
        
        $listeSelectInput = [];
        if (!$post) {
            $post['tri_NO_DA'] = 'desc';
            $post['tri_NO_PO'] = 'asc';
        } else {
            foreach ($post as $key => $value) {
                if (strpos($key, 'save_selected_da_') === 0) {
                    $listeSelectInput[$key] = $value;
                }
            }
        }
        
        $paginator = new \Helpers\Pagination\PaginatorGestion();
        $paginator->generate('10', 'NO_DA');
        
        $gestionConsu = new GestionConsultation($this->pdo);
        $consultation = $gestionConsu->getInfoAo($idAO);

        if ($consultation['TYPE_SG'] == 'G') {
            $societeRepo = new Societe($this->pdo);
            $socTmp = $societeRepo->getListeSocByGrpSoc($consultation['CODE_STE']);

            $listeSoc = [];
            foreach ($socTmp as $soc) {
                $listeSoc[] = $soc['CODE_STE'];
            }

            $socConsult = implode("','", $listeSoc);
        } else {
            $socConsult = $consultation['CODE_STE'];
        }
        
        $listeDA = $gestionConsu->getListeLigneDa($post, $socConsult);
        
        $infopagination = PaginatorGestion::getInfoPagination();
        
        
        $aoEvent = new AoEvent($this->pdo);
        $AOEventCreat = $aoEvent->getNameCreate($idAO);
        
        $trad = $this->getTranslationService();
        
        ArianeSub::generate(1, 0, $trad->t('Import DA'), $_SERVER['REQUEST_URI'], 1);
        
        return $this->renderer->render('@Consultation/Articles/listeLigneDaImport', [
            'menuActive'        => Session::verifySessionTypeMenuTop(MenuTopEnum::P2P)? 'eproc':'Consultations',
            'menuLeft'          => 'gestionAO',
            'idAO'              => $idAO,
            'listeDA'           => $listeDA,
            'post'              => $post,
            'consultation'      => $consultation,
            'AOEventCreat'      => $AOEventCreat,
            'CODE_STE'          => $_SESSION["Session_SocUsr"],
            'listeSelectInput'  => $listeSelectInput,
            'infoPagination'    => $infopagination,
        ]);
    }
    
    public function ajaxAddArticleAction()
    {
        $idAO = $this->request->getAttribute('idAO');
        $post = $this->request->getParsedBody();
        
        $daLigne = new DaLigne($this->pdo);
        $aoLigne = new AoLigne($this->pdo);
        $gestionConsultation = new GestionConsultation($this->pdo);
        $idLigne = (int)$gestionConsultation->getMaxLigneAo($idAO)['MAX_PO'];

        $aoEntet = new AoEntet($this->pdo);
        $infoEntet = $aoEntet->find($idAO);
        
        if (!$post) {
            $post['tri_NO_DA'] = 'desc';
            $post['tri_NO_PO'] = 'asc';
        } else {
            foreach (array_keys($post) as $key) {
                if (strpos($key, 'save_selected_da_') === 0) {
                    $idLigne = $idLigne + 1;
                    $codeDa = substr($key, 17);
                    $codeSplit = explode('_', $codeDa);
                    $infoLigneDa = $daLigne->find(['NO_DA' => $codeSplit[0], 'NO_PO' => $codeSplit[1]]);

                    $contentMemo = sql::getMemo($this->pdo, $infoLigneDa['NM_DCOMP']);
                    $NM_DCOMP = sql::updateMemo($this->pdo, '', $contentMemo);
                    
                    $aoLigne->insert([
                        'NO_AO' => $idAO,
                        'NO_PO' => $idLigne,
                        'NO_DA' => $infoLigneDa['NO_DA'],
                        'NO_PO_DA' => $infoLigneDa['NO_PO'],
                        'CODE_ART' => $infoLigneDa['CODE_ART'],
                        'DES' => $infoLigneDa['DES_SOMM'],
                        'NM_DCOMP' => $NM_DCOMP,
                        'QTE' => $infoLigneDa['QTE_DEM'] - $infoLigneDa['DEJA_COMM'],
                        'UNITE' => $infoLigneDa['UNITE'],
                        'DELAI' => $infoLigneDa['DTELIVSOU'],
                        'BUDGET' => $infoLigneDa['BUDGET'],
                        'PRIX_REF' => $infoLigneDa['PU'],
                        'SSFAMILLE' => $infoLigneDa['SSFAM'],
                        'COD_FAB' => $infoLigneDa['COD_FAB'],
                        'COD_GAM' => $infoLigneDa['COD_GAM'],
                        'REF_FAB' => $infoLigneDa['REF_FAB'],
                        'CODE_STE' => $infoEntet['CODE_STE'],
                    ]);
                }
            }
        }
        
        return new Response(200, [], (string) \json_encode([]));
    }
       
    
    public function ajaxUpdateAPRIXAction()
    {
        $idAO = $this->request->getAttribute('idAO');
        $post = $this->request->getParsedBody();
        
        $aoQstQ = new AoQstTh($this->pdo);
        $aoQstQ->update(['POIDS' => $post['POIDS_APRIX']], ['NO_AO' => $idAO, 'ID_THEME' => 'APRIX']);
        
        return new response(200);
    }

    public function ajaxChangementSurLigneAction(): Response
    {
        $post = $this->request->getParsedBody();
        $trad = $this->getTranslationService();

        $validator = $this->createValidator();

        $validator->isFloat($trad->t('Prix référence'), $post['PRIX'], constante::formatPU);
        $validator->isFloat($trad->t('Quantité'), $post['QTE'], Constante::formatQTE);
        
        if ($validator->isValid()) {
            if (isset($post['QTE'])) {
                $toUpdate = 'QTE';
            } elseif (isset($post['PRIX_REF'])) {
                $toUpdate = 'PRIX_REF';
                $post['PRIX_REF'] = floatval($post['PRIX_REF']);
            } else {
                return new Response(400, [], (string) $this->renderer->render('@popup-erreur/ErreurCreation', [
                    'ErreurValid' => $trad->t('Merci de bien vouloir renseigner une quantité ou un prix.'),
                    'desactiveRow' => true,
                ]));
            }
            
            $AoLigne = new AoLigne($this->pdo);
            $update = $AoLigne->update([$toUpdate => $post[$toUpdate] ?? 0], [
                'NO_AO' => $post['NO_AO'],
                'NO_PO' => $post['NO_PO'],
            ]);
    
            if (!$update) {
                $errorMsg = $toUpdate === 'QTE'
                            ? $trad->t('Une erreur est survenue lors du changement de la quantité.')
                            : $trad->t('Une erreur est survenue lors du changement du prix.');
                return new Response(400, [], (string) $this->renderer->render('@popup-erreur/ErreurCreation', [
                    'ErreurValid' => $errorMsg,
                    'desactiveRow' => true,
                ]));
            }
            
            return new Response(200, [], (string) \json_encode([]));
        } else {
            return new Response(400, [], (string) $this->renderer->render('@popup-erreur/ErreurCreation', [
                'ErreurValid' => $validator->getError(),
                'desactiveRow' => true,
            ]));
        }
    }

    public function suppressionMultiLignesAction(): Response
    {
        $post = $this->request->getParsedBody();
        $idAO = $this->request->getAttribute('idAO');
        $trad = $this->getTranslationService();
        $AoLigne = new AoLigne($this->pdo);

        $liste = [];
        foreach ($post['selected_line']??[] as $NO_PO) {
            if ($AoLigne->find(['NO_AO' => $idAO, 'NO_PO' => $NO_PO])) {
                $AoLigne->delete(['NO_AO' => $idAO, 'NO_PO' => $NO_PO]);
            } else {
                $liste[] = $NO_PO;
            }
        }

        if (!$post['selected_line']) {
            $error = $trad->t('Aucune ligne n\'est sélectionnée.');
        }

        if (count($liste) > 0) {
            $liste = implode(',', $liste);
            $error = Trad::strBuild($trad->t('La / Les ligne(s) @1@ n\'a / n\'ont pas été trouvée(s) sur cette consultation.'), $liste);
        }

        if (isset($error)) {
            return new Response(400, [], (string) $this->renderer->render('@popup-erreur/ErreurCreation', [
                'ErreurValid' => (string) $error,
                'desactiveRow' => true,
            ]));
        }

        return new Response();
    }
}
