<?php
namespace Modules\Panier\Controller;

use Entity\Model\SSiteSto;
use GuzzleHttp\Psr7\Response;
use Helpers\Ariane\Ariane;
use Helpers\Fichier\Fichier;
use Helpers\Log\LogSysteme;
use Helpers\Outil\Sql;
use Helpers\Parametres\Constante;
use Helpers\Webservice\Wsdl;
use Modules\Panier\Service\PanierService;
use Modules\Panier\Service\ValidationPanierService;
use Modules\Panier\Validator\FieldPanierValidator;
use Modules\Panier\Validator\SoumisionFinalValidator;
use Modules\Panier\WebService\PanierWebService;
use Modules\Panier\WebService\SoumissionWebService;
use Modules\Suivi\Repository\SuiviCdeRepo;
use Modules\Suivi\Repository\SuiviDaRepo;
use Skeleton\Controller\Controller;
use Helpers\Session\ParseBase1;

class ValidationPanierController extends Controller
{
    //todo specifique spec 2431 (visu budget ) panier_ong_5.php::2008
    // ! demande a SGR si on doit le reprendre ,visiblement le client doit arreté OXAPROC
    /**
     * @return mixed
     */
    public function validationAction()
    {
        $parametrage =  [
            'AFFTTC'                => Sql::paravrac($this->pdo, 'OXAPROC', 'AFFTTC') == 'O',
            'TYPDOC_NONINIT'        => Sql::paravrac($this->pdo, 'OXAPROC', 'TYPDOC_NONINIT') == 'O',
            'MASQUER_BTN_PASS_DA'   => sql::paravrac($this->pdo, 'OXAPROC', 'MASQUER_BTN_PASS_DA') == 'O',
            'WF_STD'                => Sql::paravrac($this->pdo, 'OXAPROC', 'PANIER_WF_STANDARD') != 'N',
        ];

        if (isset($_SESSION['panier']['XML'])) {
            $xmlName = $_SESSION['panier']['XML'];
            $xmlContent = Fichier::getContentFile($xmlName);
        } else {
            LogSysteme::prefixErrorLog("Validation panier : fileName inexistant en session.");
            return $this->redirect('Panier.Panier.index');
        }
        
        $panier = new \SimpleXMLElement((string)$xmlContent);

        $validationPanier = new ValidationPanierService($this->pdo, $this->getTranslationService());

        $validationPanier->getError();

        return $this->renderer->render('@Panier/Validation/validation', [
            'menuActive'                => 'eproc',
            'panierXml'                 => $panier,
            'bloquant'                  => $validationPanier->anoBloquant(),
            'parametrage'               => $parametrage,
            'infoSiteStock'             => (new SSiteSto($this->pdo))->find($_SESSION['SiteStock']),
            'listeTypeByDoc'            => $validationPanier->listeTypeDocByDoc(),
            'valueCritere'              => $_SESSION['panier'],
            'listeFactureRegul'         => $validationPanier->getFacturePourRegul(),
            'CDE'                       => ValidationPanierService::CDE,
            'DA'                        => ValidationPanierService::DA,
            'DS'                        => ValidationPanierService::DS,
        ]);
    }


    /**
     * @return Response
     */
    public function refreshValidationAction()
    {
        $post = $this->request->getParsedBody();

        unset($_SESSION['panier']['XML']);
        
        $xmlReturn = (new SoumissionWebService(
            $this->pdo,
            $this->pdoOxaFT,
            $this->getTranslationService(),
            $post
        ))->soumissionPanier();
        $objet =  new \SimpleXMLElement((string)$xmlReturn->responseData);
        
        return Wsdl::asynchrone(
            $objet,
            $this->getTranslationService(),
            $this->renderer,
            $this->router->generateUri('Panier.Panier.waitingSoumission', ['idTraitement' => (string)$objet->ID])
        );
    }

    /**
     * @return Response
     */
    public function updateValueAction()
    {
        $post = $this->request->getParsedBody();
        $trad = $this->getTranslationService();

        $typeDoc = $post['Typedoc'];
        $critere = $post['Critere']??'';

        $validator = new FieldPanierValidator($this->pdo, $trad);
        
        $fields = $post['field'];
        if (str_starts_with($fields, 'TYPE_DOC')) {
            $fields = 'TYPE_DOC';
        } elseif (str_starts_with($fields, 'NumFactureRegulCde')) {
            $fields = 'NumFactureRegulCde';
        } elseif (str_starts_with($fields, 'sign_spec')) {
            $fields = 'sign_spec';
        } elseif (str_starts_with($fields, 'AVENANT')) {
            $fields = 'AVENANT';
        }

        $validator->controleValidationFields($fields, $post['value']);
        if (!$validator->isValid()) {
            return new Response(200, [

            ], (string) \json_encode([
                'statut' => 'B',
                'message' => substr($validator->getError(), 6),
                'title' => $trad->t('Erreur'),
                'content' => $this->renderer->render('@popup-erreur/ErreurCreation', [
                    'ErreurValid' => $validator->getError(),
                ])
            ]));
        }

        if ($typeDoc == ValidationPanierService::CDE) {
            $_SESSION['panier'][$typeDoc][$critere][$fields] = $post['value'];
        } else {
            $_SESSION['panier'][$typeDoc][$fields] = $post['value'];
        }
        
        return new Response(200, [

        ], (string) \json_encode([
            'statut'            => 'O',
        ]));
    }

    /**
     * @return Response
     */
    public function validationFinalAction()
    {
        $post = $this->request->getParsedBody();
        $trad = $this->getTranslationService();

        $validator = (new SoumisionFinalValidator($this->pdo, $trad));
        $validator->controleSignataire();

        $selectTypeDoc = [];
        foreach ($post as $k => $v) {
            if (strpos($k, 'TYPE_DOC') === 0) {
                $validator->isFalse($v, $trad->t('Le type de document n\'a pas été spécifié.'));
                
                $explodeK = explode(constante::spliter, $k);
                
                if ($explodeK[1]==ValidationPanierService::CDE) {
                    $selectTypeDoc[$explodeK[1]][$explodeK[2]] = $v;
                } else {
                    $selectTypeDoc[$explodeK[1]] = $v;
                }
            } elseif (strpos($k, 'AVENANT') === 0) {
                $validator->isStringAvecEspace($trad->t('motif de l\'avenant'), $v, 1, 120);
            }
        }

        if (!$validator->isValid()) {
            return new Response(443, [], $this->renderer->render('@popup-erreur/ErreurCreation', [
                'ErreurValid' => $validator->getError(),
                'desactiveRow' => true,
            ]));
        }

        $validationPanier = new ValidationPanierService($this->pdo, $this->getTranslationService());

        $xml = $validationPanier->convertForSoummision($selectTypeDoc, $post);
        
        $responseXml = new Wsdl('Oxaproc_Commande.wsdl', 'OXAPRC_VALIDPANIER', $xml, false, true);
        $xmlContent = $responseXml->responseData;
        $objet = new \SimpleXMLElement((string)$xmlContent);

        return Wsdl::asynchrone(
            $objet,
            $this->getTranslationService(),
            $this->renderer,
            $this->router->generateUri('Panier.validationPanier.waitingvalidationFinal', ['idTraitement' => (string)$objet->ID])
        );
    }

    /**
     * @return Response
     */
    public function waitingvalidationFinalAction()
    {
        $idTraitement = $this->request->getAttribute('idTraitement');
        $Asynchrone = new \Modules\Outil\Repository\Asynchrone($this->pdo);

        $result = $Asynchrone->getOxaprcAsync($idTraitement);

        $params['Statut'] = 'W';
        $params['path'] = $this->router->generateUri('Panier.validationPanier.waitingvalidationFinal', ['idTraitement' => $idTraitement]);

        if ($result) {
            if (Sql::toBool($result['TRTFINI']) && $result['FICRESULT'] != '') {
                $chemin_fichier = (new ParseBase1())->getRep()->tmp . $result['FICRESULT'];
                $fichierLast = file_get_contents($chemin_fichier);
                $listeDocument = new \SimpleXMLElement((string) $fichierLast);
                
                $listeDA = [];
                $listeCDE = [];

                if ($listeDocument->ListeDA->DA) {
                    foreach ($listeDocument->ListeDA->DA as $da) {
                        $listeDA[] = (string) $da;
                    }
                }

                if ($listeDocument->ListeCde->Cde) {
                    foreach ($listeDocument->ListeCde->Cde as $cde) {
                        $listeCDE[] = (string) $cde;
                    }
                }

                unset($_SESSION['panier']);
                (new PanierService($this->pdo))->delete('0', $this->getTranslationService());

                $params['Statut'] = 'O';
                $params['path'] = $this->router->generateUri('Panier.validationPanier.document');
                $params['post'] = ['listeCde' => $listeCDE,'listeDA' => $listeDA];
            }
        } else {
            $params = [
                [
                    'Statut' => 'E',
                    'content' => $this->renderer->render('@popup-erreur/ErreurCreation', [
                        'ErreurValid' => $this->getTranslationService()->t('Une erreur est survenue.'),
                        'desactiveRow' => true,
                    ])
                ]
            ];
        }

        return new Response(200, [], (string) \json_encode($params));
    }

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

        $suiviDaRepo = new SuiviDaRepo($this->pdo, $this->router, $trad);
        $suiviCdeRepo = new SuiviCdeRepo($this->pdo, $this->router, $trad);

        Ariane::generate(0, $trad->t('Documents créés'), $post);

        return $this->renderer->render('@Panier/General/ListeDocument', [
            'menuActive'    => 'eproc',
            'listeCde'      => $suiviCdeRepo->getCdeLinkDoc('CDE', $post['listeCde']??[]),
            'listeDa'       => $suiviDaRepo->getDaLinkDoc('DA', $post['listeDA']??[]),
            'context'       => 'panier',
            'source'        => 'panier',

            'post'          => $post,
        ]);
    }
    
    public function popupSignataireAction():string
    {
        $typeDoc = $this->request->getAttribute('typeDoc');
        $critereRegroupOld = $this->request->getAttribute('critereRegroup');
        $critereRegroup = str_replace(Constante::oxaPipe, '|', $critereRegroupOld);

        $trad = $this->getTranslationService();

        $validationPanierController = new ValidationPanierService($this->pdo, $this->getTranslationService());
        if ($typeDoc == ValidationPanierService::CDE) {
            $infoDoc = $validationPanierController->getListe($typeDoc, $critereRegroup);
        } else {
            $infoDoc = $validationPanierController->getInfoTypeDoc($typeDoc);
        }
        
        $listeSignataireTmp     = $infoDoc->ListSignataire->Signataire;
        $listeSignataires        = [];
        foreach ($listeSignataireTmp as $sig) {
            $listeSignataires[(string) $sig->Utilisateur] = (string) $sig->NomUtilisateur;
        }

        asort($listeSignataires);
        
        $algoSpecif             = (string)$infoDoc->ListSignataire->AlgoSpecif;

        $droits['ajoutSignataire'] = \Helpers\Outil\Roles::droitsUtilisateur($this->pdo, 'HA_SE_AJSI');
        $droits['suppressionSignataire'] = \Helpers\Outil\Roles::droitsUtilisateur($this->pdo, 'HA_SE_SUSI');

        return $this->renderer->render('@popup-erreur/signataireXml', [
            'modeInitialisation'    => true,
            "modePanier"            => true,
            'listeTypeRole'         => ['N' => $trad->t('Signataire'), 'O' => $trad->t('Informé')],
            'listeSignataires'      => $listeSignataires,

            'ErreurValid'           => ['AlgoSpecif' => $algoSpecif],
            'droits'                => $droits,
            'pathValidation'        => $this->router->generateUri('Panier.validationPanier.ajaxSignataireValidation', ['typeDoc' => $typeDoc, 'critereRegroup' => $critereRegroupOld]),
        ]);
    }

    /**
     * @return mixed
     */
    public function ajaxSignataireValidationAction()
    {
        $typeDoc = $this->request->getAttribute('typeDoc');
        $critereRegroupOld = $this->request->getAttribute('critereRegroup');
        $critereRegroup = str_replace(Constante::oxaPipe, '|', $critereRegroupOld);

        $post = $this->request->getParsedBody();
        $trad = $this->getTranslationService();

        $signaPresent = false;
        $tblsignataire = [];


        foreach ($post as $key => $value) {
            $tblKey = explode('_', $key);
            if (count($tblKey)==2) {
                if ($post[$tblKey[0].'_5']=='N') {
                    $signaPresent = true;
                }

                $tblsignataire[$tblKey[0]][$tblKey[1]] = $value;
            }
        }

        foreach ($tblsignataire as &$tab) {
            ksort($tab);
            $tab = implode(';', $tab);
        }

        if (!$signaPresent) {
            return $this->renderer->render('@popup-erreur/ErreurCreation', [
                'ErreurValid' => $trad->t('Il doit y avoir au moins un signataire dans le tableau.'),
            ]);
        }

        /** @phpstan-ignore-next-line */
        $algoSpecif = implode('|', $tblsignataire);
        
        $validationPanier = new ValidationPanierService($this->pdo, $trad);
        $validationPanier->majNodeSignataire($typeDoc, $critereRegroup, $algoSpecif);

        return new Response(
            443,
            [],
            (string) \json_encode([
                'statut' => 'O',
                'closePopup' => true,
            ])
        );
    }
    

    public function popupPlanningAction():string
    {
        $typeDoc = $this->request->getAttribute('typeDoc');
        $critereRegroupOld = $this->request->getAttribute('critereRegroup');
        $critereRegroup = str_replace(Constante::oxaPipe, '|', $critereRegroupOld);
        $idLigne = $this->request->getAttribute('idLigne');

        $trad = $this->getTranslationService();

        $validationPanier = new ValidationPanierService($this->pdo, $trad);
        $article = $validationPanier->getListe($typeDoc, $critereRegroup, $idLigne);
        
        return $this->renderer->render('@Panier/Validation/popupPlanning', [
            'article' => $article,
            'typeDoc'=> $typeDoc,
            'critereRegroup' => $critereRegroupOld,
            'idLigne' => $idLigne,
        ]);
    }

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

        if (isset($post['lastId'])) {
            $idPlanning = (int)$post['lastId'];
        } else {
            $idPlanning = 0;
        }

        return $this->renderer->render('@Panier/Validation/_lignePlanning', [
            'lignePlanning' => $idPlanning+1,
        ]);
    }

    /**
     * @return Response
     */
    public function ajaxPlanningValidationAction()
    {
        $typeDoc = $this->request->getAttribute('typeDoc');
        $critereRegroupOld = $this->request->getAttribute('critereRegroup');
        $critereRegroup = str_replace(Constante::oxaPipe, '|', $critereRegroupOld);
        $idLigne = $this->request->getAttribute('idLigne');

        $post = $this->request->getParsedBody();
        $trad = $this->getTranslationService();
        $validator = $this->createValidator();

        $validationPanier = new ValidationPanierService($this->pdo, $trad);
        $article = $validationPanier->getListe($typeDoc, $critereRegroup, $idLigne);

        $recepAuto = $article->ReceptionAuto == 'true';

        if ($recepAuto) {
            $dateMin = (string)$article->DteDebContrat;
            $dateMax = (string)$article->DteFinContrat;
        }

        $maxQte = (float)$article->QteDemande;

        $total = 0;
        $arrayPlanning = [];
        $compareDate = [];
        foreach ($post['listPlanning'] as $k => $v) {
            $total += (float) $post['Qte'.$k];

            if ($recepAuto) {
                $validator->isDate($post['Date'.$k], $dateMin, $dateMax);
            } else {
                $validator->isDate($post['Date'.$k]);
            }
            $validator->isFloat($trad->t('Quantité'), $post['Qte'.$k], Constante::formatQTE, true);


            $arrayPlanning[] = [
                'date' => $post['Date'.$k],
                'qte' => $post['Qte'.$k]
            ];
            $compareDate[] = $post['Date'.$k];
        }

        $tempArray = array_unique($compareDate);

        $validator->isFalse(sizeof($compareDate) == sizeof($tempArray), 'Une date de livraison est présente plusieurs fois.');
        
        $validator->isTrue(round($total, 3)!=round($maxQte, 3), $trad->t('La somme des quantités du planning est différente de celle de la ligne.'));

        if ($validator->isValid()) {
            $validationPanier->majNodePlanning($typeDoc, $critereRegroup, $idLigne, $arrayPlanning);

            return new Response(200);
        } else {
            return new Response(400, [], (string) json_encode([
                'statut'    => 'E',
                'message'   => $validator->getError()
            ]));
        }
    }

    //WsdlPreviewDSPdf
    public function impressionDocumentAction():string
    {
        $chiffre = $this->request->getAttribute('chiffre');
        $typeDoc = $this->request->getAttribute('typeDoc');
        $critereRegroupOld = $this->request->getAttribute('critereRegroup');
        $critereRegroup = str_replace(Constante::oxaPipe, '|', $critereRegroupOld);

        $trad = $this->getTranslationService();

        $validationPanier = new ValidationPanierService($this->pdo, $trad);
        
        if ($typeDoc == ValidationPanierService::CDE) {
            $infoDoc = $validationPanier->getListe($typeDoc, $critereRegroup);
            $responseXml = (new PanierWebService())->impressionCde($this->pdo, $infoDoc, $validationPanier->getCsEntete(), $critereRegroup);
            $response = new \SimpleXMLElement($responseXml->responseData);
        } else {
            $infoDoc = $validationPanier->getInfoTypeDoc($typeDoc);
            $responseXml = (new PanierWebService())->impressionDa($this->pdo, $typeDoc, $infoDoc, $validationPanier->getCsEntete(), (int)$chiffre);
            $response = new \SimpleXMLElement($responseXml->responseData);
        }

        if ($response->Retour == 'O') {
            $pathInfo = pathInfo($response->FichierPDF);

            return Fichier::UploadClient($response->FichierPDF, $typeDoc.'_'.rand().($pathInfo['extension']??''));
        } else {
            return (string)$response->MsgErreur;
        }
    }
}
