<?php

namespace Modules\API\APIInterne\OxaMobility\Controller;

use Entity\Model\Articles;
use Entity\Model\Fourniss;
use Entity\Model\OxaUserPanier;
use Entity\Model\OxaUserPanierFour;
use GuzzleHttp\Psr7\Response;
use Helpers\Fichier\Fichier;
use Helpers\Log\LogSysteme;
use Helpers\Parametres\Constante;
use Helpers\Session\ParseBase1;
use Helpers\Webservice\Wsdl;
use Modules\Panier\Service\CritereRegroupService;
use Modules\Panier\Service\PanierLigneService;
use Modules\Panier\Service\PanierService;
use Modules\Panier\Service\UpdateValuePanierService;
use Modules\Panier\Service\ValidationPanierService;
use Modules\Panier\Validator\PanierValidator;
use Modules\Panier\WebService\SoumissionWebService;
use SimpleXMLElement;
use Helpers\Outil\Sql;
use Helpers\Fichier\Gestion_Fic_PJ;
use Modules\Commande\Repository\PJ;
use OpenApi\Annotations as OA;
use Modules\Ajax\Repository\Listes;

// phpcs:ignore
class CDE_COMPTOIR_PAR_MNTController extends AbsApiController
{

    /**
     * @OA\Post(
     *      path="/cde_comptoir_par_mtn/creat",
     *      summary="Crée une nouvelle commande comptoir",
     *      tags={"Commandes comptoir"},
     *      @OA\RequestBody(
     *          description="Numéro de commande",
     *          required=true,
     *          @OA\MediaType(
     *              mediaType="application/xml",
     *          )
     *      ),
     *      @Oa\Response(
     *          response="200",
     *          description="Nouveau bon de réception",
     *          @OA\XmlContent(
     *             type="array",
     *             @OA\items(
     *                  type="string"))
     *       ),
     *       security={{
     *          "ApiKeyAuth": {}
     *      }}
     * )
     */

    public function CREATAction() :Response
    {
        $return = [];
        $trad = $this->getTranslationService();
        $body = $this->request->getMetaBody();

        // on modifie les informations de session
        if ($body['codeSoc']) {
            $_SESSION['Session_SocUsr'] = $body['codeSoc'];
        }
        if ($body['CtrEmetteur']) {
            $_SESSION['Session_CodeCtrEmetteur'] = $body['CtrEmetteur'];
        }
        if ($body['CtrLivraison']) {
            $_SESSION['Session_CodeCtrLivraison'] = $body['CtrLivraison'];
        }
        
        $body['SI_CODE'] = is_array($body['SI_CODE']) ? '' : $body['SI_CODE'];
        $body['CDC_CODE'] = is_array($body['CDC_CODE']) ? '' : $body['CDC_CODE'];
        $body['SCA_CODE'] = is_array($body['SCA_CODE']) ? '' : $body['SCA_CODE'];

        $montantMax = Sql::paravrac($this->pdo, 'OXAMPROC', 'MNT_MAX_CDE_COMPTOIR');
        $articleCdeComptoir = Sql::paravrac($this->pdo, 'OXAMPROC', 'CDE_COMPTOIR_PAR_MONTANT_CODE_ART');

        $montantMax = trim($montantMax);
        $montantMax = str_replace(' ', '', $montantMax);

        $body['MntHT'] = trim($body['MntHT']);
        $body['MntHT'] = str_replace(' ', '', $body['MntHT']);

        //On vérifie que les commandes comptoir sont bien activé (On controle aussi que le parametrage soit complet)
        $cdeComptoirActif = Sql::paravrac($this->pdo, 'OXAMPROC', 'CDE_COMPTOIR_PAR_MONTANT_ACTIVE');
        $pjObli = Sql::paravrac($this->pdo, 'OXAMPROC', 'CDE_COMPTOIR_PAR_MONTANT_PJ_OBLIG')=='O'? true:false;
        if (count($body['ListePJ']['PJ']??[])==0 && $pjObli) {
            $return['Statut'] = 'E';
            $return['MsgErreur'] = $trad->t('Dans le cas de la commande comptoir, il est obligatoire d\'attacher une pièce jointe');
        } elseif ($cdeComptoirActif != 'O' || (trim($articleCdeComptoir) == '' || !$articleCdeComptoir)) {
            $return['Statut'] = 'E';
            $return['MsgErreur'] = $trad->t('Les commandes comptoir par montant ne sont pas activées.');
        } elseif ($montantMax < $body['MntHT']) {
            //On verifie que la commande comptoir ne depasse pas le montant parametré
            $return['Statut'] = 'E';
            $return['MsgErreur'] = $trad->t('Le montant dépasse la limite pour les commandes comptoir.');
        } else {
            // Si les deux contrôles précédents sont OK, alors on peut vider/créer/soumettre le panier
            
            (new PanierService($this->pdo))->delete('0', $this->getTranslationService());

            $oxaUserPanier = new OxaUserPanier($this->pdo);
            $oxaUserPanier->update([
                'SI_CODE' => $body['SI_CODE'],
                'SCA_CODE' => $body['SCA_CODE'],
                'CDC_CODE' => $body['CDC_CODE'],
            ], [
                'id_panier' => $_SESSION['id_panier'],
                'id_user'   => $_SESSION['id_user'],
            ]);

            $fourniss = (new Fourniss($this->pdo))->find($body['CodeFourn'], ['DEVISE']);

            $itemPanier = (new Articles($this->pdo))->find($articleCdeComptoir);
            $itemPanier['DES_ART']      = $itemPanier['DESIGN'];
            $itemPanier['COD_ART']      = $articleCdeComptoir;
            $itemPanier['COD_FOURN']    = $body['CodeFourn'];
            $itemPanier['ARTASSOCIE']   = false;
            $itemPanier['PX_ART']       = $body['MntHT'];
            $itemPanier['COD_UNIT']     = $itemPanier['UNIT'];
            $itemPanier['COD_FAB']      = $itemPanier['CODEFAB'];
            $itemPanier['REF_FAB']      = $itemPanier['REFARTFAB'];
            $itemPanier['COD_GAM']      = $itemPanier['CODEGAM'];
            $itemPanier['COD_SFAM']     = $itemPanier['SSFAM'];
            $itemPanier['ID_CAT']       = 'HAPLUS';
            $itemPanier['DEVISE']       = $fourniss['DEVISE']??'';
            $itemPanier['type_de_ligne'] = 1;

            $arrayCompl['SI'] = $body['SI_CODE'];
            $arrayCompl['CDC'] = $body['CDC_CODE'];
            $arrayCompl['SCA'] = $body['SCA_CODE'];
            $arrayCompl['dteLivr'] = date('Ymd');
            $arrayCompl['centreLivraisonLigne'] = $body['CtrLivraison'];

            $panierLigneService = new PanierLigneService($this->pdo, $this->pdoOxaFT, 'MOBILITE');
            $panierLigneService->addPanier($itemPanier, 1, $arrayCompl);

            /* Appel V1 soumission panier */

            $outilPanierService = new CritereRegroupService($this->pdo, $this->pdoOxaFT);
            $outilPanierService->setMobility(true);
            $outilPanierService->regroupementCritere();

            (new OxaUserPanier($this->pdo))->update([
                'CHIF_EXEC' => 'E',
            ], [
                'id_user' => $_SESSION['id_user'],
                'id_panier' => $_SESSION['id_panier']
            ]);

            $oxaUserPanierFour = (new OxaUserPanierFour($this->pdo))->find([
                'id_user' => $_SESSION['id_user'],
                'id_panier' => $_SESSION['id_panier']
            ], ['CRITERE_REGROUP']);

            if ($body['COD_ADR']) {
                $codAdr = $body['COD_ADR'];
            } else {
                $adresse = (new Listes($this->pdo))->adresseFournisseur([
                    'ADR_COMMANDE' => '0x54',
                    'filter_egal_CODE' => $body['CodeFourn']??'',
                ])[0]??[];
                
                $codAdr =  $adresse['COD_ADR'];
            }
            $updateValueService = new UpdateValuePanierService($this->pdo);
            $updateValueService->updateValue('ADR'.Constante::spliter.$oxaUserPanierFour['CRITERE_REGROUP'], $codAdr);


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

            $firstAno = '';
            if ($validator->isValid()) {
                $xmlReturn = (new SoumissionWebService(
                    $this->pdo,
                    $this->pdoOxaFT,
                    $this->getTranslationService()
                ))->soumissionPanier(false, true);
                $contentXml = (string)$xmlReturn->responseData;
                $responseXML =  new SimpleXMLElement($contentXml);

                $fileName = 'PanierIn'.$_SESSION["Session_Login"] .date('ymdhis').rand().'.xml';
                Fichier::createFichierTmp($fileName, $contentXml);

                $_SESSION['panier']['XML'] = $fileName;

                $anoBloquante = false;
                foreach ($responseXML->RecapGlobalAnomalies->DetailAnomalie as $ano) {
                    if ($ano->AnomalieBloquante == 'true') {
                        $anoBloquante = true;
                        break;
                    }
                }
                
                if ($responseXML->DA) {
                    $anoBloquante = true;
                }
                
                if (!$anoBloquante) {
                    $validationPanier = new ValidationPanierService($this->pdo, $this->getTranslationService());
            
                    $xml = $validationPanier->convertForSoummision();
                    
                    $responseXml = new Wsdl('Oxaproc_Commande.wsdl', 'OXAPRC_VALIDPANIER', $xml, false, false);
                    $xmlContent = $responseXml->responseData;
                    $responseXML = new SimpleXMLElement((string)$xmlContent);
                }
            } else {
                $responseXML = false;
                $listeAnoTmp = explode("<br />", $validator->getError());
                
                
                foreach ($listeAnoTmp as $ano) {
                    if ($ano != '') {
                        $firstAno = $ano;
                        break;
                    }
                }
            }

            $ArrayString = '';
            $arrayJson = [];

            // Si on a une liste de commande, c'est que notre commande a pu être créée
            $numCde = '';

            if ($responseXML) {
                if (trim((string)$responseXML->ListCdes->Cde) != '') {
                    $numCde = (string) $responseXML->ListCdes->Cde;
                } elseif (trim((string)$responseXML->ListeCde->Cde) != '') {
                    $numCde = (string)$responseXML->ListeCde->Cde;
                }
            }

            if ($numCde) {
                $return['Statut'] = 'O';
                $return['MsgErreur'] = '';
                $return['NumCde'] = $numCde;
            } elseif ($responseXML && $responseXML->RecapGlobalAnomalies) {
                //Si on a le récap global, c'est qu'il y a une anomalie bloquante dans la 1ere soumission
                foreach ($responseXML->RecapGlobalAnomalies->DetailAnomalie as $ano) {
                    if ($ano->AnomalieBloquante == 'true') {
                        $arrayJson['DetailAnomalie'][] = [
                            'TypeObjet' => $ano->TypeObjet,
                            'CRITERE_REGROUP_ANO' => $ano->CRITERE_REGROUP_ANO,
                            'NoLigPanier' => $ano->NoLigPanier,
                            'TxtAnomalie' => \htmlspecialchars($ano->TxtAnomalie, ENT_XML1, 'UTF-8'),
                            'AnomalieBloquante' => \htmlspecialchars($ano->AnomalieBloquante, ENT_XML1, 'UTF-8'),
                        ];

                        $ArrayString .= "<DetailAnomalie>
                                            <TypeObjet>" . $ano->TypeObjet . "</TypeObjet>
                                            <CRITERE_REGROUP_ANO>" . $ano->CRITERE_REGROUP_ANO . "</CRITERE_REGROUP_ANO>
                                            <NoLigPanier>" . $ano->NoLigPanier . "</NoLigPanier>
                                            <TxtAnomalie>" . \htmlspecialchars($ano->TxtAnomalie, ENT_XML1, 'UTF-8') . "</TxtAnomalie>
                                            <AnomalieBloquante>" . \htmlspecialchars($ano->AnomalieBloquante, ENT_XML1, 'UTF-8') . "</AnomalieBloquante>
                                        </DetailAnomalie>";
                    }
                }
            }

            //SUITE : Si on a le récap global, c'est qu'il y a une anomalie bloquante dans la 1ere soumission
            if ($ArrayString) {
                $return['Statut'] = 'E';
                $return['MsgErreur'] = '';
                if ($this->request->wantJson()) {
                    $return['RecapGlobalAnomalies'] = $arrayJson;
                } else {
                    $return['RecapGlobalAnomalies'] = 'replace1';
                }
            } elseif ($responseXML && ($responseXML->DA || $responseXML->ListeDA)) {
                // Si la 1ere soumission crée une DA, alors erreur (les commandes comptoir ne peuvent être que des CDE)
                $return['Statut'] = 'E';
                $return['MsgErreur'] = $trad->t('Votre panier ne peut pas créer de commande.');
            } elseif ($responseXML && $responseXML->ERREUR) {
                //Si une erreur est remonté dans les contrôles PHP
                $return['Statut'] = 'E';
                $return['MsgErreur'] = $responseXML->ERREUR;
            } elseif ($responseXML && $responseXML->CauseErreur) {
                //Si une erreur est remonté dans les contrôles PHP
                $return['Statut'] = 'E';
                $return['MsgErreur'] = $responseXML->CauseErreur;
            } elseif ($firstAno) {
                $return['Statut'] = 'E';
                $return['MsgErreur'] = $firstAno;
            } elseif (!$numCde) {
                //Si autre erreur
                $return['Statut'] = 'E';
                $return['MsgErreur'] = $trad->t('Une erreur est survenue.');
            }
        }

        /***************************** copy attachments from /tmp to /fic_pj  **********************************/
        if (isset($body['ListePJ']) && (count($body['ListePJ']) > 0) && isset($numCde) && $numCde != '') {
            $i = 2;
            if (isset($body['ListePJ']['PJ'][0])) {
                foreach ($body['ListePJ']['PJ'] as $pieceJointe) {
                    /* on copie le fichier depuis le dossier tmp vers le dossier fic_pj, sous-dossier nommé d'après le numéro de commande */
                    $file = \pathinfo($pieceJointe['NomFichier']);
                    $file = $file['basename'];
                    $gestionFicPj = new Gestion_Fic_PJ($this->pdo);
                    $newFile = $gestionFicPj->insertFichier($file);

                    /* si le fichier existe et a bien été déplacé dans le dossier fic_pj, on insère la pièce jointe dans la table CA_PIJO */
                    $arrayReq = [
                        'NO_CA'        => $numCde,
                        'NO_ORDRE'     => $i,
                        'TYPE_PJ'      => 'PJ',
                        'TITRE'        => $pieceJointe['NomFichierAff'],
                        'COPIE'        => '0x54',
                        'IMP_PJ'       => '0x54',
                        'IMP_TITRE'    => '0x54',
                        'NOM_FIC'      => $newFile,
                        'NOM_ORI'      => $pieceJointe['NomFichierAff']
                    ];
                    $i++;
                    $pj = new PJ($this->pdo);
                    $pj->insertSinglePJ($arrayReq);
                }
            } else {
                /* on copie le fichier depuis le dossier tmp vers le dossier fic_pj, sous-dossier nommé d'après le numéro de commande */
                $pieceJointe = $body['ListePJ']['PJ'];
                $file = \pathinfo($pieceJointe['NomFichier']);
                $file = $file['basename'];
                $gestionFicPj = new Gestion_Fic_PJ($this->pdo);
                $newFile = $gestionFicPj->insertFichier($file);

                /* si le fichier existe et a bien été déplacé dans le dossier fic_pj, on insère la pièce jointe dans la table CA_PIJO */
                $arrayReq = [
                    'NO_CA'        => $numCde,
                    'NO_ORDRE'     => $i,
                    'TYPE_PJ'      => 'PJ',
                    'TITRE'        => $pieceJointe['NomFichierAff'],
                    'COPIE'        => '0x54',
                    'IMP_PJ'       => '0x54',
                    'IMP_TITRE'    => '0x54',
                    'NOM_FIC'      => $newFile,
                    'NOM_ORI'      => $pieceJointe['NomFichierAff']
                ];
                $i++;
                $pj = new PJ($this->pdo);
                $pj->insertSinglePJ($arrayReq);
            }
        }

        /** @phpstan-ignore-next-line */
        if ($return['Statut'] == 'O') {
            (new PanierService($this->pdo))->delete($_SESSION['id_panier'], $trad);
        }

        return $this->createApiResponse($return, $ArrayString??'');
    }
}
