<?php
namespace Modules\Commande\Controller;

use Helpers\Outil\ArrayHelper;
use Helpers\Parametres\Constante;
use Helpers\Outil\Roles;
use Helpers\QueryBuilder\EntityTool;
use Modules\Reception\Repository\GestionBR;
use Modules\Commande\Repository\Commande;
use Skeleton\Controller\Controller;
use Entity\Model\CaEntet;
use GuzzleHttp\Psr7\Response;
use Entity\Model\CaLigne;
use Helpers\ChampsSupplementaire\ChampSupp;
use Modules\Suivi\Repository\SuiviCdeRepo;
use Helpers\Outil\StringHelper;

class ExportCommandeController extends Controller
{
    /**
     * @return Response|void
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    public function init()
    {
        // TODO : move to Rules
        if (!\Helpers\Roles\Predispatch::connectRole()) {
            return $this->redirect($this->contenaire->get('base') . 'index.php');
        }
    }
    
    public function popupExportAction() : string
    {
        $origin = $this->request->getAttribute('origin') ?? 'ANY';

        $tab = $this->getLabelField($this->exportGetTab());
        
        $post['multiSelectexportCdeOBLI1'] = 'CA_ENTET.NO_CDE';
        $post['multiSelectexportCdeOBLI2'] = 'CA_LIGNE.NO_PO';

        asort($tab);

        if ($origin == 'SUIVI' && !Roles::droitsUtilisateur($this->pdo, 'HA_CA_VIPX')) {
            unset($tab['CA_ENTET.TOT_CDE']);
            unset($tab['CA_ENTET.TOT_CDEHT']);
            unset($tab['CA_ENTET.TOT_TTC']);
            unset($tab['CA_ENTET.DEJA_FAC']);

            unset($tab['CA_LIGNE.PU']);
            unset($tab['MONTANT_LIGNE_HT']);
        }

        return $this->renderer->render('@GlobalApplication/Popup/popupExport', [
            'pathExport' => $this->router->generateUri(
                'Commande.GestionCommande.exportCde',
                ['origin' => $origin]
            ),
            'formFilter' => ($origin=='SUIVI'?'filtre_suivi':'filtre_commande'),
            'coloneExport' => $tab,
            'tabObli' => ['CA_ENTET.NO_CDE', 'CA_LIGNE.NO_PO'],
            'post' => $post,
            'modeDebug' => false,
        ]);
    }

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

        $arrayMultiSelect = ArrayHelper::filterByKey($post, function ($k) {
            return str_starts_with($k, 'multiSelectexport');
        });

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

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

        if ($origin == 'BR') {
            $gestionBr = new GestionBR($this->pdo);
            $listeCde  = $gestionBr->exportCommande($post, $listeSelect);
        } elseif ($origin == 'SUIVI') {
            if ($origin=='CDE') {
                $origin = '';
            }
            $suiviCdeRepo = new SuiviCdeRepo($this->pdo, $this->router, $this->getTranslationService());
            $listeCde = $suiviCdeRepo->export($post, $origin, $listeSelect);
        } else {
            $commande = new Commande($this->pdo);
            $listeCde = $commande->export($listeSelect, $post);
        }
        
        $this->getEmailCsvService()->sendCsv(
            "export_CDE_".date('Ymd'),
            $listeCde,
            \Closure::fromCallable([$this,'formatExportRow']),
            $this->getLabelField($arrayMultiSelect)
        );

        return 'ok';
    }

//______________________________________________________________________________
// Sub-routine
    
    /**
     * @param array<mixed> $row
     * @return array<mixed>
     */
    private function formatExportRow(array $row)
    {
        $trad = $this->getTranslationService();
        $archiEntet = (new CaEntet($this->pdo))->getArchitecture($trad);
        $archiLigne = (new CaLigne($this->pdo))->getArchitecture($trad);
        $mapCsEntField = (new ChampSupp($this->pdo))->getSchema('CA_ENTET');
        $mapCsLigField = (new ChampSupp($this->pdo))->getSchema('CA_LIGNE');
        foreach ($row as $key => $value) {
            if ($key === 'MONTANT_LIGNE_HT') {
                $row[ $key ] = EntityTool::formatFieldDisplay(
                    ['type' => 'MONTANT'],
                    $value,
                    $trad
                );
                continue;
            }
            if (str_contains($key, '.MEMOS.')) {
                continue;
            }
            if (str_starts_with($key, 'CA_ENTET.CS_DON.')) {
                $row[ $key ] = ChampSupp::formatValue(
                    $mapCsEntField
                        [ StringHelper::removePrefix($key, 'CA_ENTET.CS_DON.') ]
                        ['TYPE'],
                    $value,
                    $trad
                );
                continue;
            }
            if (str_starts_with($key, 'CA_LIGNE.CS_DON.')) {
                $row[ $key ] = ChampSupp::formatValue(
                    $mapCsLigField
                        [StringHelper::removePrefix($key, 'CA_LIGNE.CS_DON.') ]
                        ['TYPE'],
                    $value,
                    $trad
                );
                continue;
            }

            if (str_starts_with($key, 'CA_ENTET.',)) {
                $row[ $key ] = EntityTool::formatFieldDisplay(
                    $archiEntet[ StringHelper::removePrefix($key, 'CA_ENTET.') ],
                    $value,
                    $trad
                );
                continue;
            }

            if (str_starts_with($key, 'CA_LIGNE.')) {
                $row[ $key ] = EntityTool::formatFieldDisplay(
                    $archiLigne[ StringHelper::removePrefix($key, 'CA_LIGNE.') ],
                    $value,
                    $trad
                );
                continue;
            }
        }
        return $row;
    }

    
    /**
     * Summary of getLabelField
     * @param array<mixed> $tabTmp
     * @return array<mixed>
     */
    private function getLabelField($tabTmp)
    {
        $listeChpsEntete = (new CaEntet($this->pdo))->getArchitecture($this->getTranslationService());
        $listeChpsLigne = (new CaLigne($this->pdo))->getArchitecture($this->getTranslationService());
        $listeCSEntete = (new ChampSupp($this->pdo))->getInfoCS('CA_ENTET');
        $listeCSLigne = (new ChampSupp($this->pdo))->getInfoCS('CA_LIGNE');

        $libEntete = $this->getTranslationService()->t('Entête');
        $libLigne = $this->getTranslationService()->t('Ligne');

        $tab = [];
        foreach ($tabTmp as $tmp) {
            if (str_starts_with($tmp, 'CA_ENTET.MEMOS.',)) {
                $tab[$tmp] = $libEntete.' '.$listeChpsEntete[(string)str_replace('CA_ENTET.MEMOS.', '', $tmp)]['nomChamp'];
            } elseif (str_starts_with($tmp, 'CA_LIGNE.MEMOS.',)) {
                $tab[$tmp] = $libLigne.' '.$listeChpsLigne[(string)str_replace('CA_LIGNE.MEMOS.', '', $tmp)]['nomChamp'];
            } elseif (str_starts_with($tmp, 'CA_ENTET.CS_DON.',)) {
                $tab[$tmp] = $libEntete.' '.$listeCSEntete[(string)str_replace('CA_ENTET.CS_DON.', '', $tmp)]['NOM'];
            } elseif (str_starts_with($tmp, 'CA_LIGNE.CS_DON.',)) {
                $tab[$tmp] = $libLigne.' '.$listeCSLigne[(string)str_replace('CA_LIGNE.CS_DON.', '', $tmp)]['NOM'];
            } elseif (str_starts_with($tmp, 'CA_ENTET.',)) {
                $tab[$tmp] = $libEntete.' '.$listeChpsEntete[(string)str_replace('CA_ENTET.', '', $tmp)]['nomChamp'];
            } elseif (str_starts_with($tmp, 'CA_LIGNE.',)) {
                $tab[$tmp] = $libLigne.' '.$listeChpsLigne[(string)str_replace('CA_LIGNE.', '', $tmp)]['nomChamp'];
            } elseif (str_starts_with($tmp, 'MONTANT_LIGNE_HT',)) {
                $tab['MONTANT_LIGNE_HT'] = $libLigne.' '.$this->getTranslationService()->t('Montant HT');
            } elseif (str_starts_with($tmp, 'FOURNISS.RS')) {
                $tab[$tmp] = $libEntete.' '.$this->getTranslationService()->t('Libellé fournisseur');
            } elseif (str_starts_with($tmp, 'oxaExportACH.NOM')) {
                $tab[$tmp] = $libEntete.' '.$this->getTranslationService()->t('Libellé acheteur');
            } elseif (str_starts_with($tmp, 'oxaExportDEMANDEUR.NOM')) {
                $tab[$tmp] = $libEntete.' '.$this->getTranslationService()->t('Libellé demandeur');
            } elseif (str_starts_with($tmp, 'oxaExportLOGIST.NOM')) {
                $tab[$tmp] = $libEntete.' '.$this->getTranslationService()->t('Libellé logisticien');
            } elseif (str_starts_with($tmp, 'oxaExportSECTIMP.LIBELLE')) {
                $tab[$tmp] = $libEntete.' '.$this->getTranslationService()->t('Libellé section d\'imputation');
            } elseif (str_starts_with($tmp, 'oxaExportCODECOMP.LIBELLE')) {
                $tab[$tmp] = $libEntete.' '.$this->getTranslationService()->t('Libellé code complémentaire');
            } elseif (str_starts_with($tmp, 'oxaExportSSCPTEANA.LIBELLE')) {
                $tab[$tmp] = $libEntete.' '.$this->getTranslationService()->t('Libellé sous-compte d\'analyse');
            } elseif (str_starts_with($tmp, 'oxaExportCTR_EMETT.RAIS_SOC')) {
                $tab[$tmp] = $libEntete.' '.$this->getTranslationService()->t('Libellé centre emetteur');
            } elseif (str_starts_with($tmp, 'oxaExportCTR_LIV.RAIS_SOC')) {
                $tab[$tmp] = $libEntete.' '.$this->getTranslationService()->t('Libellé centre de livraison');
            } elseif (str_starts_with($tmp, 'oxaExportCTR_FACTU.RAIS_SOC')) {
                $tab[$tmp] = $libEntete.' '.$this->getTranslationService()->t('Libellé centre de facturation');
            } elseif (str_starts_with($tmp, 'oxaExportACC_CADRE.LIBELLE')) {
                $tab[$tmp] = $libEntete.' '.$this->getTranslationService()->t('Libellé accord-cadre');
            } elseif (str_starts_with($tmp, 'oxaExportCOND_PAIE.LIBELLE')) {
                $tab[$tmp] = $libEntete.' '.$this->getTranslationService()->t('Libellé condition de paiement');
            } elseif (str_starts_with($tmp, 'oxaExportMODE_PAIE.LIBELLE')) {
                $tab[$tmp] = $libEntete.' '.$this->getTranslationService()->t('Libellé mode de paiement');
            } elseif (str_starts_with($tmp, 'oxaExportMODE_LIV.LIBELLE')) {
                $tab[$tmp] = $libEntete.' '.$this->getTranslationService()->t('Libellé mode de livraison');
            } elseif (str_starts_with($tmp, 'oxaExportCODE_STE.RAIS_SOC')) {
                $tab[$tmp] = $libEntete.' '.$this->getTranslationService()->t('Libellé société');
            } elseif (str_starts_with($tmp, 'oxaExport_LIGNE_SSFAM.DESIGNAT')) {
                $tab[$tmp] = $libLigne.' '.$this->getTranslationService()->t('Libellé sous-famille');
            } elseif (str_starts_with($tmp, 'oxaExport_LIGNE_SECTIMP.LIBELLE')) {
                $tab[$tmp] = $libLigne.' '.$this->getTranslationService()->t('Libellé section d\'imputation');
            } elseif (str_starts_with($tmp, 'oxaExport_LIGNE_CODE_COMP.LIBELLE')) {
                $tab[$tmp] = $libLigne.' '.$this->getTranslationService()->t('Libellé code complémentaire');
            } elseif (str_starts_with($tmp, 'oxaExport_LIGNE_SSCPTEANA.LIBELLE')) {
                $tab[$tmp] = $libLigne.' '.$this->getTranslationService()->t('Libellé sous-compte d\'analyse');
            } elseif (str_starts_with($tmp, 'oxaExport_LIGNE_SITE_STK.DESIGN')) {
                $tab[$tmp] = $libLigne.' '.$this->getTranslationService()->t('Libellé site de stock');
            } elseif (str_starts_with($tmp, 'oxaExport_LIGNE_CODE_STE.RAIS_SOC')) {
                $tab[$tmp] = $libLigne.' '.$this->getTranslationService()->t('Libellé société');
            } elseif (str_starts_with($tmp, 'oxaExport_LIGNE_ACCORCA.LIBELLE')) {
                $tab[$tmp] = $libLigne.' '.$this->getTranslationService()->t('Libellé accord-cadre');
            } elseif (str_starts_with($tmp, 'oxaExport_LIGNE_COD_FAB.RS')) {
                $tab[$tmp] = $libLigne.' '.$this->getTranslationService()->t('Libellé fabricant');
            } elseif (str_starts_with($tmp, 'oxaExport_LIGNE_COD_GAM.DESIGN')) {
                $tab[$tmp] = $libLigne.' '.$this->getTranslationService()->t('Libellé gamme');
            }
        }

        return $tab;
    }
    
    /**
     * Return a map of exportable entity definitions (or ChampSupp) indexed by their export key
     * @return string[]
     */
    private function exportGetTab() :array
    {
        $tab = [];
        $listeChpCde = (new CaEntet($this->pdo))->getArchitecture($this->getTranslationService());
        foreach ($listeChpCde as $key => $config) {
            if (($config['type'] ?? null) == 'MEMO') {
                $tab[] = 'CA_ENTET.MEMOS.'.$key;
                continue;
            }
            $tab[] = 'CA_ENTET.'.$key;
        }

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

        foreach ($listeTmpCS as $cs) {
            $tab[] = 'CA_ENTET.CS_DON.'.$cs['NUM_FIX'];
        }

        $listeChpCde = (new CaLigne($this->pdo))->getArchitecture($this->getTranslationService());
        foreach ($listeChpCde as $key => $config) {
            if ($key == 'NO_CDE') {
                continue;
            }
            if (($config['type'] ?? null) == 'MEMO') {
                $tab[] = 'CA_LIGNE.MEMOS.'.$key;
                continue;
            }
            $tab[] = 'CA_LIGNE.'.$key;
        }

        $listeTmpCS = $champSupp->getInfoCS('CA_LIGNE');
        foreach ($listeTmpCS as $cs) {
            $tab[] = 'CA_LIGNE.CS_DON.'.$cs['NUM_FIX'];
        }

        $tab[] = 'MONTANT_LIGNE_HT';

        $tab[] = 'FOURNISS.RS';
        $tab[] = 'oxaExportACH.NOM';
        $tab[] = 'oxaExportDEMANDEUR.NOM';
        $tab[] = 'oxaExportLOGIST.NOM';
        $tab[] = 'oxaExportSECTIMP.LIBELLE';
        $tab[] = 'oxaExportCODECOMP.LIBELLE';
        $tab[] = 'oxaExportSSCPTEANA.LIBELLE';
        $tab[] = 'oxaExportCTR_EMETT.RAIS_SOC';
        $tab[] = 'oxaExportCTR_LIV.RAIS_SOC';
        $tab[] = 'oxaExportCTR_FACTU.RAIS_SOC';
        $tab[] = 'oxaExportACC_CADRE.LIBELLE';
        $tab[] = 'oxaExportCOND_PAIE.LIBELLE';
        $tab[] = 'oxaExportMODE_PAIE.LIBELLE';
        $tab[] = 'oxaExportMODE_LIV.LIBELLE';
        $tab[] = 'oxaExportCODE_STE.RAIS_SOC';


        $tab[] = 'oxaExport_LIGNE_SSFAM.DESIGNAT';
        $tab[] = 'oxaExport_LIGNE_SECTIMP.LIBELLE';
        $tab[] = 'oxaExport_LIGNE_CODE_COMP.LIBELLE';
        $tab[] = 'oxaExport_LIGNE_SSCPTEANA.LIBELLE';
        $tab[] = 'oxaExport_LIGNE_SITE_STK.DESIGN';
        $tab[] = 'oxaExport_LIGNE_CODE_STE.RAIS_SOC';
        $tab[] = 'oxaExport_LIGNE_ACCORCA.LIBELLE';
        $tab[] = 'oxaExport_LIGNE_COD_FAB.RS';
        $tab[] = 'oxaExport_LIGNE_COD_GAM.DESIGN';

        return $tab;
    }
}
