<?php
namespace Modules\Suivi\Controller;

use Entity\Model\OxaSuiviRequete;
use Entity\Model\SbsEnte;
use Entity\Model\SbsLign;
use Helpers\Ariane\Ariane;
use Helpers\Filter\FiltreAvance\Generator;
use Helpers\Outil\Date;
use Helpers\Outil\Roles;
use Helpers\Outil\Sql;
use Helpers\Pagination\PaginatorGestion;
use Helpers\Parametres\Constante;
use Modules\Suivi\MenuContextuel\SuiviBsContextuel;
use Modules\Suivi\Repository\SuiviBSRepo;
use Modules\Suivi\Service\RuptureService;
use Modules\Suivi\Service\SuiviService;
use Skeleton\Controller\Controller;

class SuiviBSController extends Controller
{
    public SuiviBsRepo $suiviBSRepo;
    public SuiviService $serviceSuivi;
    /**
     * @var array<mixed> $parametrage
     */
    public $parametrage;

    public function init() : void
    {
        $this->suiviBSRepo  = new SuiviBSRepo($this->pdo, $this->router, $this->getTranslationService());

        $this->serviceSuivi = new SuiviService($this->pdo, $this->getTranslationService());
        $this->parametrage  = $this->serviceSuivi->getParametrageSuivi();
    }

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

        // valeur par defaut
        if (!$post) {
            $post['filter_egal_CODE_STE']   = $_SESSION["Session_SocUsr"];
        }

        SuiviService::loadFavorisFilter($this->pdo, $post);
        
        $listeRequete = (new OxaSuiviRequete($this->pdo))->fetchAll([], ['filter_egal_ID_USER' => $_SESSION['id_user'], 'filter_egal_TYPE_SUIVI' => 'BS']);
        
        (new PaginatorGestion())->generate(0, 'SBS_ENTE.NO_BS');

        $listeBS = $this->suiviBSRepo->getListe($post, []);

        /** Pagination */
        $nombreArticle  = PaginatorGestion::getNbrArticle();
        $infopagination = PaginatorGestion::getInfoPagination();

        /** Gestion des ruptures */
        $ruptureService = new RuptureService($this->pdo);
        $listeRupture   = $ruptureService->getListeRupture($listeBS, $post);
        
        $allRupture = [];
        foreach ($listeRupture as $kRupture => $rupture) {
            $allRupture[$kRupture] = $this->suiviBSRepo->getListe($post, $rupture)['RUPTURE_TOTAL']??0;
        }
        
        /** Menu contextuel */
        $menuContextuel = new SuiviBsContextuel($this->pdo, $this->router, $this->getTranslationService());
        foreach ($listeBS as &$cde) {
            $cde['menuContextuel'] = $menuContextuel->generate($cde, 'divRefresh');
        }
        
        Ariane::generate(0, $trad->t('Suivi des bons de sortie'), $post, $nombreArticle);
        
        /** Init des valeurs de l'écran */
        $listeStatutFilter = [
            ''                      => '',
            'A_VALIDER'             => $trad->t('A valider'),
            'VALIDE'                => $trad->t('Validé'),
        ];

        $listeRupture = [
            ''                      => $trad->t('Pas de rupture'),
            'SBS_ENTE.SITE'         => $trad->t('Site'),
            'SBS_ENTE.DEST'         => $trad->t('Destinataire'),
            'SBS_ENTE.CODE_STE'     => $trad->t('Société'),
            'SBS_ENTE.DTE_VALID'    => $trad->t('Date de validation'),
        ];

        $filtreAvance = new Generator($post);
        $filtreAvance->setFiltre('SBS_ENTE.DTE_VALID', 'date', $trad->t('Date de validation'), '', '', '');
        $filtreAvance->setFiltre('SBS_LIGN.ART', 'liste', $trad->t('Article'), '', 'Ajax.liste.articles', 'articles');

        return $this->renderer->render('@suivi/BonsDeSortie/SuiviBS', [
            'menuActive'        => 'eproc',
            'post'              => $post,
            'source'            => 'BS',
            'listeBs'           => $listeBS,
            'infoPagination'    => $infopagination,
            'parametrage'       => $this->parametrage,
            'infoRupture'       => $allRupture,
            'listeStatutFilter' => $listeStatutFilter,
            'listeRupture'      => $listeRupture,

            'initFiltreAvance'  => $filtreAvance->getInit(),
            'filtreAvance'      => $filtreAvance->getFiltres(),

            'sessionSoc'        => $_SESSION["Session_SocUsr"],
            'sessionUsr'        => $_SESSION["Session_Login"],

            'listeRequete'      => $listeRequete,
            'typeSuivi'         => 'BS',
        ]);
    }

    public function ajaxDetailsAction() : string
    {
        $idDoc      = $this->request->getAttribute('idDoc');
        $source     = $this->request->getAttribute('source');
        
        return $this->renderer->render('@suivi/BonsDeSortie/ajaxDetailsBs', [
            'infoEntete'    => $this->suiviBSRepo->getInfoEntete($idDoc),
            'ligneBs'       => $this->suiviBSRepo->getLiseLigne($idDoc),
            'source'        => $source,
            'idDoc'         => $idDoc,
            'parametrage'   => $this->parametrage,
        ]);
    }

    public function popupExportAction() : string
    {
        $post = $this->request->getParsedBody();
        $tab = [];
        $trad = $this->getTranslationService();
        $tradArray = [
            'Entête' => $trad->t('Entête'),
            'Ligne'  => $trad->t('Ligne'),
        ];

        $listeChp = (new SbsEnte($this->pdo))->getArchitecture($this->getTranslationService());
        foreach ($listeChp as $key => $value) {
            $tab['SBS_ENTE.'.$key] = $tradArray['Entête'].' : '.$value['nomChamp'];
        }

        $listeChp = (new SbsLign($this->pdo))->getArchitecture($this->getTranslationService());
        foreach ($listeChp as $key => $value) {
            $tab['SBS_LIGN.'.$key] = $tradArray['Ligne'].' : '.$value['nomChamp'];
        }

        $post['multiSelectexportBsOBLI1'] = 'SBS_ENTE.NO_BS';
        $post['multiSelectexportBsOBLI2'] = 'SBS_LIGN.NO_LIG';

        if (!Roles::droitsUtilisateur($this->pdo, 'HA_CA_VIPX')) {
            unset($tab['SBS_ENTE.TOT_BS']);
            unset($tab['SBS_LIGN.PRIX_SORT']);
        }

        return $this->renderer->render('@GlobalApplication/Popup/popupExport', [
            'pathExport'    => $this->router->generateUri('Suivi.SuiviBs.export'),
            'formFilter'    => 'filtre_suivi',
            'coloneExport'  => $tab,
            'post'          => $post,
            'tabObli'       => ['SBS_ENTE.NO_BS', 'SBS_LIGN.NO_LIG'],
            'modeDebug'     => false,
        ]);
    }

    public function exportAction() : string
    {
        ini_set('memory_limit', '500M');

        $post = $this->request->getParsedBody();
        
        $arrayMultiSelect = array_filter($post, function ($k) {
            return (bool)stristr($k, 'multiSelect');
        }, ARRAY_FILTER_USE_KEY);

        // Filter any unauthorized fields
        $arrayMultiSelect = array_intersect(
            $arrayMultiSelect,
            array_keys($this->exportGetTab())
        );

        $listeSelectTmp = [];

        foreach ($arrayMultiSelect as $key => &$val) {
            $explode = explode('.', $val);
            
            if ($explode[0] == 'SBS_LIGN') {
                $listeSelectTmp[] = $val.' '.$explode[0].$explode[1];
            } else {
                $listeSelectTmp[] = $val;
            }
        }
        
        $listeSelect = implode(',', $listeSelectTmp);

        if (empty($post['okFilter'])) {
            $post= [];
        }

        $suiviBsRepo    = new SuiviBSRepo($this->pdo, $this->router, $this->getTranslationService());
        $listeBs        = $suiviBsRepo->getListe($post, [], $listeSelect);
 
        $listeChpEnt    = (new SbsEnte($this->pdo))->getArchitecture($this->getTranslationService());
        $listeChpLign   = (new SbsLign($this->pdo))->getArchitecture($this->getTranslationService());

        $trad = $this->getTranslationService();

        //On récupère la liste des champs DATE & BOOL afin de les traités après
        $listeChpsDate      = [];
        $listeChpsBool      = [];
        $listeChpsMemo      = [];
        $listeChpsNumber    = [];
        $keyValue           = [];
        foreach ($listeChpEnt as $key => $value) {
            $keyValue['SBS_ENTE.'.$key] = $value['nomChamp'];
            
            if (isset($value['type'])) {
                if ($value['type']=='DATE') {
                    $listeChpsDate[] = $key;
                }
                if ($value['type']=='RADIO') {
                    $listeChpsBool[] = $key;
                }
                if ($value['type']=='MEMO') {
                    $listeChpsMemo[] = $key;
                }

                if (isset($value['formatted']) && $value['formatted'] === true) {
                    if ($value['type'] === 'TEXT') {
                        $listeChpsNumber[] = $key;
                    }
                }
            }
        }
        
        foreach ($listeChpLign as $key => $value) {
            $keyValue['SBS_LIGN.'.$key] = $value['nomChamp'];
            
            $key = 'SBS_LIGN'.$key;
            
            if (isset($value['type'])) {
                if ($value['type']=='DATE') {
                    $listeChpsDate[] = $key;
                }
                if ($value['type']=='RADIO') {
                    $listeChpsBool[] = $key;
                }
                if ($value['type']=='MEMO') {
                    $listeChpsMemo[] = $key;
                }

                if (isset($value['formatted']) && $value['formatted'] === true) {
                    if ($value['type'] === 'TEXT') {
                        $listeChpsNumber[] = $key;
                    }
                }
            }
        }

        $params = [
            'NB_DECIMAL_PU' => Constante::PUDECIMAL
        ];

        $oui = $trad->t('Oui');
        $non = $trad->t('Non');
        foreach ($listeBs as &$ligne) {
            foreach ($listeChpsDate as $chps) {
                if (isset($ligne[$chps])) {
                    $ligne[$chps] = Date::dateConverte($ligne[$chps]);
                }
            }
            
            foreach ($listeChpsBool as $chps) {
                if (isset($ligne[$chps])) {
                    $ligne[$chps] = Sql::toBool($ligne[$chps]) ? $oui : $non;
                }
            }
            
            foreach ($listeChpsMemo as $chps) {
                if (isset($ligne[$chps])) {
                    $ligne[$chps] = Sql::getMemo($this->pdo, $ligne[$chps]);
                }
            }

            foreach ($listeChpsNumber as $chps) {
                if (isset($ligne[$chps])) {
                    $ligne[$chps] = number_format($ligne[$chps], $params['NB_DECIMAL_PU'], '.', ' ');
                }
            }
        }

        $tab = [];
        //On génère l'entete du fichier d'export
        foreach ($arrayMultiSelect as $value) {
            $tab[$value] = $keyValue[$value];
        }

        \Helpers\ExportTo\Outils::gestionEmailAsync2(
            "export_BS_".date('Ymd'),
            $listeBs,
            $this->JWTKEY,
            $this->router,
            $this->getTranslationService(),
            $tab
        );
        
        return 'ok';
    }

    /**
     * Return a map of exportable entity definitions (or ChampSupp) indexed by their export key
     * @return mixed[]
     */
    private function exportGetTab()
    {
        $tab = [];
        $listeChp = (new SbsEnte($this->pdo))->getArchitecture($this->getTranslationService());
        foreach ($listeChp as $key => $value) {
            $tab['SBS_ENTE.'.$key] = $value;
        }

        $listeChp = (new SbsLign($this->pdo))->getArchitecture($this->getTranslationService());
        foreach ($listeChp as $key => $value) {
            $tab['SBS_LIGN.'.$key] = $value;
        }

        return $tab;
    }
}
