<?php

namespace Modules\Panier\Service;

use Entity\Model\Centre;
use Entity\Model\Codgest;
use Entity\Model\CtcCtr;
use Entity\Model\OxaUserPanier;
use Entity\Model\OxaUserPanierCsDon;
use Entity\Model\OxaUserPanierFour;
use Entity\Model\OxaUserPanierFourContact;
use Entity\Model\OxaUserPanierLigne;
use Entity\Model\Societe;
use Helpers\Additional\Specifique\Specifique;
use Helpers\ChampsSupplementaire\ChampSupp;
use Helpers\Fichier\Fichier;
use Helpers\Outil\Sql;
use Helpers\Parametres\Constante;
use Helpers\Trad\ITrad;
use Modules\GlobalApplication\Outil\InitAxesImpDa;
use Modules\GlobalApplication\Service\ConvertionDeviseService;
use Modules\Index\Service\SessionService;
use Modules\Panier\Repository\PanierEntete;
use Modules\Panier\Repository\PanierFrs;
use Modules\Panier\Repository\PanierLigne;

class PanierEnteteService
{
    /**
     * @var \PDO $pdo
     */
    private $pdo;

    /**
     * @var PanierEntete $panierEntete
     */
    private $panierEntete;

       /**
     * @var PanierLigne $panierLigne
     */
    private $panierLigne;

    /**
     * @var array<mixed> $infoEntete
     */
    private $infoEntete;

    public function __construct(\PDO $pdo)
    {
        $this->pdo = $pdo;

        $this->panierEntete = new PanierEntete($this->pdo);
        $this->panierLigne = new PanierLigne($this->pdo);
        $this->infoEntete = $this->panierEntete->getEntetePanier($_SESSION['id_panier'], $_SESSION['id_user']);
    }

    public function initPanierEntete(ITrad $trad, bool $force = false):void
    {
        if ($this->infoEntete) {
            if (($this->infoEntete['IS_INITIALIZED'] != '1' || $force)) {
                $arraySession = $this->getArrayInitSession($trad);
                if ($_SESSION['Session_Login'] != 'OXAUSER') {
                    (new OxaUserPanier($this->pdo))->update($arraySession, [
                        'id_user' => $_SESSION['id_user'],
                        'id_panier' => $_SESSION['id_panier']
                    ]);
                    
                    $arraySessionLigne = [];
                    if ($arraySession['LIV_CTR']) {
                        $arraySessionLigne['CodeCtrLivraison']    = $arraySession['LIV_CTR'];
                    }

                    $listeLignePanier = (new OxaUserPanierLigne($this->pdo))->findAll([
                        'id_user' => $_SESSION['id_user'],
                        'id_panier' => $_SESSION['id_panier']
                    ]);

                    $codeGestion = new Codgest($this->pdo);
                    $infoCG = $codeGestion->find([
                        'CODE_STE'  => $arraySession['CODE_STE'],
                        'CODE_SI'   => $arraySession['SI_CODE'],
                        'CODE_AFF'  => $arraySession['CG_CODE']
                    ]);
                    
                    $initImputation = new InitAxesImpDa($this->pdo, [
                        'CODE_STE'  => $arraySession['CODE_STE'],
                        'SECTIMP'   => $arraySession['SI_CODE'],
                        'SSCPTEANA' => $arraySession['SCA_CODE'],
                        'CODECOMP'  => $arraySession['CDC_CODE'],
                        'TYP_DOC'   => '',
            
                        'ID_CG'     => $infoCG['CODE_GES']??'',
                        'CODGES'    => $infoCG['CODE_AFF']??'',
                        'LIBGES'    => $infoCG['LIB_GES']??'',
                    ]);

                    foreach ($listeLignePanier as $article) {
                        $imputation = $initImputation->getInitImputation([
                            'CODE_ART' => ($article['COD_ART']??''),
                            'SousFamille' => [
                                'CODE_SFA' => $article['COD_SFAM']??'',
                                'CODE_FAM' => $article['CODE_FAM']??'',
                            ],
                        ]);

                        $arraySessionLigne['SI_CODE']   = $imputation['SI'];
                        $arraySessionLigne['CDC_CODE']  = $imputation['CDC'];
                        $arraySessionLigne['SCA_CODE']  = $imputation['SCA'];
                        $arraySessionLigne['CG_CODE']   = $imputation['CODGES'];

                        $specifique = new Specifique();
                        $namespaceSpecifique = $specifique->specifiqueFunction('\\Modules\\Panier\\Service\\UpdateValueCtrLivraison');
                        if (class_exists($namespaceSpecifique)) {
                            $centrLivraisonSpec = Specifique::specifique('\\Modules\\Panier\\Service\\UpdateValueCtrLivraison', 'initCentreLivraisonSI', $this->pdo, $imputation['SI'], $article['id_lig'], true);
                        
                            if ($centrLivraisonSpec) {
                                $arraySessionLigne['CodeCtrLivraison'] = $centrLivraisonSpec;
                            }
                        }

                        $specifique = new Specifique();
                        $namespaceSpecifique = $specifique->specifiqueFunction('\\Modules\\Panier\\Service\\UpdateCdcBySi');
                        if (class_exists($namespaceSpecifique)) {
                            $cdc = Specifique::specifique('\\Modules\\Panier\\Service\\UpdateCdcBySi', 'updateCdcBySI', $this->pdo, $arraySession['CODE_STE'], $imputation['SI']);
                            if ($cdc) {
                                $arraySessionLigne['CDC_CODE'] = $cdc;
                            }
                        }

                        (new OxaUserPanierLigne($this->pdo))->update($arraySessionLigne, [
                            'id_user'   => $_SESSION['id_user'],
                            'id_panier' => $_SESSION['id_panier'],
                            'id_lig'    => $article['id_lig']
                        ]);
                    }

                    /*(new OxaUserPanierLigne($this->pdo))->update($arraySessionLigne, [
                        'id_user' => $_SESSION['id_user'],
                        'id_panier' => $_SESSION['id_panier']
                    ]);*/
                }

                $this->resetControlePanier($_SESSION['id_panier']);
                $this->initCS();
            }
        } else {
            $arraySession = $this->getArrayInitSession($trad);

            (new OxaUserPanier($this->pdo))->insert([
                'id_user' => $_SESSION['id_user'],
                'id_panier' => $_SESSION['id_panier']
            ]+$arraySession);
            $this->infoEntete = $this->panierEntete->getEntetePanier($_SESSION['id_panier'], $_SESSION['id_user']);

            $this->resetControlePanier($_SESSION['id_panier']);
            $this->initCS();
        }
    }

    //getValueInitEntetePanierFromSession
    /**
     * @param ITrad $trad
     * @return array<mixed>
     */
    public function getArrayInitSession(ITrad $trad)
    {

        if (!isset($_SESSION['Session_SocUsr'])) {
            $_SESSION['Session_SocUsr'] = $_SESSION['Session_SocUsrProfil'];
        }

        // Fail safe
        if ((!isset($_SESSION['Session_CodeCtrLivraison'])
            || !isset($_SESSION['Session_SocUsr'])) && $_SESSION['Session_Login'] != 'OXAUSER'
        ) {
            throw new \Exception('User no authentified');
        }

        $chiffExec = Sql::paravrac($this->pdo, 'OXAPROC', 'VALEUR_DEF_CHIFF_EXEC');
        $societe = (new Societe($this->pdo))->find($_SESSION['Session_SocUsr']);

        if ($chiffExec != 'C' && $chiffExec != 'E') {
            $chiffExec = 'E';
        }

        $centreLivSession = $_SESSION['Session_CodeCtrLivraison']??'';
        $MOD_TRS = '';

        $specifique = new Specifique();
        $namespaceSpecifique = $specifique->specifiqueFunction('\\Modules\\Panier\\Service\\InitSpecifique');
        if (class_exists($namespaceSpecifique)) {
            $centreLivSession = Specifique::specifique('\\Modules\\Panier\\Service\\InitSpecifique', 'getCentreLivraison', $this->pdo, $_SESSION['Session_SocUsr'], $centreLivSession);
        }

        if ($centreLivSession) {
            $infoCentre = (new Centre($this->pdo))->find($centreLivSession);

            if (sql::boolSql($infoCentre['TRS_INTER'])) {
                $MOD_TRS = $infoCentre['MOD_TRS'];
            }

            $ctcCtrEntity = new CtcCtr($this->pdo);
            $ctcCtr = $ctcCtrEntity->fetchAll([], ['filter_egal_COD_CTR' => $centreLivSession, 'filter_egal_CTC_RCA' => 'T', 'tri_CTC_IND' => 'asc']);
            $ctcCtr = $ctcCtr[0]??[];
        }

        $cdc = $_SESSION['Session_CDC']??'';

        $specifique = new Specifique();
        $namespaceSpecifique = $specifique->specifiqueFunction('\\Modules\\Panier\\Service\\InitSpecifiqueCDC');
        if (class_exists($namespaceSpecifique)) {
            $cdc = Specifique::specifique('\\Modules\\Panier\\Service\\InitSpecifiqueCDC', 'getCDC', $this->pdo, $cdc);
        }

        $si = $_SESSION['Session_SectionImputation']??'';

        $specifique = new Specifique();
        $namespaceSpecifique = $specifique->specifiqueFunction('\\Modules\\Panier\\Service\\UpdateSISpecifique');
        
        if (class_exists($namespaceSpecifique)) {
            $si = Specifique::specifique('\\Modules\\Panier\\Service\\UpdateSISpecifique', 'updateSI', $this->pdo, $_SESSION['Session_CodeCtrEmetteur']);
            /*if ($si) {
                $initSession = [
                    'SI'        => $si,
                ];

                $sessionService = new SessionService($this->pdo);
                $sessionService->setAllFieldsSessionUser($initSession);
            }*/
        }


        $specifique = new Specifique();
        $namespaceSpecifique = $specifique->specifiqueFunction('\\Modules\\Liste\\Service\\SpecifiqueCentreLivraison');
        if (class_exists($namespaceSpecifique)) {
            $array = [
                'SI' => $si,
                'CODE_STE' => $_SESSION['Session_SocUsr']
            ];

            $centreLivSession  = Specifique::specifique('\\Modules\\Liste\\Service\\SpecifiqueCentreLivraison', 'initCentreBySi', $this->pdo, $array);
        }
        
        $arraySession = [
            //general panier
            'IS_INITIALIZED'    => '1',
            'COD_DEV'           => $societe['DEVISE'],
            'mnt_budget'        => 0,
            'ORIGINE'           => 'panier',
            'CHIF_EXEC'         => $chiffExec,
            'CHIF_EXEC_LOCK'    => '0',

            //imputation
            'CODE_STE'          => $_SESSION['Session_SocUsr'],
            'SI_CODE'           => $si,
            'CDC_CODE'          => $cdc,
            'SCA_CODE'          => $_SESSION['Session_SCA']??'',
            'CG_CODE'           => $_SESSION['Session_CG']??'',
            
            
            //centre emetteur
            'OUPA_CENTRE_EMETTEUR' => $_SESSION['Session_CodeCtrEmetteur'],

            //DA
            'TOTAL_DA'          => 0,
            'BUDGET_DA'         => '0',
            'NO_DA'             => '0',
            'TITRE_DA'          => '',
            'NO_DEM'            => $_SESSION['Session_Login'],

            //CDE
            'NO_CDE'            => '',

            //Centre
            'MOD_TRS'           => $MOD_TRS,
            'LIV_ADR'           => $infoCentre['ADRESSE']??'',
            'LIV_PAYS'          => $infoCentre['PAYS']??'',
            'LIV_CP'            => $infoCentre['CPOSTAL']??'',
            'LIV_VILLE'         => $infoCentre['VILLE1']??'',
            
            'CTC_TEL'           => $ctcCtr['CTC_TEL']??'',
            'CTC_FCT'           => $ctcCtr['CTC_FCT']??'',
            'CTC_NOM'           => $ctcCtr['CTC_NOM']??'',
            'CTC_FAX'           => $ctcCtr['CTC_FAX']??'',
            'CTC_MAIL'          => $ctcCtr['CTC_MAIL']??'',
            'CTC_GSM'           => $ctcCtr['CTC_GSM']??'',

            // ??
            'CHPSPECCLT'        => '',
            'ZONE_LIBRE'        => '',
            'COMMENT_INT'       => '',

            'CDE_COMPTOIR' => Sql::FALSE
        ];

        //centre de livraison
        if ($centreLivSession) {
            $arraySession['LIV_CTR']    = $centreLivSession;
        }

        if (($this->infoEntete['lib_panier']??'') == '') {
            $arraySession['lib_panier'] = $trad->t('En cours');
        }

        if (!$this->infoEntete) {
            $arraySession['flg_panier_modele'] = '0';
        }
        
        return $arraySession;
    }

    /**
     * @return array<mixed>
     */
    public function getTotalPanier(string $idPanier = '0')
    {
        $deviseEntete = $this->infoEntete['COD_DEV'];

        $allLigne = $this->panierLigne->getAllLignePanier($idPanier);
        $montant_total = 0;

        $convertDevise = new ConvertionDeviseService($this->pdo);

        foreach ($allLigne as $ligne) {
            if ($deviseEntete != $ligne['COD_DEV']) {
                $ligne['PX_ART'] = $ligne['PX_ART'] * $convertDevise->getTauxConvDevSrcToDevDest($ligne['COD_DEV'], $deviseEntete);
            }

            if ($ligne['TXTCOND'] != '' && $ligne['CONDITNT'] > 0) {
                $conditionnement = $ligne['CONDITNT'];
            } else {
                $conditionnement = 1;
            }

            if (Sql::paravrac($this->pdo, 'OXAPROC', 'AFFTTC') == 'O') {
                $ligne['PX_ART'] = $ligne['PX_ART'] * (1 + $ligne['TAUX_TVA'] / 100);
            }

            $prixBase = $ligne['PX_ART'];

            $montant_total += round($prixBase * $ligne['qte'] * $conditionnement, 2);
        }


        $_SESSION['montant_Total_Panier'] = $montant_total;
        
        return [
            'montant' => number_format($montant_total, 2, '.', ''),
            'nombreLigne' => count($allLigne),
        ];
    }

    public function initCS(?string $idPanier = null, ?string $idUser = null) : void
    {
        $idPanier = is_null($idPanier)? $_SESSION['id_panier']:$idPanier;
        $idUser   = is_null($idUser)? $_SESSION['id_user']:$idUser;

        $oxaUserCsDon = new OxaUserPanierCsDon($this->pdo);

        $oxaUserCsDon->delete([
            'id_user' => $idUser,
            'id_panier' => $idPanier,
            'ID_LIGNE' => '0'
        ]);

        $listeCSForInit[] = ['TAB_SRC' => 'CENTRE',     'ID' => $this->infoEntete['LIV_CTR']];
        $listeCSForInit[] = ['TAB_SRC' => 'HASTUTIL',   'ID' => $_SESSION["Session_Login"]];
        $listeCSForInit[] = ['TAB_SRC' => 'TYPDOC',     'ID' => sql::paravrac($this->pdo, 'OXAPROC', 'TYPDOCUMENT')];

        foreach ($listeCSForInit as $val) {
            foreach (ChampSupp::initCs('DA_ENTET', $val['TAB_SRC'], $val['ID'], $this->pdo) as $initCS) {
                $arrayInitCs['CS_EXTENTION'.Constante::spliter.'DA_ENTET'.Constante::spliter.''.Constante::spliter.$initCS['CHP_DESTI']] = $initCS['VALEUR'];
            }
        }

        $listeCS = ChampSupp::listeIdCS('DA_ENTET', $this->pdo);
        foreach ($listeCS as $cs) {
            $oxaUserCsDon->insert([
                'id_user'       => $idUser,
                'id_panier'     => $idPanier,
                'NUM_FIX'       => $cs['NUM_FIX'],
                'VALEUR'        => $arrayInitCs['CS_EXTENTION'.Constante::spliter.'DA_ENTET'.Constante::spliter.''.Constante::spliter.$cs['NUM_FIX']]??'',
                'ID_LIGNE'      => '0',
                'COD_TAB'       => 'DA_ENTET'
            ]);
        }
    }

    /**
     * @param array<mixed> $post
     * @return void
     */
    public function changeCentreLivraison($post)
    {
        (new OxaUserPanier($this->pdo))->update([
            'LIV_CTR'   => $post['LIV_CTR'],

            'LIV_ADR'   => $post['LIV_ADR'],
            'LIV_VILLE' => $post['LIV_VILLE'],
            'LIV_CP'    => $post['LIV_CP'],
            'LIV_PAYS'  => $post['LIV_PAYS'],
            'MOD_TRS'   => $post['MOD_TRS']??'',
        
            'CTC_NOM'   => $post['CTC_NOM'],
            'CTC_FCT'   => $post['CTC_FCT'],
            'CTC_FAX'   => $post['CTC_FAX'],
            'CTC_TEL'   => $post['CTC_TEL'],
            'CTC_GSM'   => $post['CTC_GSM'],
            'CTC_MAIL'  => $post['CTC_MAIL'],
        ], [
            'id_user' => $_SESSION['id_user'],
            'id_panier' => $_SESSION['id_panier'],
        ]);
        //info_livraison :: 242
        
        $panierFrsRepo = new PanierFrs($this->pdo);
        
        // appliquer le contact a tout les contact de livraison des bloc frs
        (new OxaUserPanierFourContact($this->pdo))->update([
            'CTC_NOM'   => $post['CTC_NOM'],
            'CTC_FCT'   => $post['CTC_FCT'],
            'CTC_FAX'   => $post['CTC_FAX'],
            'CTC_TEL'   => $post['CTC_TEL'],
            'CTC_GSM'   => $post['CTC_GSM'],
            'CTC_MAIL'  => $post['CTC_MAIL'],
        ], [
            'ID_USER' => $_SESSION['id_user'],
            'ID_PANIER' => $_SESSION['id_panier'],
            'CTC_TYPE' => 'livraison'
        ]);
        
        if ($this->infoEntete['LIV_CTR'] == $post['LIV_CTR']) {
            return;
        }
        
        $listeDoc = $panierFrsRepo->getListeDocCentreToDelete();
        foreach ($listeDoc as $doc) {
            if (!sql::boolSql($doc['LIEN_FICHIER'])) {
                Fichier::deleteFichierPj($doc['nom_piece_sys']);
            }
        }
        //on delete les doc lié a l'ancien centre
        $panierFrsRepo->deleteDocCentre();

        //on maj le centre de livraison et la mod de transport de toute les lignes
        (new PanierService($this->pdo))->updateCtrLiv($_SESSION['id_user'], $_SESSION['id_panier'], $post['LIV_CTR'], ($post['MOD_TRS']??''));

        //on va reactualisé les adresses de commande si ils ont piloté par les zone geo des centres emetteurs
        if (Sql::paravrac($this->pdo, 'OXAPROC', 'ZGEO_SUR_CTR_EMETTEUR') != 'O') {
            (new PanierFrsService($this->pdo))->updateAdresseCommandeByCentre($post['LIV_CTR'], true);

            $this->resetControlePanier($_SESSION['id_panier']);
        }

        //on genère les nouveau doc du centre
        $listeBlocFrs = (new OxaUserPanierFour($this->pdo))->findAll([
            'id_user' => $_SESSION['id_user'],
            'id_panier' => $_SESSION['id_panier']
        ]);

        $messageErreur = '';
        foreach ($listeBlocFrs as $infoBloc) {
            if (! Sql::boolSql($infoBloc['flg_add_pj'])) {
                continue;
            }
            $listeDoc = $panierFrsRepo->listeDocInit(
                '',
                $post['LIV_CTR'],
                '',
                '',
            );

            $panierFrsService = new PanierFrsService($this->pdo);

            foreach ($listeDoc as $pj) {
                $panierFrsService->createDoc($pj, true, $infoBloc['COD_FOURN'], $infoBloc['CRITERE_REGROUP'], $messageErreur);
            }
        }
    }

    public function resetControlePanier(string $idPanier):void
    {
        (new OxaUserPanierLigne($this->pdo))->update([
            'numerique_CTRL_FAIT' => Sql::setBoolSql(false),
        ], [
            'id_user' => $_SESSION['id_user'],
            'id_panier' => $idPanier,
        ]);
    }
}
