<?php
namespace Modules\API\APIInterne\OxaMobility\Controller;

use Entity\Model\Articles;
use Entity\Model\CCLDoc;
use Entity\Model\Centre;
use Entity\Model\Codecomp;
use Entity\Model\Codgest;
use Entity\Model\OxaUserPanier;
use Entity\Model\OxaUserPanierLigne;
use Entity\Model\Paravrac;
use Entity\Model\Sectimpu;
use Entity\Model\Societe;
use Entity\Model\SocUser;
use Entity\Model\Sscptana;
use Entity\Model\SSiteSto;
use GuzzleHttp\Psr7\Response;
use Helpers\CaracCompl\CaracCompl;
use Helpers\ChampsSupplementaire\ChampSupp;
use Helpers\Outil\Roles;
use Helpers\Outil\Sql;
use Helpers\Parametres\Constante;
use Helpers\Trad\Trad;
use Modules\Ajax\Repository\Listes;
use Modules\Panier\Repository\PanierEntete;
use Modules\Panier\Repository\PanierLigne;
use Modules\Panier\Service\CritereRegroupService;
use Modules\Panier\Service\PanierEnteteService;
use Modules\Panier\Service\PanierLigneService;
use Modules\Panier\Service\PanierService;
use Modules\Panier\Service\TransferePanierService;
use Modules\Panier\Service\UpdateValuePanierService;
use Modules\Panier\Validator\PanierValidator;
use Modules\Panier\WebService\SoumissionWebService;
use Modules\RechercheArticles\Service\OutilRechercheService;
use Helpers\User\User;

// phpcs:ignore
class MOBILITE_V1Controller extends AbsApiController
{
    /**
     * @return void|Response
     */
    public function init()
    {
        if (($_SESSION["Session_Login"] ?? '') == '') {
            $trad = $this->getTranslationService();

            $return['Statut'] = 'E';
            $return['MsgErreur'] = $trad->t('Vous devez être authentifié pour utiliser l\'API.');
            return $this->createApiResponse($return);
        }
    }
    
    // phpcs:ignore
    public function COPIEPANIERAction(): Response
    {
        $return = [];
        $trad   = $this->getTranslationService();
        $body   = $this->request->getMetaBody();

        $idPanierSource        = $body['idPanierSource'] ?? '';
        $forcageInitImputation = $body['forcageInitImputation'] ?? false;

        $infoPanier = (new OxaUserPanier($this->pdo))->find([
            'id_user' => $_SESSION['id_user'],
            'id_panier' => $idPanierSource
        ]);

        $transferePanier = new TransferePanierService($this->pdo, $idPanierSource, $_SESSION['id_user']);

        if ($infoPanier['flg_panier_modele']) {
            //si on cherche un panier modèle, alors on recréer une entete de panier, on viendra importer les articles dans ce panier
            (new PanierService($this->pdo))->delete('0', $trad, false);
            $societeIdentique = ($infoPanier['CODE_STE'] == $_SESSION["Session_SocUsr"]);

            if ($societeIdentique) {
                if ($forcageInitImputation) {
                    $initImputation = $forcageInitImputation;
                } else {
                    return $this->createApiResponse($return);
                }
            } else {
                $initImputation = $forcageInitImputation;
            }


            $transferePanier->importPanierModele($this->pdoOxaFT, $initImputation, $societeIdentique);
        } else {
            (new PanierService($this->pdo))->delete('0', $trad, true);
            $transferePanier->movePanier(0, $trad->t('En cours'), false);
        }

        return $this->createApiResponse($return);
    }

    // phpcs:ignore
    public function VALIDATIONPANIERAction(): Response
    {
        $body               = $this->request->getMetaBody();
        $return['Statut']   = 'O';
        $CdeComptoir        = $body['CdeComptoir'] ?? false;
        $CdeComptoir = filter_var($CdeComptoir, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
        $ChiffrageExecution = $body['ChiffrageExecution']; // C ou E

        if (!$ChiffrageExecution) {
            $return['Statut'] = 'E';
            return $this->createApiResponse($return);
        }

        $outilPanierService = new CritereRegroupService($this->pdo, $this->pdoOxaFT);
        $outilPanierService->regroupementCritere('', '', !$CdeComptoir);

        $validator = (new PanierValidator($this->pdo, $this->getTranslationService()));
        $validator->validatePanier();

        $listeError  = [];
        $stringError = '';
        if (!$validator->isValid()) {
            $errorTmp      = $validator->getError();
            $listeErrorTMP = explode('<br />', $errorTmp);

            foreach ($listeErrorTMP as $error) {
                if ($error) {
                    $return['Statut']                = 'E';
                    $listeError['erreur']['texte'][] = $error;

                    $stringError  .= "<erreur><texte>" . htmlspecialchars($error) . "</texte></erreur>";
                }
            }
        }

        if ($this->request->wantJson()) {
            $return['Retour'] = $listeError;
        } else {
            if ($stringError) {
                $return['Retour'] = 'replace1';
            }
        }

        if (!$listeError) {
            $xmlReturn   = (new SoumissionWebService(
                $this->pdo,
                $this->pdoOxaFT,
                $this->getTranslationService()
            ))->soumissionPanier(false, $CdeComptoir);
            $stringError = $xmlReturn->responseData;

            $stringError = (string) str_replace('<?xml version="1.0" encoding="UTF-8" standalone="no"?>', '', (string) $stringError);
            $stringError = (string) str_replace('<PanierOut', '<wsdl', $stringError);
            $stringError = (string) str_replace('</PanierOut>', '</wsdl>', $stringError);

            $return['Retour'] = 'replace1';
        }

        return $this->createApiResponse($return, $stringError);
    }

    // phpcs:ignore
    public function SOUMISSIONPANIERAction(): Response
    {
        $body             = $this->request->getMetaBody();
        $return['Statut'] = 'O';

        $CdeComptoir        = $body['CdeComptoir'] ?? false;
        $ChiffrageExecution = $body['ChiffrageExecution'] ?? null; // C ou E
        $codeFou            = $body['COD_FOURN'] ?? '';
        $critere            = $body['CRITERE_REGROUP'] ?? '';

        if (!$ChiffrageExecution) {
            $return['Statut'] = 'E';
            return $this->createApiResponse($return);
        }

        if (!$CdeComptoir) {
            $panierLigneService = new PanierLigneService($this->pdo, $this->pdoOxaFT, 'panier');
            $panierLigneService->calculFraisDePort();
        }

        $outilPanierService = new CritereRegroupService($this->pdo, $this->pdoOxaFT);
        $outilPanierService->regroupementCritere($critere, $codeFou);

        return $this->createApiResponse($return);
    }

    // phpcs:ignore
    public function SUPPRIMERPANIERAction(): Response
    {
        $return['Statut'] = 'O';
        $body             = $this->request->getMetaBody();
        $idPanier         = $body['id_panier'] ?? '';

        (new PanierService($this->pdo))->delete($idPanier, $this->getTranslationService());

        return $this->createApiResponse($return);
    }

    // phpcs:ignore
    public function SELECTENTETEAction(): Response
    {
        $body             = $this->request->getMetaBody();
        $json             = $this->request->wantJson();
        $return['Statut'] = 'O';
        $idPanier         = $body['id_panier'] ?? '';

        $return['Retour']['Entete'] = (new PanierEntete($this->pdo))->getEntetePanier($idPanier, $_SESSION['id_user']);

        $champSupp = new ChampSupp($this->pdo);
        $csTMP     = $champSupp->generateChampSupp('DA_ENTET', '', '', 'PANIER');

        $listeCSXml = '';
        foreach ($csTMP as $cs) {
            if ($json) {
                $return['Retour']['Entete']['ListChpSup']['ChpSup'][] = [
                    'CSNumFixe' => $cs['NUM_FIX'],
                    'CSValeur' => $cs['VALUECHAMPSUPP'],
                    'CSCodeTable' => Sql::boolSql($cs['CONTROLE']) ? $cs['TYPE'] : '',
                    'CSFormat' => $cs['FORMAT'],
                    'CSLibelle' => htmlspecialchars($cs['NOM']),
                    'CSOblig' => Sql::boolSql($cs['OBLIG']) ? 'true' : 'false',
                ];
            } else {
                $listeCSXml  .= ' <ChpSup>
                                    <CSNumFixe>' . $cs['NUM_FIX'] . '</CSNumFixe>
                                    <CSValeur>' . htmlspecialchars($cs['VALUECHAMPSUPP']) . '</CSValeur>
                                    <CSCodeTable>' . (Sql::boolSql($cs['CONTROLE']) ? $cs['TYPE'] : '') . '</CSCodeTable>
                                    <CSFormat>' . $cs['FORMAT'] . '</CSFormat>
                                    <CSLibelle>' . htmlspecialchars($cs['NOM']) . '</CSLibelle>
                                    <CSOblig>' . (Sql::boolSql($cs['OBLIG']) ? 'true' : 'false') . '</CSOblig>
                                </ChpSup>';
            }
        }

        if (!$json) {
            $return['Retour']['Entete']['ListChpSup']['ChpSup'] = 'replace1';
        }

        return $this->createApiResponse($return, $listeCSXml);
    }

    // phpcs:ignore
    public function UPDATEENTETEAction(): Response
    {
        $return['Statut'] = 'O';
        $body             = $this->request->getMetaBody();

        //todo specifique Bouygie SI
        $si      = $body['SI_CODE'] ?: '';
        $cg      = $body['CG_CODE'] ?: '';
        $cdc     = $body['CDC_CODE'] ?: '';
        $sca     = $body['SCA_CODE'] ?: '';
        $ctrLivr = $body['CtrLivraison'] ?: '';

        $listeCS = $body['ListChpSup'] ?? [];

        $updateValueService = new UpdateValuePanierService($this->pdo);
        if ($si) {
            $updateValueService->updateValue('SECTIMP', $si);
        }

        if ($cg) {
            $updateValueService->updateValue('CODGES', $cg);
        }

        if ($cdc) {
            $updateValueService->updateValue('CODECOMP', $cdc);
        }

        if ($sca) {
            $updateValueService->updateValue('SSCPTEANA', $sca);
        }

        if ($ctrLivr && Roles::droitsUtilisateur($this->pdo, 'OX_MOD_ADL')) {
            $centreLivraison = (new PanierEntete($this->pdo))->getInfoCentre($ctrLivr);
            (new PanierEnteteService($this->pdo))->changeCentreLivraison($centreLivraison);
        }

        if ($listeCS) {
            if (isset($listeCS['ChpSup'])) {
                $listeCS = $listeCS['ChpSup'];
            }
            foreach ($listeCS as $cs) {
                $value  = $cs['CSValeur'] ?: '';
                $numFix = $cs['CSNumFixe'];
                $csName = 'CS_EXTENTION' . Constante::spliter . 'DA_ENTET' . Constante::spliter . '' . Constante::spliter . $numFix;

                $updateValueService->updateValue($csName, $value);
            }
        }

        return $this->createApiResponse($return);
    }

    // phpcs:ignore
    public function UPDATESESSIONAction(): Response
    {
        $body             = $this->request->getMetaBody();
        $return['Statut'] = 'O';

        $langue    = $body['Langue'] ?? '';
        $emetteur  = $body['CtrEmetteur'] ?? '';
        $livraison = $body['CtrLivraison'] ?? '';
        $si        = $body['SI_CODE'] ?? '';
        $cg        = $body['CG_CODE'] ?? '';
        $cdc       = $body['CDC_CODE'] ?? '';
        $sca       = $body['SCA_CODE'] ?? '';
        $codeSte   = $body['CODE_STE'] ?? '';

        $validator = $this->createValidator();

        $listeSte = match (Sql::toBool(User::getUser()->getHastutil()['UTIMULTI'])) {
            true => array_column((new Societe($this->pdo))->findAll(null, ['CODE_STE']), 'CODE_STE'),
            default => array_column((new SocUser($this->pdo))->findAll(['COD_USR' => User::getUser()->getCodeUser()], ['COD_STE']), 'COD_STE') + ['COD_STE' => $codeSte]
        };

        if (!empty($codeSte) && in_array($codeSte, $listeSte)) {
            User::getUser()->getHastutil()['CODE_STE'] = $codeSte;
        } elseif (!empty($codeSte)) {
            return $this->createApiResponse([
                'Statut' => 'E',
                'MsgError' => $this->getTranslationService()->t('Ce code société est invalide.')
            ]);
        } else {
            $codeSte = User::getUser()->getHastutil()['CODE_STE'];
        }

        $listeCentre = (new Centre($this->pdo))->findAll(['CODE_STE' => $codeSte], ['CODE_CTR']);
        if (count($listeCentre) > 0) {
            $listeCentre = array_column($listeCentre, 'CODE_CTR');
        }

        if (($langue != '') && $validator->zoom('Langues', $langue, $this->getTranslationService()->t('Langue'), $this->pdo)) {
            $_SESSION['Session_Langue'] = $langue;
        }

        if (($emetteur != '')
            && in_array($emetteur, $listeCentre)
        ) {
            $_SESSION['Session_CodeCtrEmetteur'] = $emetteur;
        } elseif (!empty($emetteur)) {
            $validator->setError("Ce centre émetteur n'est pas associé à votre société.");
        }

        if (($livraison != '')
            && in_array($livraison, $listeCentre)
        ) {
            $_SESSION['Session_CodeCtrLivraison'] = $livraison;
        } elseif (!empty($livraison)) {
            $validator->setError("Ce centre de livraison n'est pas associé à votre société.");
        }

        $siSecto  = Sql::toBool((new Paravrac($this->pdo))->find(['TYPEPARV' => 'PARAMSTE', 'CODEPARV' => 'SISECTOR'])['LIB01PARV'] ?? '');
        $cdcSecto = Sql::toBool((new Paravrac($this->pdo))->find(['TYPEPARV' => 'PARAMSTE', 'CODEPARV' => 'CDCSECTO'])['LIB01PARV'] ?? '');
        $scaSecto = Sql::toBool((new Paravrac($this->pdo))->find(['TYPEPARV' => 'PARAMSTE', 'CODEPARV' => 'SCASECTO'])['LIB01PARV'] ?? '');

        if (!empty($si) && (new Sectimpu($this->pdo))->find(['CODE_SI' => $si] + ($siSecto ? ['CODE_STE' => $codeSte] : []))) {
            $_SESSION['Session_SectionImputation'] = $si;
        } elseif (!empty($si)) {
            $validator->setError("Cette section d'imputation est non valide.");
        }
        
        if (!empty($cg) && (new Codgest($this->pdo))->find(['CODE_STE' => $codeSte, 'CODE_GES' => $cg]) + ($siSecto ? ['CODE_SI' => $si] : [])) {
            $_SESSION['Session_CG'] = $cg;
        } elseif (!empty($cg)) {
            $validator->setError("Ce code gestion est non valide.");
        }

        if (!empty($cdc) && (new Codecomp($this->pdo))->find(['CODE_CDC' => $cdc] + ($cdcSecto ? ['CODE_STE' => $codeSte] : []))) {
            $_SESSION['Session_CDC'] = $cdc;
        } elseif (!empty($cdc)) {
            $validator->setError("Ce code complémentaire est non valide.");
        }

        if (!empty($sca) && (new Sscptana($this->pdo))->find(['CODE_SCA' => $sca] + ($scaSecto ? ['CODE_STE' => $codeSte] : []))) {
            $_SESSION['Session_SCA'] = $sca;
        } elseif (!empty($sca)) {
            $validator->setError("Ce sous compte d'analyse est non valide.");
        }

        if ($validator->getError()) {
            $return['Statut']    = 'E';
            $return['MsgErreur'] = trim(str_replace('<br />', ' ', $validator->getError()));
            return $this->createApiResponse($return);
        }

        $nombreLigne = (new PanierLigne($this->pdo))->getNbLignePanier($_SESSION['id_panier'], $_SESSION['id_user']);
        if ($nombreLigne == 0) {
            (new PanierEnteteService($this->pdo))->initPanierEntete($this->getTranslationService(), true);
        }

        $centre = (new Centre($this->pdo))->find($_SESSION['Session_CodeCtrLivraison']);
        if ($centre) {
            $site = (new SSiteSto($this->pdo))->find($centre['SITSTOCK']);
        }

        $return['Retour']['CodeSiteStock'] = $site['SITE'] ?? '';
        $return['Retour']['LibSiteStock']  = htmlspecialchars($site['DESIGN'] ?? '');

        //return OutilExtension::checkExtension($body, $return, $json);
        return $this->createApiResponse($return);
    }

    // phpcs:ignore
    public function SELECTLIGNEARTICLEAction(): Response
    {
        $body             = $this->request->getMetaBody();
        $return['Statut'] = 'O';

        $idPanier = $body['id_panier'] ?? '';
        $codeFou  = $body['COD_FOURN'] ?? '';
        $critere  = $body['CRITERE_REGROUP'] ?? '';

        //TODO VOIR AVEC RA LE RETOUR

        $listeLigne = (new PanierLigne($this->pdo))->listePanierMobilite($idPanier, $critere, $codeFou);

        foreach ($listeLigne as &$ligne) {
            $adresse = (new Listes($this->pdo))->adresseFournisseur([
                'filter_egal_CODE' => $ligne['COD_FOURN'] ?? '',
            ], false, false, [
                'ADR' => $ligne['FOU_ADR'],
                'VILLE1' => $ligne['FOU_VILLE1'],
                'CPOSTAL' => $ligne['FOU_CPOSTAL'],
                'CODPAYS' => $ligne['FOU_CODE_PAYS'],
            ])[0] ?? [];

            if (!$adresse) {
                $adresse = (new Listes($this->pdo))->adresseFournisseur([
                    'filter_egal_CODE' => $ligne['COD_FOURN'] ?? '',
                    'ADR_COMMANDE' => '0x54',
                ], false, false)[0] ?? [];
            }

            $ligne['Fournisseur'] = [
                'CODE_ADR' => $adresse['COD_ADR'],
                'RS' => ($adresse['LIBELLE']),
                'ADR' => ($adresse['ADRESSE']),
                'VILLE' => ($adresse['VILLE']),
                'CODE_PAYS' => $adresse['CODPAYS'],
                'TEL' => $adresse['TELEPHONE'],
                'FAX' => $adresse['FAX'],
                'TELEX' => $adresse['TELEX'],
                'EMAIL' => $adresse['EMAIL'],
                'CPOSTAL' => $adresse['CPOSTAL'],
                'VILLE1' => ($adresse['VILLE1']),
                'ADR_COMMANDE' => sql::boolSql($adresse['ADR_COMMANDE']),
            ];

            $champSupp = new ChampSupp($this->pdo);
            $csTMP     = $champSupp->generateChampSupp('DA_LIGNE', '', '', 'PANIER', false, null, false, $ligne['id_lig']);

            $listeCS = [];
            foreach ($csTMP as $cs) {
                $listeCS[] = [
                    'CSNumFixe' => $cs['NUM_FIX'],
                    'CSValeur' => ($cs['VALUECHAMPSUPP']),
                    'CSCodeTable' => Sql::boolSql($cs['CONTROLE']) ? $cs['TYPE'] : '',
                    'CSFormat' => $cs['FORMAT'],
                    'CSLibelle' => ($cs['NOM']),
                    'CSOblig' => Sql::boolSql($cs['OBLIG']) ? 'true' : 'false',
                ];
            }

            $ligne['ListChpSup']['ChpSup'] = $listeCS;

            $caracCompl = (new CaracCompl($this->pdo))->getCCDocc('PAN', $idPanier, $ligne['id_lig'], $_SESSION['id_user']);

            $listeCC = [];
            foreach ($caracCompl as $CC) {
                $listeCC[] = [
                    'CC_ID' => $CC['CC_ID'],
                    'CC_IS_TITLE' => sql::boolSql($CC['CC_IS_TITLE']) ? 'true' : 'false',
                    'CC_NAME' => ($CC['NOM']),
                    'CC_FORMAT' => $CC['FORMAT'],
                    'CC_TYPE' => $CC['CC_TYPE'],
                    'CC_REQUIRED' => sql::boolSql($CC['CC_REQUIRED']) ? 'true' : 'false',
                    'CC_VALUE' => ($CC['VALEUR'])
                ];
            }

            $ligne['ListCarComp']['CarComp'] = $listeCC;
        }

        $xml = '';
        if ($this->request->wantJson()) {
            $return['Retour']['Ligne'] = $listeLigne;
        } else {
            foreach ($listeLigne as $ligneFinal) {
                $xml  .= "<Ligne>";

                foreach ($ligneFinal as $k => $v) {
                    if ($k != 'Fournisseur' && $k != 'ListChpSup' && $k != 'ListCarComp') {
                        $xml  .= "<" . $k . ">" . htmlspecialchars($v) . "</" . $k . ">";
                    }
                }

                $xml  .= "  <Fournisseur>
                                <CODE_ADR>" . $ligneFinal['Fournisseur']['CODE_ADR'] . "</CODE_ADR><CODE>712533</CODE>
                                <RS>" . htmlspecialchars($ligneFinal['Fournisseur']['RS']) . "</RS>
                                <ADR>" . htmlspecialchars($ligneFinal['Fournisseur']['ADR']) . "</ADR>
                                <VILLE>" . htmlspecialchars($ligneFinal['Fournisseur']['VILLE']) . "</VILLE>
                                <CODE_PAYS>" . $ligneFinal['Fournisseur']['CODE_PAYS'] . "</CODE_PAYS>
                                <TEL>" . $ligneFinal['Fournisseur']['TEL'] . "</TEL>
                                <FAX>" . $ligneFinal['Fournisseur']['FAX'] . "</FAX>
                                <TELEX>" . $ligneFinal['Fournisseur']['TELEX'] . "</TELEX>
                                <EMAIL>" . $ligneFinal['Fournisseur']['EMAIL'] . "</EMAIL>
                                <CPOSTAL>" . $ligneFinal['Fournisseur']['CPOSTAL'] . "</CPOSTAL>
                                <VILLE1>" . htmlspecialchars($ligneFinal['Fournisseur']['VILLE1']) . "</VILLE1>
                                <ADR_COMMANDE>" . $ligneFinal['Fournisseur']['ADR_COMMANDE'] . "</ADR_COMMANDE>
                            </Fournisseur>
                            <ListChpSup>";

                foreach ($ligneFinal['ListChpSup']['ChpSup'] as $cs) {
                    $xml  .= "<ChpSup>
                                            <CSNumFixe>" . $cs['CSNumFixe'] . "</CSNumFixe>
                                            <CSValeur>" . htmlspecialchars($cs['CSValeur']) . "</CSValeur>
                                            <CSOblig>" . $cs['CSOblig'] . "</CSOblig>
                                            <CSCodeTable>" . $cs['CSCodeTable'] . "</CSCodeTable>
                                            <CSFormat>" . $cs['CSFormat'] . "</CSFormat>
                                            <CSLibelle>" . htmlspecialchars($cs['CSLibelle']) . "</CSLibelle>
                                        </ChpSup>";
                }

                $xml  .= "   </ListChpSup>

                            <ListCarComp>";

                foreach ($ligneFinal['ListCarComp']['CarComp'] as $CC) {
                    $xml  .= "<CarComp>
                                            <CC_ID>" . $CC['CC_ID'] . "</CC_ID>
                                            <CC_IS_TITLE>" . $CC['CC_IS_TITLE'] . "</CC_IS_TITLE>
                                            <CC_NAME>" . htmlspecialchars($CC['CC_NAME']) . "</CC_NAME>
                                            <CC_FORMAT>" . $CC['CC_FORMAT'] . "</CC_FORMAT>
                                            <CC_TYPE>" . $CC['CC_TYPE'] . "</CC_TYPE>
                                            <CC_REQUIRED>" . $CC['CC_REQUIRED'] . "</CC_REQUIRED>
                                            <CC_VALUE>" . htmlspecialchars($CC['CC_VALUE']) . "</CC_VALUE>R'])
                                        </CarComp>";
                }

                $xml  .= "   </ListCarComp>
                        </Ligne>";
            }

            if ($listeLigne) {
                $return['Retour'] = 'replace1';
            }
        }
        return $this->createApiResponse($return, $xml);
    }

    // phpcs:ignore
    public function SELECTPANIERCOMPLETAction(): Response
    {
        $return['Statut'] = 'O';
        $body             = $this->request->getMetaBody();
        $idPanier         = $body['id_panier'] ?? '';

        $return['Retour']['Entete'] = (new PanierEntete($this->pdo))->getEntetePanier($idPanier, $_SESSION['id_user']);

        $champSupp = new ChampSupp($this->pdo);
        $csTMP     = $champSupp->generateChampSupp('DA_ENTET', '', '', 'PANIER');

        $listeCSXml = '';
        foreach ($csTMP as $cs) {
            if ($this->request->wantJson()) {
                $return['Retour']['Entete']['ListChpSup']['ChpSup'][] = [
                    'CSNumFixe' => $cs['NUM_FIX'],
                    'CSValeur' => $cs['VALUECHAMPSUPP'],
                    'CSCodeTable' => Sql::boolSql($cs['CONTROLE']) ? $cs['TYPE'] : '',
                    'CSFormat' => $cs['FORMAT'],
                    'CSLibelle' => htmlspecialchars($cs['NOM']),
                    'CSOblig' => Sql::boolSql($cs['OBLIG']) ? 'true' : 'false',
                ];
            } else {
                $listeCSXml  .= ' <ChpSup>
                                    <CSNumFixe>' . $cs['NUM_FIX'] . '</CSNumFixe>
                                    <CSValeur>' . htmlspecialchars($cs['VALUECHAMPSUPP']) . '</CSValeur>
                                    <CSCodeTable>' . (Sql::boolSql($cs['CONTROLE']) ? $cs['TYPE'] : '') . '</CSCodeTable>
                                    <CSFormat>' . $cs['FORMAT'] . '</CSFormat>
                                    <CSLibelle>' . htmlspecialchars($cs['NOM']) . '</CSLibelle>
                                    <CSOblig>' . (Sql::boolSql($cs['OBLIG']) ? 'true' : 'false') . '</CSOblig>
                                </ChpSup>';
            }
        }

        if (!$this->request->wantJson()) {
            $return['Retour']['Entete']['ListChpSup'] = 'replace1';
        }

        $listeLigne = (new PanierLigne($this->pdo))->listePanierMobilite($idPanier);

        foreach ($listeLigne as &$ligne) {
            $adresse = (new Listes($this->pdo))->adresseFournisseur([
                'filter_egal_CODE' => $ligne['COD_FOURN'] ?? '',
            ], false, false, [
                'ADR' => $ligne['FOU_ADR'],
                'VILLE1' => $ligne['FOU_VILLE1'],
                'CPOSTAL' => $ligne['FOU_CPOSTAL'],
                'CODPAYS' => $ligne['FOU_CODE_PAYS'],
            ])[0] ?? [];

            if (!$adresse) {
                $adresse = (new Listes($this->pdo))->adresseFournisseur([
                    'filter_egal_CODE' => $ligne['COD_FOURN'] ?? '',
                    'ADR_COMMANDE' => '0x54',
                ], false, false)[0] ?? [];
            }

            $ligne['Fournisseur'] = [
                'CODE_ADR' => $adresse['COD_ADR'],
                'RS' => ($adresse['LIBELLE']),
                'ADR' => ($adresse['ADRESSE']),
                'VILLE' => ($adresse['VILLE']),
                'CODE_PAYS' => $adresse['CODPAYS'],
                'TEL' => $adresse['TELEPHONE'],
                'FAX' => $adresse['FAX'],
                'TELEX' => $adresse['TELEX'],
                'EMAIL' => $adresse['EMAIL'],
                'CPOSTAL' => $adresse['CPOSTAL'],
                'VILLE1' => ($adresse['VILLE1']),
                'ADR_COMMANDE' => sql::boolSql($adresse['ADR_COMMANDE']),
            ];

            $champSupp = new ChampSupp($this->pdo);
            $csTMP     = $champSupp->generateChampSupp('DA_LIGNE', '', '', 'PANIER', false, null, false, $ligne['id_lig']);

            $listeCS = [];
            foreach ($csTMP as $cs) {
                $listeCS[] = [
                    'CSNumFixe' => $cs['NUM_FIX'],
                    'CSValeur' => ($cs['VALUECHAMPSUPP']),
                    'CSCodeTable' => Sql::boolSql($cs['CONTROLE']) ? $cs['TYPE'] : '',
                    'CSFormat' => $cs['FORMAT'],
                    'CSLibelle' => ($cs['NOM']),
                    'CSOblig' => Sql::boolSql($cs['OBLIG']) ? 'true' : 'false',
                ];
            }

            $ligne['ListChpSup']['ChpSup'] = $listeCS;

            $caracCompl = (new CaracCompl($this->pdo))->getCCDocc('PAN', $idPanier, $ligne['id_lig'], $_SESSION['id_user']);

            $listeCC = [];
            foreach ($caracCompl as $CC) {
                $listeCC[] = [
                    'CC_ID' => $CC['CC_ID'],
                    'CC_IS_TITLE' => sql::boolSql($CC['CC_IS_TITLE']) ? 'true' : 'false',
                    'CC_NAME' => ($CC['NOM']),
                    'CC_FORMAT' => $CC['FORMAT'],
                    'CC_TYPE' => $CC['CC_TYPE'],
                    'CC_REQUIRED' => sql::boolSql($CC['CC_REQUIRED']) ? 'true' : 'false',
                    'CC_VALUE' => ($CC['VALEUR'])
                ];
            }

            $ligne['ListCarComp']['CarComp'] = $listeCC;
        }

        $xml = null;
        if ($this->request->wantJson()) {
            $return['Retour']['Ligne'] = $listeLigne;
        } else {
            foreach ($listeLigne as $ligneFinal) {
                $xml  .= "<Ligne>";

                foreach ($ligneFinal as $k => $v) {
                    if ($k != 'Fournisseur' && $k != 'ListChpSup' && $k != 'ListCarComp') {
                        $xml  .= "<" . $k . ">" . htmlspecialchars($v) . "</" . $k . ">";
                    }
                }

                $xml  .= "  <Fournisseur>
                                <CODE_ADR>" . $ligneFinal['Fournisseur']['CODE_ADR'] . "</CODE_ADR><CODE>712533</CODE>
                                <RS>" . htmlspecialchars($ligneFinal['Fournisseur']['RS']) . "</RS>
                                <ADR>" . htmlspecialchars($ligneFinal['Fournisseur']['ADR']) . "</ADR>
                                <VILLE>" . htmlspecialchars($ligneFinal['Fournisseur']['VILLE']) . "</VILLE>
                                <CODE_PAYS>" . $ligneFinal['Fournisseur']['CODE_PAYS'] . "</CODE_PAYS>
                                <TEL>" . $ligneFinal['Fournisseur']['TEL'] . "</TEL>
                                <FAX>" . $ligneFinal['Fournisseur']['FAX'] . "</FAX>
                                <TELEX>" . $ligneFinal['Fournisseur']['TELEX'] . "</TELEX>
                                <EMAIL>" . $ligneFinal['Fournisseur']['EMAIL'] . "</EMAIL>
                                <CPOSTAL>" . $ligneFinal['Fournisseur']['CPOSTAL'] . "</CPOSTAL>
                                <VILLE1>" . htmlspecialchars($ligneFinal['Fournisseur']['VILLE1']) . "</VILLE1>
                                <ADR_COMMANDE>" . $ligneFinal['Fournisseur']['ADR_COMMANDE'] . "</ADR_COMMANDE>
                            </Fournisseur>
                            <ListChpSup>";

                foreach ($ligneFinal['ListChpSup']['ChpSup'] as $cs) {
                    $xml  .= "<ChpSup>
                                            <CSNumFixe>" . $cs['CSNumFixe'] . "</CSNumFixe>
                                            <CSValeur>" . htmlspecialchars($cs['CSValeur']) . "</CSValeur>
                                            <CSOblig>" . $cs['CSOblig'] . "</CSOblig>
                                            <CSCodeTable>" . $cs['CSCodeTable'] . "</CSCodeTable>
                                            <CSFormat>" . $cs['CSFormat'] . "</CSFormat>
                                            <CSLibelle>" . htmlspecialchars($cs['CSLibelle']) . "</CSLibelle>
                                        </ChpSup>";
                }

                $xml  .= "   </ListChpSup>

                            <ListCarComp>";

                foreach ($ligneFinal['ListCarComp']['CarComp'] as $CC) {
                    $xml  .= "<CarComp>
                                            <CC_ID>" . $CC['CC_ID'] . "</CC_ID>
                                            <CC_IS_TITLE>" . $CC['CC_IS_TITLE'] . "</CC_IS_TITLE>
                                            <CC_NAME>" . htmlspecialchars($CC['CC_NAME']) . "</CC_NAME>
                                            <CC_FORMAT>" . $CC['CC_FORMAT'] . "</CC_FORMAT>
                                            <CC_TYPE>" . $CC['CC_TYPE'] . "</CC_TYPE>
                                            <CC_REQUIRED>" . $CC['CC_REQUIRED'] . "</CC_REQUIRED>
                                            <CC_VALUE>" . htmlspecialchars($CC['CC_VALUE']) . "</CC_VALUE>R'])
                                        </CarComp>";
                }

                $xml  .= "   </ListCarComp>
                        </Ligne>";
            }

            if ($listeLigne) {
                $return['Retour']['Lignes'] = 'replace2';
            }
        }

        return $this->createApiResponse($return, ['replace1' => $listeCSXml, 'replace2' => $xml]);
    }

    // phpcs:ignore
    public function DELETELIGNEARTICLEAction(): Response
    {
        $return['Statut'] = 'O';
        $body             = $this->request->getMetaBody();
        $idPanier         = $body['id_panier'] ?? '';
        $id_lig           = $body['id_lig'] ?? '';

        if ((!(new OxaUserPanier($this->pdo))->find(['id_user' => User::getUser()->getIdUserPanier(), 'id_panier' => $idPanier]))
            || empty($id_lig)
        ) {
            return $this->createApiResponse([
                'Statut' => 'E',
                'MsgErreur' => $this->getTranslationService()->t('Une erreur est survenue.')
            ]);
        }

        if ($idPanier) {
            $_SESSION['id_panier'] = $idPanier;
        }

        $panierLigneService = new PanierLigneService($this->pdo, $this->pdoOxaFT, '');
        $panierLigneService->deleteLignepanier(['id_lig' => $id_lig]);

        return $this->createApiResponse($return);
    }

    // phpcs:ignore
    public function UPDATELIGNEARTICLEAction(): Response
    {
        $body             = $this->request->getMetaBody();
        $return['Statut'] = 'O';

        $articleToUpdate = [];
        $listeCS         = [];
        $listeCC         = [];

        $idLigne = null;
        foreach ($body as $k => $v) {
            if ($k == 'COD_ADR') {
                if (!$v && $v !== '0' && $v !== 0) {
                    $codeAdresse = '';
                } else {
                    $codeAdresse = $v;
                }
            } elseif ($k == 'id_lig') {
                $idLigne = $v;
            } elseif ($k == 'COD_FOURN') {
            } elseif ($k == 'DTE_LIV') {
                if (!$v) {
                    $dteLivr = '';
                } else {
                    $dteLivr = $v;
                }
            } elseif ($k == 'ListChpSup') {
                if (isset($v['ChpSup']['CSNumFixe'])) {
                    $listeCS['CS_EXTENTION' . Constante::spliter . 'DA_LIGNE' . Constante::spliter . '' . Constante::spliter . $v['ChpSup']['CSNumFixe']] = $v['ChpSup']['CSValeur'];
                } else {
                    foreach ($v['ChpSup'] as $cs) {
                        if (!$cs['CSValeur']) {
                            $cs['CSValeur'] = '';
                        }
                        $listeCS['CS_EXTENTION' . Constante::spliter . 'DA_LIGNE' . Constante::spliter . '' . Constante::spliter . $cs['CSNumFixe']] = $cs['CSValeur'];
                    }
                }
            } elseif ($k == 'ListCarComp') {
                if (isset($v['CarComp']['CC_ID'])) {
                    $listeCC[] = [
                        'CC_ID' => $v['CarComp']['CC_ID'],
                        'CC_VALUE' => $v['CarComp']['CC_VALUE'],
                    ];
                } else {
                    foreach ($v['CarComp'] as $cc) {
                        $listeCC[] = [
                            'CC_ID' => $cc['CC_ID'],
                            'CC_VALUE' => $cc['CC_VALUE'],
                        ];
                    }
                }
            } elseif ($k == 'qte' || $k == 'id_panier') {
            } elseif (in_array($k, ['PX_ART', 'DES_COMP', 'SI_CODE', 'CG_CODE', 'CDC_CODE', 'SCA_CODE'])) {
                if (!$v) {
                    $articleToUpdate[$k] = '';
                } else {
                    $articleToUpdate[$k] = $v;
                }
            }
        }

        if (!$idLigne) {
            $return['Statut']    = 'E';
            $return['MsgErreur'] = ($this->getTranslationService())->t('Le code ligne est obligatoire.');
            return $this->createApiResponse($return);
        }

        $isArticlePanier = (new OxaUserPanierLigne($this->pdo))->find($idLigne);
        if ($isArticlePanier && isset($body['qte'])) {
            $panierLigneService    = new PanierLigneService($this->pdo, $this->pdoOxaFT, 'panier');
            $isArticlePanier['PU'] = $isArticlePanier['PX_ART'];
            $panierLigneService->updateQteArticle($isArticlePanier, floatval($body['qte']));
        }
        (new OxaUserPanierLigne($this->pdo))->update($articleToUpdate, ['id_lig' => $idLigne]);

        $this->updateCodeAdresse($idLigne, $codeAdresse ?? null);
        $this->updateDateLivraison($idLigne, $dteLivr ?? null);

        if ($listeCS) {
            ChampSupp::updateCsPanier($this->pdo, $idLigne, $listeCS);
        }

        foreach ($listeCC as $cc) {
            (new CCLDoc($this->pdo))->update([
                'DOC_TYPE' => 'PAN',
                'DOC_NUM' => $_SESSION['id_panier'],
                'DOC_LINE_NUM' => $idLigne,
                'ID_USER_BASKET' => $_SESSION['id_user'],
                'CC_ID' => $cc['CC_ID']
            ], [
                'CC_VALUE' => $cc['CC_VALUE']
            ]);
        }

        return $this->createApiResponse($return);
    }

    // phpcs:ignore
    public function INSERTLIGNEARTICLEAction(): Response
    {
        $body             = $this->request->getMetaBody();
        $return['Statut'] = 'O';

        $articleToAdd = [
            'CdeComptoir' => false,
            'RECEP_AUTO' => false,
            'ARTASSOCIE' => false,
        ];

        foreach ($body as $k => $v) {
            if (!$v) {
                $articleToAdd[$k] = '';
            } else {
                $articleToAdd[$k] = $v;
            }

            if ($k == 'COD_ADR') {
                if (!$v) {
                    $codeAdresse = '';
                } else {
                    $codeAdresse = $v;
                }
            } elseif ($k == 'CdeComptoir') {
                $articleToAdd['CdeComptoir'] = sql::boolSql($body['CdeComptoir']);
            }
        }

        if (!isset($articleToAdd['qte']) || $articleToAdd['qte'] == 0) {
            $return['Statut']    = 'E';
            $return['MsgErreur'] = ($this->getTranslationService())->t('La quantité est obligatoire.');
            return $this->createApiResponse($return);
        }

        //ticket mobilite 492 : probleme article site de stock
        $infoCentre = (new Centre($this->pdo))->find($articleToAdd['CTR_LIVR']);
        if ($articleToAdd['COD_FOURN'] == '' && $articleToAdd['CTR_LIVR'] != '' && $infoCentre['SITSTOCK']) {
            $articleToAdd['COD_FOURN'] = 'RESERVESTOCK';
        }

        if ($articleToAdd['type_de_ligne'] == '1' && $articleToAdd['COD_ART'] != '') {
            $articleToAdd['COD_GAM'] = 'GEN';

            $infoArt = (new Articles($this->pdo))->find($articleToAdd['COD_ART'], ['CODEFAB']);
            if ($infoArt) {
                $articleToAdd['COD_FAB'] = $infoArt['CODEFAB'];
            } else {
                $articleToAdd['COD_FAB'] = 'GEN';
            }
        }

        $articleToAdd['DEVISE'] = $articleToAdd['COD_DEV'];
        $panierLigneService     = new PanierLigneService($this->pdo, $this->pdoOxaFT, 'PANIER');
        $idLignePanier          = $panierLigneService->addPanier($articleToAdd, $articleToAdd['qte']);

        if ($idLignePanier) {
            $this->updateCodeAdresse($idLignePanier, $codeAdresse ?? null);
        }

        $return['Retour']['Action']['NbLigneCree'] = count($panierLigneService->getListeArticleEdit());

        return $this->createApiResponse($return);
    }


    private function updateCodeAdresse(string $idLignePanier, ?string $codeAdresse = null): void
    {

        $infoLigne = (new OxaUserPanierLigne($this->pdo))->find($idLignePanier);


        if ($codeAdresse === '') {
            $ZGEO_SUR_CTR_EMETTEUR = Sql::paravrac($this->pdo, 'OXAPROC', 'ZGEO_SUR_CTR_EMETTEUR');

            if ($ZGEO_SUR_CTR_EMETTEUR == 'O') {
                $centre = (new OxaUserPanier($this->pdo))->find(['id_user' => $_SESSION['id_user'], $_SESSION['id_panier']], ['OUPA_CENTRE_EMETTEUR'])['OUPA_CENTRE_EMETTEUR'];
            } else {
                $centre = (new OxaUserPanier($this->pdo))->find(['id_user' => $_SESSION['id_user'], $_SESSION['id_panier']], ['LIV_CTR'])['LIV_CTR'];
            }

            $adresse = (new Listes($this->pdo))->adresseFournisseur([
                'ADR_COMMANDE' => '0x54',
                'filter_egal_CODE' => $infoLigne['COD_FOURN'] ?? '',
            ], $centre)[0] ?? [];

            $codeAdresse = $adresse['COD_ADR'];
        }

        /** @phpstan-ignore-next-line */
        if ($codeAdresse || $codeAdresse === '0' || $codeAdresse === 0) {
            $outilPanierService = new CritereRegroupService($this->pdo, $this->pdoOxaFT);
            $outilPanierService->regroupementCritere($infoLigne['CRITERE_REGROUP'], $infoLigne['COD_FOURN']);

            (new UpdateValuePanierService($this->pdo))->updateValue(
                'ADR' . Constante::spliter . str_replace('|', Constante::oxaPipe, $infoLigne['CRITERE_REGROUP']),
                $codeAdresse
            );
        }
    }

    private function updateDateLivraison(string $idLignePanier, ?string $dateLivraison = null): void
    {
        if ($dateLivraison) {
            $infoLigne = (new OxaUserPanierLigne($this->pdo))->find($idLignePanier);

            $outilPanierService = new CritereRegroupService($this->pdo, $this->pdoOxaFT);
            $outilPanierService->regroupementCritere($infoLigne['CRITERE_REGROUP'], $infoLigne['COD_FOURN']);

            (new UpdateValuePanierService($this->pdo))->updateValue(
                'DATELIVR' . Constante::spliter . str_replace('|', Constante::oxaPipe, $infoLigne['CRITERE_REGROUP']),
                $dateLivraison
            );
        }
    }

    // phpcs:ignore
    public function RAYONDETAILAction(): Response
    {
        $body             = $this->request->getMetaBody();
        $return['Statut'] = 'O';

        $ctrEmetteur  = $body['CtrEmetteur'];
        $ctrLivraison = $body['CtrLivraison'];
        $codeRayon    = $body['CodeRayon'];

        $validator = $this->createValidator();

        $listeCentre = (new Centre($this->pdo))->findAll(['CODE_STE' => User::getUser()->getHastutil()['CODE_STE']], ['CODE_CTR']);
        if (count($listeCentre) > 0) {
            $listeCentre = array_column($listeCentre, 'CODE_CTR');
        }

        if (($ctrEmetteur != '')
            && $validator->zoom('Centre', $ctrEmetteur, $this->getTranslationService()->t('Centre émetteur'), $this->pdo)
            && in_array($ctrEmetteur, $listeCentre)
        ) {
            $_SESSION['Session_CodeCtrEmetteur'] = $ctrEmetteur;
        }
        if (($ctrLivraison != '')
            && $validator->zoom('Centre', $ctrLivraison, $this->getTranslationService()->t('Centre de livraison'), $this->pdo)
            && in_array($ctrLivraison, $listeCentre)
        ) {
            $_SESSION['Session_CodeCtrLivraison'] = $ctrLivraison;
        }
        if ((($body['Langue'] ?? '') != '') && $validator->zoom('Langues', $body['Langue'], $this->getTranslationService()->t('Langue'), $this->pdo)) {
            $_SESSION['Session_Langue'] = $body['Langue'];
        }

        if ($validator->getError()) {
            return $this->createApiResponse([
                'Statut' => 'E',
                'MsgErreur' => $validator->getError()
            ]);
        }

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

        $infoPanier['CENTRE_EMETTEUR'] = $ctrEmetteur;
        $infoPanier['LIV_CTR']         = $ctrLivraison;

        $outilRecherche = new OutilRechercheService($this->pdo);
        $listeRayon     = $outilRecherche->generateRayon($this->pdoOxaFT, $infoPanier, $codeRayon);

        $replaceXml = '';
        foreach ($listeRayon as $rayon) {
            if ($this->request->wantJson()) {
                /** @phpstan-ignore-next-line */
                $return['Retour']['DetailRayon']['NIV_' . $rayon['NIVRAYON']]['data'] = [
                    'code' => $rayon['IDRAYON'],
                    'libelle' => $rayon['LIBRAYON'],
                ];
            } else {
                $replaceXml  .= "<NIV_" . $rayon['NIVRAYON'] . ">
                                    <data>
                                        <code>" . $rayon['IDRAYON'] . "</code>
                                        <libelle>" . htmlspecialchars($rayon['LIBRAYON']) . "</libelle>
                                    </data>
                                </NIV_" . $rayon['NIVRAYON'] . ">";

                $return['Retour']['DetailRayon'] = 'replace1';
            }
        }

        return $this->createApiResponse($return, $replaceXml);
    }

    // phpcs:ignore
    public function RAYONLISTEAction(): Response
    {
        $body             = $this->request->getMetaBody();
        $return['Statut'] = 'O';
        $ctrEmetteur      = $body['CtrEmetteur'];
        $ctrLivraison     = $body['CtrLivraison'];

        $validator = $this->createValidator();

        $listeCentre = (new Centre($this->pdo))->findAll(['CODE_STE' => User::getUser()->getHastutil()['CODE_STE']], ['CODE_CTR']);
        if (count($listeCentre) > 0) {
            $listeCentre = array_column($listeCentre, 'CODE_CTR');
        }

        if (($ctrEmetteur != '')
            && $validator->zoom('Centre', $ctrEmetteur, $this->getTranslationService()->t('Centre émetteur'), $this->pdo)
            && in_array($ctrEmetteur, $listeCentre)
        ) {
            $_SESSION['Session_CodeCtrEmetteur'] = $ctrEmetteur;
        }
        if (($ctrLivraison != '')
            && $validator->zoom('Centre', $ctrLivraison, $this->getTranslationService()->t('Centre de livraison'), $this->pdo)
            && in_array($ctrLivraison, $listeCentre)
        ) {
            $_SESSION['Session_CodeCtrLivraison'] = $ctrLivraison;
        }
        if ((($body['Langue'] ?? '') != '') && $validator->zoom('Langues', $body['Langue'], $this->getTranslationService()->t('Langue'), $this->pdo)) {
            $_SESSION['Session_Langue'] = $body['Langue'];
        }
        if ((($body['Langue'] ?? '') != '') && $validator->zoom('Langues', $body['Langue'], $this->getTranslationService()->t('Langue'), $this->pdo)) {
            $_SESSION['Session_Langue'] = $body['Langue'];
        }

        if ($validator->getError()) {
            return $this->createApiResponse([
                'Statut' => 'E',
                'MsgErreur' => $validator->getError()
            ]);
        }

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

        $infoPanier['CENTRE_EMETTEUR'] = $ctrEmetteur;
        $infoPanier['LIV_CTR']         = $ctrLivraison;

        $outilRecherche = new OutilRechercheService($this->pdo);
        $listeRayon     = $outilRecherche->generateRayon($this->pdoOxaFT, $infoPanier);

        $listeRayonXml = '';
        if ($this->request->wantJson()) {
            foreach ($listeRayon as $rayon) {
                $return['Retour']['listeRayons']['groupe']['rayon'] = [
                    'id' => $rayon['IDRAYON'],
                    'nom' => $rayon['LIBRAYON'],
                ];
            }
        } else {
            foreach ($listeRayon as $rayon) {
                $listeRayonXml  .= " <rayon>
                                        <id>" . ($rayon['IDRAYON']) . "</id>
                                        <nom>" . (htmlspecialchars($rayon['LIBRAYON'])) . "</nom>
                                    </rayon>";
            }
            $return['Retour']['listeRayons']['groupe'] = 'replace1';
        }
        return $this->createApiResponse($return, $listeRayonXml);
    }
}
