<?php
namespace Modules\Additional\Specifique\Client128\Modules\EtatStatistique\Controller;

use Entity\Model\CsDon;
use Helpers\Outil\ArrayHelper;
use Helpers\Outil\Sql;
use Skeleton\Controller\Controller;
use Helpers\Ariane\Ariane;
use Modules\Additional\Specifique\Client128\Modules\EtatStatistique\Repository\Reporting;
use Modules\Additional\Specifique\Client128\Modules\EtatStatistique\Repository\ReportingUO;
use Helpers\Outil\Date;
use Helpers\Pagination\PaginatorGestion;
use Helpers\Parametres\Constante;

class EtatStatistiqueController extends Controller
{
    public function listeCdeDetailAction() : string
    {
        $post = $this->request->getParsedBody();
        
        $trad = $this->getTranslationService();
        
        // Set by default dates filters on first/last day of the current year
        $post['DATE_DEB'] = $post['DATE_DEB'] ?? date('d/m/Y', strtotime('first day of january this year'));
        $post['DATE_FIN'] = $post['DATE_FIN'] ?? date('d/m/Y', strtotime('last day of this month'));

        if (! empty($post['Uo'])) {
            $_SESSION['bulleFiltre']['Uo']['titre'] = $trad->t('Unité Organisationnelle');
            $_SESSION['bulleFiltre']['Uo']['value'] = $post['text_Uo'];
        }

        if (! empty($post['Uo'])) {
            $cs_value = $this->getUoCsValue($post['Uo']);
            
            if (!in_array($cs_value['VALEUR'], [
                'SOCIETE', 'DR', 'DO', 'AGENCE',
                'SOUS-AGENCE', 'SOUS-SECTEUR'
            ])) {
                $messageAno = 'Le type de l\'UO que vous avez choisie n\'est pas défini. Le filtre ne peut pas être appliqué.';
            }

            $post['cs_value'] = $cs_value['VALEUR'];
            $post['Uo_filtre'] = $post['Uo'];
          //  $allUOUser                                      = '';
        } else {
            // Get user's UO
            $post['cs_value'] = 'SOUSSECTEUR';
        }

        $listeReportingUO = new ReportingUO($this->pdo);
        $allUOUser = $listeReportingUO->listUOUser();

        $listeReporting = new Reporting($this->pdoOxaDw);
        $liste = $listeReporting->getListCDEDetail($post, $allUOUser);

        foreach ($liste as $key => $ligne) {
            $liste[$key] = $this->getCdeDetailView($ligne);
        }

        Ariane::generate(1, $trad->t('Lignes de commande avec détail article'), $post, PaginatorGestion::getNbrArticle());

        return $this->renderer->render('@Specifique128Reporting/Reporting/reportingListeCDEDetail', [
            'menuActive' => 'Etats Statistiques',
            'post' => $post,
            'infoPagination' => PaginatorGestion::getInfoPagination(),
            'liste' => $liste??[],
            'messageAno' => $messageAno??'',
        ]);
    }

    /**
     * @param string $uo_filtre
     * @return array<string>
     */
    private function getUoCsValue($uo_filtre)
    {
        return (new CsDon($this->pdo))->find([
            'COD_TAB' => 'UO',
            'COD_ENR' => '       ' . $uo_filtre,
            'NUM_FIX' => 1,
        ]);
    }

    public function exportCdeDetailAction() : string
    {
        $post = $this->request->getParsedBody();
        
        $trad = $this->getTranslationService();
        
        $listeReportingUO = new ReportingUO($this->pdo);
        $allUOUser = $listeReportingUO->listUOUser();

        if (isset($post['Uo']) && $post['Uo'] != '') {
            $cs_value = $this->getUoCsValue($post['Uo']);

            $post['cs_value'] = $cs_value['VALEUR'];
            $post['Uo_filtre'] = $post['Uo'];
          //  $allUOUser                                      = '';
        } else {
            // Get user's UO
          
            $post['cs_value']                               = 'SOUSSECTEUR';
        }

    
        $listeReporting = new Reporting($this->pdoOxaDw);
        $liste = $listeReporting->getListCDEDetail($post, $allUOUser, 'export');

        set_time_limit(900);

        foreach ($liste as $key => $ligne) {
            $liste[$key]['DATE_CDE'] = Reporting::convertdateOXADW($liste[$key]['DATE_CDE']);
            $liste[$key]['DATE_RECEPTION'] = Reporting::convertdateOXADW($liste[$key]['DATE_RECEPTION']);
            $liste[$key]['DATE_LIVRAISON_PREV'] = Reporting::convertdateOXADW($liste[$key]['DATE_LIVRAISON_PREV']);

            switch ($liste[$key]['FOURNISSEUR_REFERENCE']) {
                case 'NATIONAL':
                    $liste[$key]['FOURNISSEUR_REFERENCE']       = $trad->t('National');
                    break;
                case 'NR':
                    $liste[$key]['FOURNISSEUR_REFERENCE']       = $trad->t('Non référencé');
                    break;
                case 'REGIONAL':
                    $liste[$key]['FOURNISSEUR_REFERENCE']       = $trad->t('Régional');
                    break;
            }
            $liste[$key]['STATUT_CDE'] = $this->getCommandeStatusLabel(
                $liste[$key]['STATUT_CDE']
            );

            $liste[$key]['ENLEVEMENT_COMPTOIR']=='O'? $trad->t('Oui'):$trad->t('Non');
            $liste[$key]['PAIEMENT_DIRECT'] = $liste[$key]['PAIEMENT_DIRECT']=='OUI'? $trad->t('Oui'):$trad->t('Non');
            $liste[$key]['TVA_AUTO_LIQ'] = $liste[$key]['TVA_AUTO_LIQ']=='OUI'? $trad->t('Oui'):$trad->t('Non');
            $liste[$key]['COMMANDE_EN_MOBILITE'] = $liste[$key]['COMMANDE_EN_MOBILITE']=='OUI'? $trad->t('Oui'):$trad->t('Non');
        }

        $title = [
            'CODE_SOCIETE' => $trad->t('Code Société'),
            'CODE_SOUS_SECTEUR' => $trad->t('Direction'),
            'DEMANDEUR' => $trad->t('Demandeur'),
            'DATE_CDE' => $trad->t('Date CDE'),
            'NUMERO_CDE'=> $trad->t('N° CDE'),
            'CODE_FOURN'=> $trad->t('Code Fournisseur'),
            'FRS_RAISON_SOC'=> $trad->t('Raison Sociale Fournisseur'),
            'FOURNISSEUR_REFERENCE'=> $trad->t('Fournisseur Référencé'),
            'TAILLE_ENTREPRISE'=> $trad->t('Taille Entreprise'),
            'CHANTIER'=> $trad->t('Chantier'),
            'DESIGNATION_CHANTIER'=> $trad->t('Désignation Chantier'),
            'CODE_INSTALL'=> $trad->t('Code Installation'),
            'DESIGNATION_INSTALL'=> $trad->t('Désignation Installation'),
            'PRESTATION'=> $trad->t('Prestation'),
            'OBJET_CDE'=> $trad->t('Objet CDE'),
            'CODE_ART'=> $trad->t('Code Article'),
            'DESIGNATION_ART'=> $trad->t('Désignation article'),
            'DESIGNATION_COMP'=> $trad->t('Désignation complémentaire'),
            'REF_DISTRIBUTEUR'=> $trad->t('Référence Distributeur'),
            'CONSTRUCTEUR'=> $trad->t('Constructeur'),
            'REF_CONSTRUCTEUR'=> $trad->t('Référence constructeur'),
            'QTE'=> $trad->t('Quantité'),
            'PU'=> $trad->t('PU'),
            'MONTANT_LIGNE_CDE'=> $trad->t('Montant Ligne CDE'),
            'DEVISE'=> $trad->t('Devise'),
            'TYPE_CDE'=> $trad->t('Type CDE'),
            'STATUT_CDE' => $trad->t('Statut CDE'),
            'DATE_RECEPTION' => $trad->t('Date Réception'),
            'ENLEVEMENT_COMPTOIR'=> $trad->t('Enlèvement Comptoir'),
            'INVEST_NNINVES'=> $trad->t('Investissement/Non invest.'),
            'PAIEMENT_DIRECT'=> $trad->t('Paiement Direct'),
            'TVA_AUTO_LIQ'=> $trad->t('TVA auto-liquidée'),
            'NUMERO_DEVIS_OXYGEN'=> $trad->t('N° Devis Oxygen'),
            'COMPTE_COMPTABLE'=> $trad->t('Compte Comptable'),
            'CODE_SEGMENTATION'=> $trad->t('Code Segmentation'),
            'LIBELLE_SEGMENTATION'=> $trad->t('Libellé Segmentation'),
            'COMMANDE_EN_MOBILITE'=> $trad->t('Commande en Mobilité'),
            'UO_LIGNE'=> $trad->t('UO'),
        ];
        $listKey = array_keys($title);
        \Helpers\ExportTo\Outils::gestionEmailAsync2(
            'reporting_list_commande_detail',
            array_map(function ($data) use ($listKey) {
                return ArrayHelper::sortKeyByArray(
                    ArrayHelper::filterByKey($data, $listKey),
                    $listKey
                );
            }, $liste),
            $this->JWTKEY,
            $this->router,
            $this->getTranslationService(),
            $title
        );

        return 'ok';
    }

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

        // Set by default dates filters on first/last day of the current year
        $post['DATE_DEB'] = $post['DATE_DEB'] ?? date('d/m/Y', strtotime('first day of january this year'));
        $post['DATE_FIN'] = $post['DATE_FIN'] ?? date('d/m/Y', strtotime('last day of this month'));

        if (! empty($post['Uo'])) {
            $_SESSION['bulleFiltre']['Uo']['titre'] = $trad->t('Unité Organisationnelle');
            $_SESSION['bulleFiltre']['Uo']['value'] = $post['text_Uo'];
        }
        
        // Get user's UO
        $allUOUser = (new ReportingUO($this->pdo))->listUOUser();
        
        if (! empty($post['Uo'])) {
            $cs_value = $this->getUoCsValue($post['Uo']);
            if (!in_array($cs_value['VALEUR'], [
                'SOCIETE', 'DR', 'DO', 'AGENCE',
                'SOUS-AGENCE', 'SOUS-SECTEUR'
            ])) {
                $messageAno = 'Le type de l\'UO que vous avez choisie n\'est pas défini. Le filtre ne peut pas être appliqué.';
            }

            $post['cs_value'] = $cs_value['VALEUR'];
            $post['Uo_filtre'] = $post['Uo'];
            // $allUOUser                                      = '';
        } else {
            $post['cs_value'] = 'SOUSSECTEUR';
        }
        $liste = (new Reporting($this->pdoOxaDw))->getAllCDE($post, $allUOUser);

        foreach ($liste as $key => $ligne) {
            $liste[$key] = $this->getCdeView($ligne);
        }

        Ariane::generate(1, $trad->t('Liste de commandes'), $post, PaginatorGestion::getNbrArticle());

        return $this->renderer->render('@Specifique128Reporting/Reporting/reportingListeCDE', [
            'menuActive'                    => 'Etats Statistiques',
            'post'                          => $post,
            'infoPagination'                => PaginatorGestion::getInfoPagination(),
            'listeCde'                      => $liste??[],
            'messageAno'                    => $messageAno??'',
        ]);
    }
    public function exportCdeAction() : string
    {
        $post = $this->request->getParsedBody();
        
        $trad = $this->getTranslationService();
        
        // Get user's UO
        $allUOUser = (new ReportingUO($this->pdo))->listUOUser();
        
        if (! empty($post['Uo'])) {
            $cs_value = $this->getUoCsValue($post['Uo']);

            $post['cs_value'] = $cs_value['VALEUR'];
            $post['Uo_filtre'] = $post['Uo'];
            // $allUOUser                                      = '';
        } else {
            $post['cs_value'] = 'SOUSSECTEUR';
        }
        $liste = (new Reporting($this->pdoOxaDw))->getAllCDE($post, $allUOUser, 'export');


        set_time_limit(900);

        foreach ($liste as $key => $ligne) {
            $liste[$key] = $this->getCdeView($ligne);
        }

        $title = [
            'CODE_SOCIETE'=> $trad->t('Code Société'),
            'CODE_SOUS_SECTEUR'=> $trad->t('Direction'),
            'DEMANDEUR'=> $trad->t('Demandeur'),
            'DATE_CDE' => $trad->t('Date CDE'),
            'DATE_LIVRAISON_PREV' => $trad->t('Date de livraison prévisionnelle'),
            'NUMERO_CDE'=> $trad->t('N° CDE'),
            'CODE_FOURN'=> $trad->t('Code Fournisseur'),
            'FRS_RAISON_SOC'=> $trad->t('Raison Sociale Fournisseur'),
            'FOURNISSEUR_REFERENCE'=> $trad->t('Fournisseur Référencé'),
            'TAILLE_ENTREPRISE'=> $trad->t('Taille Entreprise'),
            'CHANTIER'=> $trad->t('Chantier'),
            'DESIGNATION_CHANTIER'=> $trad->t('Désignation Chantier'),
            'CODE_INSTALL'=> $trad->t('Code Installation'),
            'DESIGNATION_INSTALL'=> $trad->t('Désignation Installation'),
            'PRESTATION'=> $trad->t('Prestation'),
            'OBJET_CDE'=> $trad->t('Objet CDE'),
            'MONTANT_TOTAL'=> $trad->t('Montant HT'),
            'MONTANT_RECEP'=> $trad->t('Montant réceptionné'),
            'DEVISE'=> $trad->t('Devise'),
            'TYPE_CDE'=> $trad->t('Type CDE'),
            'STATUT_CDE'=> $trad->t('Statut CDE'),
            'DATE_RECEPTION' => $trad->t('Date Réception'),
            'ENLEVEMENT_COMPTOIR'=> $trad->t('Enlèvement Comptoir'),
            'INVEST_NNINVES'=> $trad->t('Investissement/Non invest.'),
            'PAIEMENT_DIRECT'=> $trad->t('Paiement Direct'),
            'TVA_AUTO_LIQ'=> $trad->t('TVA auto-liquidée'),
            'NUMERO_DEVIS_OXYGEN'=> $trad->t('N° Devis Oxygen'),
            'COMMANDE_EN_MOBILITE'=> $trad->t('Commande en Mobilité'),
        ];
        $listKey = array_keys($title);
        \Helpers\ExportTo\Outils::gestionEmailAsync2(
            'reporting_list_commande',
            array_map(function ($data) use ($listKey) {
                return ArrayHelper::sortKeyByArray(
                    ArrayHelper::filterByKey($data, $listKey),
                    $listKey
                );
            }, $liste),
            $this->JWTKEY,
            $this->router,
            $this->getTranslationService(),
            $title
        );
    
        return 'ok';
    }

    /**
     * @param array<mixed> $cde
     * @return array<mixed>
     */
    private function getCdeView(array $cde)
    {
        $trad = $this->getTranslationService();
        return [
            'DATE_CDE' => Reporting::convertdateOXADW($cde['DATE_CDE']),
            'DATE_RECEPTION' => Reporting::convertdateOXADW($cde['DATE_RECEPTION']),
            'DATE_LIVRAISON_PREV' => Reporting::convertdateOXADW($cde['DATE_LIVRAISON_PREV']),
            'FOURNISSEUR_REFERENCE' => $this->getFournissRefLabel($cde['FOURNISSEUR_REFERENCE']),
            'STATUT_CDE' => $this->getCommandeStatusLabel($cde['STATUT_CDE']),
            'ENLEVEMENT_COMPTOIR' => Sql::toBool($cde['ENLEVEMENT_COMPTOIR']) ? $trad->t('Oui') : $trad->t('Non'),
            'PAIEMENT_DIRECT' => $cde['PAIEMENT_DIRECT']=='OUI' ? $trad->t('Oui') : $trad->t('Non'),
            'TVA_AUTO_LIQ' => $cde['TVA_AUTO_LIQ']=='OUI' ? $trad->t('Oui') : $trad->t('Non'),
            'COMMANDE_EN_MOBILITE' => $cde['COMMANDE_EN_MOBILITE']=='OUI' ? $trad->t('Oui') : $trad->t('Non'),
        ] + $cde;
    }

    /**
     * @param array<mixed> $cde
     * @return array<mixed>
     */
    private function getCdeDetailView(array $cde)
    {
        return $this->getCdeView($cde);
    }

    private function getFournissRefLabel(string $s) :string
    {
        $trad = $this->getTranslationService();
        switch ($s) {
            case 'NATIONAL':
                return $trad->t('National');
            case 'NR':
                return $trad->t('Non référencé');
            case 'REGIONAL':
                return $trad->t('Régional');
        }
        return $s;
    }

    // phpcs:ignore
    public function array_filter_and_tags($array)
    {
        foreach ($array as &$value) {
            if (is_array($value)) {
                $value = $this->array_filter_and_tags($value);
                if (array_key_exists('id', $value)) {
                    if (array_key_exists('nodes', $value)) {
                        $value['tags'] = array(count($value['nodes']));
                    } else {
                        $value['tags'] = array(0);
                    }
                }
            }
        }
        
        return array_filter($array, function ($val) {
            return ($val || is_numeric($val));
        });
    }

    public function uoTreeviewAction() : string
    {
        $post = $this->request->getParsedBody();
        
        $treeviewReporting                              = new ReportingUO($this->pdo);
        // Get user's UO
        $listeUO                                        = $treeviewReporting->listUOUserTreeview();
        $treeCG =  $this->treeUO('', $listeUO, $post);
        $treeCG =  $this->array_filter_and_tags($treeCG);
        return $this->renderer->render('@Specifique128Reporting/ajax-liste/listeUO', [
            'post' => $post,
            'treeCG' => $treeCG,
        ]);
    }

    public function treeviewAction() : string
    {
        $post = array('divCode' => 'input_Uo', 'divLibelle' => 'text_Uo', 'CODE_STE' => 'DEMO', 'input' => 'Uo' );
        
        $treeviewReporting                              = new ReportingUO($this->pdo);
        // Get user's UO
        $listeUO                                        = $treeviewReporting->listUOUserTreeview();
        $treeCG =  $this->treeUO('', $listeUO, $post);
        $treeCG =  $this->array_filter_and_tags($treeCG);
        
        return $this->renderer->render('@Specifique128Reporting/ajax-liste/listeUO', [
            'post' => $post,
            'treeCG' => $treeCG,
        ]);
    }
    


    public function treeUO($parent, $array, $post)
    {
        $result = array();
        foreach ($array as $noeud) {
            if ($parent == trim($noeud['UO_MERE'])) {
                $result[] = array(
                    'id' => $noeud['CODE_UO'],
                    'text' => $noeud['LIB_UO'].' ('.$noeud['CODE_UO'].')',
                    'nodes' => $this->treeUO($noeud['CODE_UO'], $array, $post),
                    'href' => '#'.$noeud['CODE_UO'].Constante::spliter.$noeud['LIB_UO'],
                );
            } elseif ($parent=='') {
                // check if UO already in array
                $uoInResult =0;
                foreach ($result as $r) {
                    if (in_array(trim($noeud['UO_MERE']), $r)) {
                        $uoInResult = 1;
                        break;
                    }
                }
                if (!$uoInResult) {
                    $result[] = array(
                        'id' => $noeud['CODE_UO'],
                        'text' => $noeud['LIB_UO'].' ('.$noeud['CODE_UO'].')',
                        'nodes' => $this->treeUO($noeud['CODE_UO'], $array, $post),
                        'href' => '#'.$noeud['CODE_UO'].Constante::spliter.$noeud['LIB_UO'],
                    );
                }
            }
        }
        return $result;
    }

    private function getCommandeStatusLabel(string $status) :string
    {
        $trad = $this->getTranslationService();
        return [
            'E' => $trad->t('En cours'),
            'I' => $trad->t('À envoyer'),
            'S' => $trad->t('Soldée'),
            'P' => $trad->t('En signature'),
            'R' => $trad->t('Refusée'),
            'L' => $trad->t('Livraison partielle'),
        ][ $status ] ?? $status;
    }
}
