<?php


namespace Modules\DemandeAchat\Controller;

use Entity\Model\Centre;
use Entity\Model\DaPlann;
use Entity\Model\Hastutil;
use Entity\Model\Paravrac;
use Entity\Model\Societe;
use Helpers\Outil\ArrayHelper;
use Helpers\Outil\Roles;
use Helpers\Pagination\PaginatorGestion;
use Helpers\QueryBuilder\EntityTool;
use Modules\DemandeAchat\Outil\FormArray;
use Modules\GlobalApplication\Controller\AbsExportController;
use Helpers\Ariane\Ariane;
use Helpers\Ariane\ArianeSub;
use Entity\Model\DaEntet;
use Entity\Model\DaLigne;
use Helpers\ChampsSupplementaire\ChampSupp;
use Helpers\Outil\Sql;
use Modules\DemandeAchat\MenuContextuel\GestionMenuContextuel;
use Modules\DemandeAchat\Repository\DemandeAchat;
use Modules\DemandeAchat\Service\GestionDemandeAchatService;
use Modules\Suivi\Repository\SuiviDaRepo;

class GestionDemandeAchatController extends AbsExportController
{
    /**
     * @var array<mixed>
     */
    private array $droits;

    public function init(): void
    {
        $paravrac = new Paravrac($this->pdo);
        $this->droits = [
            'DA_CreatModif' => $_SESSION['DA_CreatModif'],
            'HA_DA_TTDM' => Roles::droitsUtilisateur($this->pdo, 'HA_DA_TTDM'),
            'HA_DA_TTCE' => Roles::droitsUtilisateur($this->pdo, 'HA_DA_TTCE'),
            'HA_DA_TTCT' => Roles::droitsUtilisateur($this->pdo, 'HA_DA_TTCT'),
            'HA_DA_VISU' => Roles::droitsUtilisateur($this->pdo, 'HA_DA_VISU'),
            'HA_CA_CMV' => Roles::droitsUtilisateur($this->pdo, 'HA_CA_CMV'),
            'DEMANDEUR' => Sql::boolSql(
                (new Hastutil($this->pdo))
                    ->find($_SESSION['Session_Login'])['DEMAND']
            ),
            'DA_AFF_CODE_ART' => $paravrac->getGeneric('DA_AFF_CODE_ART') == 'O',
            'DA_AFF_CODE_REF_FAB' => $paravrac->getGeneric('DA_AFF_CODE_REF_FAB') == 'O',
            'DA_AFF_REF_ART_FOUR' => $paravrac->getGeneric('DA_AFF_REF_ART_FOUR') == 'O',
            'ACTIVATION_BPA'    => $paravrac->getGeneric('ACTIVATION_BPA') == 'O',
        ];
    }

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

        $purchaseRequests = [];
        $param = [];

        (new PaginatorGestion())
            ->generate(0, 'DA_ENTET.NO_DA');

        $menuContextuel = new GestionMenuContextuel($this->pdo, $this->router, $trad);

        // périmètres
        if (!$this->droits['HA_DA_TTDM']) {
            // si HA_DA_TTDM == false => uniquement DA dont user est demandeur
            $post['demandeur'] = $_SESSION['Session_Login'];
            $param['demandeur_LOCK'] = true;
        }

        if (!$post || ($post['tri_NO_DA'] ?? '' == '')) {
            $post['tri_NO_DA'] = 'desc';
        }

        $purchaseRequests = (new DemandeAchat($this->pdo))->listeDemandeAchat($post);
        foreach ($purchaseRequests as &$pr) {
            $pr['menuContextuel'] = $menuContextuel->generate($pr, 'GestionDemandeAchat');
        }

        /* Filtre avancées */
        $advancedFilters = (new GestionDemandeAchatService(
            $this->pdo,
            $this->getTranslationService(),
        ))->setAdvancedFilters($post);

        Ariane::generate(0, $trad->t('Gestion'), $post, PaginatorGestion::getNbrArticle());
        ArianeSub::init();

        $infoPagination = PaginatorGestion::getInfoPagination();

        $formArray = FormArray::getFormArrays($trad);

        return $this->renderer->render('@DemandeAchat/Gestion/index', [
            'menuActive' => 'CollecteBesoins',
            'post' => $post,
            'infoPagination' => $infoPagination,
            'filtreAvance' => $advancedFilters['filtreAvance'],
            'initFiltreAvance' => $advancedFilters['initFiltreAvance'],
            'listeDA' => $purchaseRequests,
            'listeTypeChiffExec' => $formArray['typeChiffExec'],
            'listeEtatDA' => $formArray['listeEtatDA'],
            'tabTypeMarchePublic' => $formArray['tabTypeMarchePublic'],
            'tabPeriodicite' => $formArray['tabPeriodicite'],
            'tabPeriode' => $formArray['tabPeriode'],
            'tabJoursAppli' => $formArray['tabJoursAppli'],
            'tabTypeDate' => $formArray['tabTypeDate'],
            'user' => (new Hastutil($this->pdo))->find($_SESSION['Session_Login']),
            'societe' => (new Societe($this->pdo))->find($_SESSION['Session_SocUsr']),
            'centreLivraison' => (new Centre($this->pdo))->find($_SESSION['Session_CodeCtrLivraison']),
            'nombreResultat' => count($purchaseRequests),
            'droits' => $this->droits,
            'param' => $param,
        ]);
    }

    public function detailEntetAction(): string
    {
        $purchaseRequest = $this->request->getAttribute('idDA');

        $detailDA = [];
        $listeLigneDemandeAchat = [];

        $repository = new DemandeAchat($this->pdo);

        $listeLigneDemandeAchat = $repository->listeLigneDemandeAchat($purchaseRequest);
        $detailDA = $repository->demandeAchat($purchaseRequest);
        
        $formArray = FormArray::getFormArrays(
            $this->getTranslationService(),
        );

        return $this->renderer->render('@DemandeAchat/Gestion/detailDemandeAchat', [
            'detailDA' => $detailDA,
            'listeLigneDemandeAchat' => $listeLigneDemandeAchat,
            'id' => $purchaseRequest,
            'typeChiffExec' => $formArray['typeChiffExec'],
            'tabTypeMarchePublic' => $formArray['tabTypeMarchePublic'],
            'tabPeriodicite' => $formArray['tabPeriodicite'],
            'tabPeriode' => $formArray['tabPeriode'],
            'tabJoursAppli' => $formArray['tabJoursAppli'],
            'tabTypeDate' => $formArray['tabTypeDate'],
            'droits' => $this->droits,
        ]);
    }

    public function detailLigneAction():string
    {
        $purchaseRequest = $this->request->getAttribute('idDA');
        $idLigne = $this->request->getAttribute('idLigne');

        $ligne = (new DemandeAchat($this->pdo))->listeLigneDemandeAchat($purchaseRequest, $idLigne);

        return $this->renderer->render('@DemandeAchat/Gestion/detailLigne', [
            'detailDA' => ['NO_DA' => $purchaseRequest],
            'ligneDA' => $ligne,
        ]);
    }

    public function popupPlanningAction(): string
    {
        $da = $this->request->getAttribute('da');
        $line = $this->request->getAttribute('line');

        $listePlanning = (new DaPlann($this->pdo))
            ->findAll(
                [
                    'NO_DA' => $da,
                    'NO_PO' => $line
                ],
                [],
                ['tri_DTE_LIV' => 'ASC']
            );

        $ligne = (new DaLigne($this->pdo))
            ->find([
                'NO_DA' => $da,
                'NO_PO' => $line
            ]);

        return $this->renderer->render('@Commande/GareDeTriage/popupPlanning', [
            'listPlanning' => $listePlanning,
            'ligne' => $ligne,
        ]);
    }

    public function popupExportAction(): string
    {
        $origin = $this->request->getAttribute('origin') ?? 0;

        $post['multiSelectexportCdeOBLI1'] = 'DA_ENTET.NO_DA';
        $post['multiSelectexportCdeOBLI2'] = 'DA_LIGNE.NO_PO';

        $tab = $this->_exportGetTab();

        if ($origin == 'DA' && !Roles::droitsUtilisateur($this->pdo, 'HA_CA_VIPX')) {
            unset($tab['DA_ENTET.TOTAL_DA']);
            unset($tab['DA_ENTET.TOTAL_DA_TTC']);

            unset($tab['DA_LIGNE.PU']);
            unset($tab['DA_LIGNE.MNT_LIG']);
        }

        return $this->renderer->render('@GlobalApplication/Popup/popupExport', [
            'pathExport' => $this->router->generateUri(
                'DemandeAchat.GestionDemandeAchat.exportDemandeAchat',
                ['origin' => $origin]
            ),
            'formFilter' => ($origin != 'DA'
                ? 'filtre_suivi'
                : 'filtre_demandeAchat'
            ),
            'coloneExport' => $tab,
            'tabObli' => ['DA_ENTET.NO_DA', 'DA_LIGNE.NO_PO'],
            'post' => $post,
            // 'modeDebug' => true,
        ]);
    }

    public function exportDemandeAchatAction(): string
    {
        $post = $this->request->getParsedBody();
        $origin = $this->request->getAttribute('origin');
        $trad = $this->getTranslationService();

        // Column ambigu
        $post['tri_DA_ENTET.NO_DA'] = $post['tri_NO_DA'] ?? null;
        unset($post['tri_NO_DA']);
        $post['tri_DA_ENTET.CODE_STE'] = $post['tri_CODE_STE'] ?? null;
        unset($post['tri_CODE_STE']);
        unset($post['tri_ETAT']);

        $mapFielList = $this->extractConfig(
            $post,
            $this->_exportGetTab(),
            'DA_LIGNE'
        );

        $listCSEnteteSchema = $this->getCsSchema('DA_ENTET', $mapFielList->listeCSEntete);
        $listCSLigneSchema = $this->getCsSchema('DA_LIGNE', $mapFielList->listeCSLigne);

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

        //___________________
        // Fetch data

        if ($origin == 'DA') {
            $suiviCdeRepo = new SuiviDaRepo($this->pdo, $this->router, $trad);
            $listeDemandeAchat = $suiviCdeRepo->getListe(
                $post,
                [],
                implode(',', $mapFielList->listeEntityField)
            );
        } else {
            $DemandeAchat = new DemandeAchat($this->pdo);
            $listeDemandeAchat = $DemandeAchat->listeDemandeAchat(
                $post,
                implode(',', $mapFielList->listeEntityField)
            );
        }

        $mapChampSup = array_column(array_map(
            function ($item) {
                return $item + ['index' => implode(':', [
                    $item['COD_TAB'],
                    $item['COD_ENR'],
                    $item['NUM_FIX'],
                ])];
            },
            $this->listChampSupForEntityList(
                $listeDemandeAchat,
                'DA_ENTET.NO_DA',
                'DA_LIGNE.NO_PO',
                $listCSEnteteSchema,
                $listCSLigneSchema
            )
        ), null, 'index');

        //___________________
        // Format fields

        $trad = $this->getTranslationService();
        $mapArchiEntet = (new DaEntet($this->pdo))->getArchitecture($trad);
        $mapArchiLigne = (new DaLigne($this->pdo))->getArchitecture($trad);
        $listeDemandeAchat = array_map(function ($row) use ($mapArchiEntet, $mapArchiLigne, $trad) {
            foreach ($row as $key => $value) {
                if (str_starts_with($key, 'DA_ENTET.')) {
                    $field = explode('.', $key)[1];
                    $row[ $key ] = EntityTool::formatFieldDisplay(
                        $mapArchiEntet[ $field ] ?? [],
                        $value,
                        $trad
                    );
                    continue;
                }
                if (str_starts_with($key, 'DA_LIGNE.')) {
                    $field = explode('.', $key)[1];
                    $row[ $key ] = EntityTool::formatFieldDisplay(
                        $mapArchiLigne[ $field ] ?? [],
                        $value,
                        $trad
                    );
                    continue;
                }
            }
            return $row;
        }, $listeDemandeAchat);

        // Join & format ChampSup
        foreach ($listeDemandeAchat as &$ligne) {
            foreach ($listCSEnteteSchema as $schema) {
                $ligne[ 'CS_EXTENSION_ENTETE' . $schema['NUM_FIX'] ] = ChampSupp::formatValue(
                    $schema['TYPE'],
                    $mapChampSup[implode(':', [
                        $schema['COD_TAB'],
                        ChampSupp::autoCompletCodeEnr($ligne['DA_ENTET.NO_DA']),
                        $schema['NUM_FIX'],
                    ])]['VALEUR'] ?? '',
                    $trad
                );
                if ($schema['TYPE'] == 'MEMO') {
                    $ligne[ 'CS_EXTENSION_ENTETE' . $schema['NUM_FIX'] ] = Sql::getMemo(
                        $this->pdo,
                        $ligne[ 'CS_EXTENSION_ENTETE' . $schema['NUM_FIX'] ]
                    );
                }
            }
            foreach ($listCSLigneSchema as $schema) {
                $ligne[ 'CS_EXTENSION_LIGNE' . $schema['NUM_FIX'] ] = ChampSupp::formatValue(
                    $schema['TYPE'],
                    $mapChampSup[implode(':', [
                        $schema['COD_TAB'],
                        ChampSupp::autoCompletCodeEnr(
                            $ligne['DA_ENTET.NO_DA'],
                            $ligne['DA_LIGNE.NO_PO'],
                        ),
                        $schema['NUM_FIX'],
                    ])]['VALEUR'] ?? '',
                    $trad
                );
                if ($schema['TYPE'] == 'MEMO') {
                    $ligne[ 'CS_EXTENSION_LIGNE' . $schema['NUM_FIX'] ] = Sql::getMemo(
                        $this->pdo,
                        $ligne[ 'CS_EXTENSION_LIGNE' . $schema['NUM_FIX'] ]
                    );
                }
            }
        }
        unset($ligne);
        
        //___________________
        // Send

        \Helpers\ExportTo\Outils::gestionEmailAsync2(
            'export_DA_' . date('Ymd'),
            array_map(function ($data) use ($mapFielList) {
                return ArrayHelper::sortKeyByArray($data, $mapFielList->arrayMultiSelect);
            }, $listeDemandeAchat),
            $this->JWTKEY,
            $this->router,
            $this->getTranslationService(),
            ArrayHelper::sortKeyByArray(
                $this->getEntityTitle($mapArchiEntet, 'DA_ENTET', $mapFielList->arrayMultiSelect)
                + $this->getEntityTitle($mapArchiLigne, 'DA_LIGNE', $mapFielList->arrayMultiSelect)
                + $this->getChampSupTitle($listCSEnteteSchema, $listCSLigneSchema),
                $mapFielList->arrayMultiSelect
            )
        );

        return 'ok';
    }

    /**
     * @return string[] label indexed by export key
     */
    private function _exportGetTab(): array
    {
        $trad = $this->getTranslationService();
        $tab = [];
        $listeChpDA = (new DaEntet($this->pdo))->getArchitecture($trad);
        foreach ($listeChpDA as $key => $value) {
            $tab['DA_ENTET.' . $key] = $trad->t('Entête') . ' : ' . $value['nomChamp'];
        }

        $champSupp = new ChampSupp($this->pdo);
        $listeTmpCS = $champSupp->getInfoCS('DA_ENTET');

        foreach ($listeTmpCS as $cs) {
            $tab['CS_EXTENSION_ENTETE' . $cs['NUM_FIX']] = $trad->t('Entête') . ' : ' . $trad->t('CS') . ' - ' . $cs['NOM'];
            $tab['CS_EXTENSION_ENTETE' . $cs['NUM_FIX']] = $trad->t('Entête') . ' : ' . $trad->t('CS') . ' - ' . $cs['NOM'];
        }

        $listeChpDALigne = (new DaLigne($this->pdo))->getArchitecture($trad);
        foreach ($listeChpDALigne as $key => $value) {
            $tab['DA_LIGNE.' . $key] = $trad->t('Ligne') . ' : ' . $value['nomChamp'];
            $tab['DA_LIGNE.' . $key] = $trad->t('Ligne') . ' : ' . $value['nomChamp'];
        }

        $listeTmpCS = $champSupp->getInfoCS('DA_LIGNE');

        foreach ($listeTmpCS as $cs) {
            $tab['CS_EXTENSION_LIGNE' . $cs['NUM_FIX']] = $trad->t('Ligne') . ' : ' . $trad->t('CS') . ' - ' . $cs['NOM'];
        }

        return $tab;
    }
}
