<?php

namespace Modules\Panier\Service;

use Entity\Model\Centre;
use Entity\Model\CsParIni;
use Entity\Model\OxaUserPanier;
use Entity\Model\OxaUserPanierCsDon;
use Entity\Model\OxaUserPanierFour;
use Entity\Model\OxaUserPanierFourClause;
use Entity\Model\OxaUserPanierFourContact;
use Entity\Model\OxaUserPanierImputation;
use Entity\Model\OxaUserPanierLigne;
use Helpers\ChampsSupplementaire\ChampSupp;
use Helpers\Outil\Sql;
use Helpers\Parametres\Constante;
use Modules\Ajax\Repository\Listes;
use Modules\GlobalApplication\Service\ConvertionDeviseService;
use Modules\Panier\Repository\PanierEntete;
use Modules\Panier\Repository\PanierFrs;
use Modules\Panier\Repository\PanierLigne;

class UpdateValuePanierService
{
    private \PDO $pdo;
    private bool $refresh;
    private bool $updateImputLigne;
    /**
     * @var array<mixed> $arrayUpdate
     */
    private array $arrayUpdate;
    public function __construct(\PDO $pdo)
    {
        $this->pdo = $pdo;
        $this->refresh = false;
        $this->updateImputLigne = false;
        $this->arrayUpdate = [];
    }

    public function refreshScreen():bool
    {
        return $this->refresh;
    }

    public function isUpdateImputLigne():bool
    {
        return $this->updateImputLigne;
    }

    /**
     * @return array<mixed>|null
     */
    public function getArrayUpdate() :?array
    {
        return $this->arrayUpdate;
    }
    
    /**
     * @param string $fields
     * @param string $value
     * @param array<mixed> $post
     * @return void
     */
    public function updateValue(string $fields, string $value, $post = []):void
    {
        $infoPanier = (new PanierEntete($this->pdo))->getEntetePanier($_SESSION['id_panier'], $_SESSION['id_user']);

        $majImputation      = false;
        $majLivraison       = false;

        $ligneImputation    = null;
        $idLigne            = null;
        $arrayUpdate        = [];
        $arrayUpdateCtc     = [];
        $infoGroupement     = [];

        $idLigne            = null;
        $codeGroupement     = null;
        
        //plusieurs objet on le spliter : les CS, Les lignes et les champs des blocs frs
        $idExplode = explode(Constante::spliter, $fields);
        $saveField = $fields;
        if (($idExplode[1]??'') == 'ligne') {
            $idLigne = $idExplode[2];
            $fields = $idExplode[0];
        } elseif (strpos($fields, 'CS_EXTENTION') === false && strpos($fields, 'text_CS_EXTENTION') === false && ($idExplode[1]??false)) {
            $codeGroupement = str_replace(Constante::oxaPipe, '|', $idExplode[1]);

            $fields = $idExplode[0];

            $infoGroupement = (new OxaUserPanierFour($this->pdo))->find([
                'id_user' => $_SESSION['id_user'],
                'id_panier' => $_SESSION['id_panier'],
                'CRITERE_REGROUP' => $codeGroupement
            ]);
        }
        switch ($fields) {
            case strpos($fields, 'CONTENU') === 0:
                $idClause = str_replace('CONTENU', '', $fields);

                (new OxaUserPanierFourClause($this->pdo))->update([
                    'CONTENU' => $value
                ], $idClause);

                break;
            case strpos($fields, 'CS_EXTENTION') === 0:
            case strpos($fields, 'text_CS_EXTENTION') === 0:
                $csField = explode(Constante::spliter, $fields);
                
                ChampSupp::insertCsPanier(
                    $this->pdo,
                    $csField[1],
                    $csField[3],
                    '',
                    $value
                );

                $updateCSlIGNE = (new CsParIni($this->pdo))->find([
                    'TAB_DESTI' => 'DA_LIGNE',
                    'TAB_SOUR' => 'DA_ENTET',
                    'CHP_SOUR' => $csField[3]
                ], ['CHP_DESTI'])['CHP_DESTI']??null;

                if ($updateCSlIGNE) {
                    ( new OxaUserPanierCsDon($this->pdo))->update([
                        'VALEUR' => $value
                    ], [
                        'id_user'       => $_SESSION['id_user'],
                        'id_panier'     => $_SESSION['id_panier'],
                        'NUM_FIX'       => $updateCSlIGNE,
                        'COD_TAB'       => 'DA_LIGNE',
                    ]);
                }

                break;
            case 'text_CTR_EMETT':
                $arrayUpdate = [
                    'OUPA_CENTRE_EMETTEUR' => $value,
                ];
                
                $siPar = sql::paravrac($this->pdo, 'OXAPROC', 'SOURCE_SI');

                if ($siPar == 'CEM' || $siPar == 'LSTCEM') {
                    $arrayUpdate['SI_CODE'] = '';
                    $arrayUpdate['CG_CODE'] = '';
    
                    $this->arrayUpdate['SECTIMP'] = '';
                    $this->arrayUpdate['CODGES'] = '';
                    $majImputation = true;
                }

                $specifique = new \Helpers\Additional\Specifique\Specifique();
                $namespaceSpecifique = $specifique->specifiqueFunction('\\Modules\\Panier\\Service\\UpdateSISpecifique');
                
                if (class_exists($namespaceSpecifique)) {
                    $si = \Helpers\Additional\Specifique\Specifique::specifique('\\Modules\\Panier\\Service\\UpdateSISpecifique', 'updateSI', $this->pdo, $value);
                
                    if ($si) {
                        $arrayUpdate['SI_CODE'] = $si;
                        $arrayUpdate['CG_CODE'] = '';
                        $majImputation = true;

                        $this->arrayUpdate['SECTIMP'] = $si;
                        $this->arrayUpdate['CODGES'] = '';
                    }
                }

                //voir si on doit faire cette action, elle n'était pas faite en V1
                if (Sql::paravrac($this->pdo, 'OXAPROC', 'ZGEO_SUR_CTR_EMETTEUR') == 'O') {
                    (new PanierFrsService($this->pdo))->updateAdresseCommandeByCentre($value, true);

                    (new PanierEnteteService($this->pdo))->resetControlePanier($_SESSION['id_panier']);

                    $this->refresh = true;
                }

                break;
            case 'text_COD_DEV':
                $this->refresh = true;

                $convertDevise = new ConvertionDeviseService($this->pdo);
                $taux = $convertDevise->getTauxConvDevSrcToDevDest($infoPanier['COD_DEV'], $value);
                (new PanierLigne($this->pdo))->majBudgetLignePanier((string)$taux);

                $arrayUpdate['COD_DEV'] = $value;
                $arrayUpdate['BUDGET_DA'] = $infoPanier['BUDGET_DA'] * (float)$taux;
                break;
            case strpos($fields, 'SECTIMP') === 0:
                $majImputation = true; // pour les axes d'imputation, on maj aussi les lignes
                
                if (!$idLigne) {
                    $ligneImputation = str_replace('SECTIMP', '', $fields);
                }

                $arrayUpdate = [
                    'SI_CODE' => $value,
                    'CG_CODE' => '',
                ];

                $this->arrayUpdate[str_replace('SECTIMP', 'CODGES', $saveField)] = '';

                $specifique = new \Helpers\Additional\Specifique\Specifique();
                $namespaceSpecifique = $specifique->specifiqueFunction('\\Modules\\Panier\\Service\\UpdateValueCtrLivraison');
                if (class_exists($namespaceSpecifique)) {
                    $this->refresh = \Helpers\Additional\Specifique\Specifique::specifique('\\Modules\\Panier\\Service\\UpdateValueCtrLivraison', 'initCentreLivraisonSI', $this->pdo, $value, $idLigne, false);
                }

                $specifique = new \Helpers\Additional\Specifique\Specifique();
                $namespaceSpecifique = $specifique->specifiqueFunction('\\Modules\\Panier\\Service\\UpdateCdcBySi');
                if (class_exists($namespaceSpecifique)) {
                    $cdc = \Helpers\Additional\Specifique\Specifique::specifique('\\Modules\\Panier\\Service\\UpdateCdcBySi', 'updateCdcBySI', $this->pdo, $infoPanier['CODE_STE'], $value);
                    if ($cdc) {
                        $arrayUpdate['CDC_CODE'] = $cdc;
                        $this->arrayUpdate[str_replace('SECTIMP', 'CODECOMP', $saveField)] = $cdc;
                    }
                }
                break;
            case strpos($fields, 'CODGES') === 0:
                $majImputation = true;
                if (!$idLigne) {
                    $ligneImputation = str_replace('CODGES', '', $fields);
                }
                
                $specifique = new \Helpers\Additional\Specifique\Specifique();
                $namespaceSpecifique = $specifique->specifiqueFunction('\\Modules\\Panier\\Service\\UpdateValueCtrLivraison');
                if (class_exists($namespaceSpecifique)) {
                    $this->refresh = \Helpers\Additional\Specifique\Specifique::specifique('\\Modules\\Panier\\Service\\UpdateValueCtrLivraison', 'initCentreLivraisonCG', $this->pdo, $value, $idLigne, $infoPanier['CODE_STE']);
                }

                $arrayUpdate = [
                    'CG_CODE' => $value,
                ];
                break;
            case strpos($fields, 'CODECOMP') === 0:
                $majImputation = true;
                if (!$idLigne) {
                    $ligneImputation = str_replace('CODECOMP', '', $fields);
                }

                $arrayUpdate = [
                    'CDC_CODE' => $value,
                ];

                break;
            case strpos($fields, 'SSCPTEANA') === 0:
                $majImputation = true;
                if (!$idLigne) {
                    $ligneImputation = str_replace('SSCPTEANA', '', $fields);
                }

                $arrayUpdate = [
                    'SCA_CODE' => $value,
                ];

                break;
            case strpos($fields, 'REPARTITION') === 0:
                $ligneImputation = str_replace('REPARTITION', '', $fields);

                $arrayUpdate = [
                    'REPARTITION' => $value,
                ];

                break;
            case 'CHIF_EXEC':
                $this->refresh = true;
                $arrayUpdate = [
                    $fields => $value
                ];
                
                break;

            case 'ADR':
                if ($value) {
                    $adresse = (new Listes($this->pdo))->adresseFournisseur([
                        'ADR_COMMANDE' => '0x54',
                        'filter_egal_CODE' => $infoGroupement['COD_FOURN']??'',
                        'filter_egal_COD_ADR' => $value,
                    ])[0]??[];
    
    
                    $arrayUpdate = [
                        'CPOSTAL'       => $adresse['CPOSTAL']??'',
                        'VILLE1'        => $adresse['VILLE1']??'',
                        'ADR'           => $adresse['ADRESSE']??'',
                        'CODE_PAYS'     => $adresse['CODPAYS']??'',
                    ];

                    $ctcFrs = (new PanierFrs($this->pdo))->getInfoCtcAdresse($infoGroupement['COD_FOURN']??'', $value);
                    
                    $arrayUpdateCtc = [
                        'CTC_NOM'       => $ctcFrs['CTC_NOM']??'',
                        'CTC_TEL'       => $ctcFrs['CTC_TEL']??'',
                        'CTC_FCT'       => $ctcFrs['CTC_FCT']??'',
                        'CTC_GSM'       => $ctcFrs['CTC_GSM']??'',
                    ];

    
                    if (sql::paravrac($this->pdo, 'PARAMGEN', 'CHOIX_INIT_FAXMAILFOUR_SUR_CDE') == 'O') {
                        $arrayUpdateCtc['CTC_FAX'] = $adresse['FAX']??'';
                        $arrayUpdateCtc['CTC_MAIL'] = $adresse['EMAIL']??'';
                    }
                } else {
                    $arrayUpdate = [
                        'CPOSTAL'       => '',
                        'VILLE1'        => '',
                        'ADR'           => '',
                        'CODE_PAYS'     => '',
                    ];
    
                    if (sql::paravrac($this->pdo, 'PARAMGEN', 'CHOIX_INIT_FAXMAILFOUR_SUR_CDE') == 'O') {
                        $arrayUpdateCtc['CTC_FAX'] = '';
                        $arrayUpdateCtc['CTC_MAIL'] = '';
                    }
                }

                break;
            case strpos($fields, 'TYP_ACH_CONF') === 0:
                if ($post['TYP_ACH_CONF'] != 'false') {
                    $arrayUpdate = [
                        'TYP_ACH' => $post['TYP_ACH']
                    ];
                } else {
                    $arrayUpdate = [
                        'TYP_ACH' => ''
                    ];
                }
                if ($infoGroupement['TYP_ACH']??'') {
                    $panierFrs = new PanierFrs($this->pdo);
                    $panierFrs->deleteClauseTypeAchat($codeGroupement);
                    $panierFrs->deletePjTypeAchat($codeGroupement);
                }
                break;
            case strpos($fields, 'TYP_ACH') === 0:
                $arrayUpdate = [
                    'TYP_ACH' => $post['TYP_ACH']
                ];
                

                if ($infoGroupement['TYP_ACH']??'') {
                    $panierFrs = new PanierFrs($this->pdo);
                    $panierFrs->deleteClauseTypeAchat($codeGroupement);
                    $panierFrs->deletePjTypeAchat($codeGroupement);
                }
                break;
            case 'text_CodeCtrLivraison':
                $arrayUpdate = [
                    'CodeCtrLivraison' => $value,
                ];

                $infoCentre = (new Centre($this->pdo))->find($value, ['TRS_INTER', 'MOD_TRS']);

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

                $this->refresh = true;
                break;
            case 'PER_REC_AUTO':
            case 'DATEDEBCONT':
            case 'DATEFINCONT':
            case 'DATELIVR':
                $arrayUpdate = [
                    $fields => $value
                ];
                $majLivraison = true;
                break;
            default:
                $fieldInsert = str_replace('text_', '', $fields);
                $arrayUpdate = [
                    $fieldInsert => $value
                ];
                break;
        }

        if ($arrayUpdate) {
            if ($ligneImputation) {
                (new OxaUserPanierImputation($this->pdo))->update($arrayUpdate, [
                    'id_user'   => $_SESSION['id_user'],
                    'id_panier' => $_SESSION['id_panier'],
                    'id_imputation' => $ligneImputation
                ]);
            } elseif ($idLigne) {
                (new OxaUserPanierLigne($this->pdo))->update($arrayUpdate, [
                    'id_user'   => $_SESSION['id_user'],
                    'id_panier' => $_SESSION['id_panier'],
                    'id_lig'    => $idLigne
                ]);

                $regroupement = CritereRegroupService::recalculCritereRegroup($this->pdo, $_SESSION['id_panier'], $idLigne);
                $this->refresh = $regroupement['changement'];
            } elseif ($codeGroupement) {
                (new OxaUserPanierFour($this->pdo))->update($arrayUpdate, [
                    'id_user'   => $_SESSION['id_user'],
                    'id_panier' => $_SESSION['id_panier'],
                    'CRITERE_REGROUP' => $codeGroupement
                ]);

                if ($arrayUpdateCtc) {
                    (new OxaUserPanierFourContact($this->pdo))->update($arrayUpdateCtc, [
                        'ID_USER'   => $_SESSION['id_user'],
                        'ID_PANIER' => $_SESSION['id_panier'],
                        'CTC_TYPE' => 'fournisseur',
                        'CRITERE_REGROUP' => $codeGroupement
                    ]);
                }
            } else {
                (new OxaUserPanier($this->pdo))->update($arrayUpdate, [
                    'id_user'   => $_SESSION['id_user'],
                    'id_panier' => $_SESSION['id_panier'],
                ]);

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

                foreach ($listeLigne as $ligne) {
                    $regroupement = CritereRegroupService::recalculCritereRegroup($this->pdo, $_SESSION['id_panier'], $ligne['id_lig']);

                    if (!$this->refresh) {
                        $this->refresh = $regroupement['changement'];
                    }
                }
            }

            if ($majImputation && !$idLigne) {
                $this->updateImputationHeritageLigne($arrayUpdate);
                $this->updateImputLigne = true;
            } elseif ($majImputation) {
                $this->updateCSByImputation($arrayUpdate, $idLigne);
            }

            if ($majLivraison && !$idLigne) {
                (new OxaUserPanierLigne($this->pdo))->update($arrayUpdate, [
                    'id_user'   => $_SESSION['id_user'],
                    'id_panier' => $_SESSION['id_panier'],
                    'CRITERE_REGROUP' => $codeGroupement
                ]);
            }

            if (($infoGroupement??false) && strpos($fields, 'TYP_ACH') === 0 || strpos($fields, 'TYP_ACH_CONF') === 0) {
                $panierFrsService = new PanierFrsService($this->pdo);
                if (!Sql::boolSql($infoGroupement['flg_add_pj'])) {
                    $explodeID = explode('|', $infoGroupement['CRITERE_REGROUP']);

                    $panierFrsService->initDoc(
                        $infoGroupement,
                        $infoPanier['CODE_STE'],
                        $explodeID[2],
                        $infoPanier['CENTRE_EMETTEUR'],
                        $infoGroupement['COD_FOURN'],
                    );
                }

                $panierFrsService->initClause($infoGroupement, $infoPanier['CODE_STE'], $arrayUpdate['TYP_ACH']);
                $panierFrsService->initPjTypeAchat($infoGroupement, $infoPanier['CODE_STE'], $arrayUpdate['TYP_ACH']);
            }
        }
    }

    /**
     * @param array<mixed> $arrayUpdate
     * @return void
     */
    public function updateImputationHeritageLigne($arrayUpdate)
    {
        unset($arrayUpdate['OUPA_CENTRE_EMETTEUR']);
        if (array_key_exists('CG_CODE', $arrayUpdate) && !array_key_exists('SI_CODE', $arrayUpdate)) {
            $infoPanier = (new PanierEntete($this->pdo))->getEntetePanier($_SESSION['id_panier'], $_SESSION['id_user']);
            (new OxaUserPanierLigne($this->pdo))->update($arrayUpdate, [
                'id_user'   => $_SESSION['id_user'],
                'id_panier' => $_SESSION['id_panier'],
                'SI_CODE' => $infoPanier['SI_CODE']
            ]);
        } else {
            (new OxaUserPanierLigne($this->pdo))->update($arrayUpdate, [
                'id_user'   => $_SESSION['id_user'],
                'id_panier' => $_SESSION['id_panier'],
            ]);
        }

        $this->updateCSByImputation($arrayUpdate);
    }
    /**
     * @param array<mixed> $arrayUpdate
     * @return void
     */
    public function updateCSByImputation($arrayUpdate, ?string $idLigne = null):void
    {
        $listeCSUpdate = [];
        if (isset($arrayUpdate['SI_CODE'])) {
            $listeCSUpdate += ChampSupp::initCs(
                'DA_LIGNE',
                'SECTIMPU',
                ChampSupp::autoCompletCodeEnrImputations($this->pdo, 'SECTIMPU', $arrayUpdate['SI_CODE']),
                $this->pdo
            );
        }
        if (isset($arrayUpdate['CDC_CODE'])) {
            $listeCSUpdate += ChampSupp::initCs(
                'DA_LIGNE',
                'CODECOMP',
                ChampSupp::autoCompletCodeEnrImputations($this->pdo, 'CODECOMP', $arrayUpdate['CDC_CODE']),
                $this->pdo
            );
        }
        if (isset($arrayUpdate['SCA_CODE'])) {
            $listeCSUpdate += ChampSupp::initCs(
                'DA_LIGNE',
                'SSCPTANA',
                ChampSupp::autoCompletCodeEnrImputations($this->pdo, 'SSCPTANA', $arrayUpdate['SCA_CODE']),
                $this->pdo
            );
        }

        foreach ($listeCSUpdate as $csUpdate) {
            (new OxaUserPanierCsDon($this->pdo))->update([
                'VALEUR' => $csUpdate['CS_VALEUR']
            ], [
                'id_user'   => $_SESSION['id_user'],
                'id_panier' => $_SESSION['id_panier'],
                'NUM_FIX'   => $csUpdate['CHP_DESTI'],
                'COD_TAB'   => 'DA_LIGNE',
            ]+($idLigne? [
                'ID_LIGNE' => $idLigne
            ]:[]));
        }
    }
}
