<?php

namespace Modules\Facture\Controller;

use Firebase\JWT\Key;
use GuzzleHttp\Psr7\Response;
use Helpers\Ariane\Ariane;
use Helpers\Fichier\Fichier;
use Helpers\Outil\Sql;
use Helpers\Trad\Trad;
use Modules\Facture\Outil\LadService;
use Skeleton\Controller\Controller;
use Helpers\Outil\Outils;
use Helpers\Session\ParseBase1;

class ZedocController extends Controller
{
    public function init()
    {
        if (!\Helpers\Roles\Predispatch::connectRole()) {
            return $this->redirect($this->contenaire->get('base').'index.php');
        }
    }

    /**
     * Dispatcher ZEDOC
     * zedocAction
     *
     * @return string
     */
    public function zedocAction() : string
    {
        $trad = $this->getTranslationService();
        Ariane::generate(0, $trad->t('Vidéocodage'));
        $paramDico = new \Entity\Model\ParamDico($this->pdo);
        $paraVrac = new \Entity\Model\Paravrac($this->pdo);
        $parametre = $paraVrac->find([
            'TYPEPARV' => 'PARAMGEN',
            'CODEPARV' => 'LADFACT_PARTENAIRE'
        ], ['LIB01PARV']);

        switch ($parametre['LIB01PARV']??'OXAFLEXI') {
            case 'OXAFLEXI':
                return $this->zedocFlexi($paramDico);

            default:
                return $this->zedocBSV($paramDico);
        }
    }

    public function zedocBSV(\Entity\Model\ParamDico $paramDico) : string
    {
        $urlZedoc = \Helpers\Outil\Roles::getDroit($this->pdo, 'LADFACT_URL_VIDEOCODAGE', 'PARAMGEN');

        $parametre = $paramDico->find(['TYPEDICO' => 'LAD_PARAM_PARTNER', 'ID1' => 'BSV']);

        if (isset($parametre['ALPHA3']) && trim($parametre['ALPHA3'])!='') {
            $payload = [
                'log'=> $_SESSION['Session_Login'],
                'iss' => 'oxaproc',
                'iat' => time(),
            ];

            $token = \Firebase\JWT\JWT::encode($payload, $parametre['ALPHA3'], 'HS256');

            // $decode = \Firebase\JWT\JWT::decode($token, $parametre['ALPHA3'],["HS256"]);

            $urlZedoc.='jwtconnect.htm?jwt='.$token;
        }

        return $this->renderer->render('@lad/zedocBSV', [
            'menuActive' => 'Facture',
            'menuLeft' => '',
            'urlZedoc' => $urlZedoc,

        ]);
    }


    public function zedocFlexi(\Entity\Model\ParamDico $paramDico) : string
    {

        if (!Fichier::fileExisteEtc('OXALAD//Certificat//Flexi_KeyPrivate.pem')) {
            return $this->zedocBSV($paramDico);
        }
        $ticket = '';
        $xml ='';
        $urlZedoc = \Helpers\Outil\Roles::getDroit($this->pdo, 'LADFACT_URL_VIDEOCODAGE', 'PARAMGEN', false);
        $trad = $this->getTranslationService();

        if (trim((string)$urlZedoc)  == '') {
            return $this->renderer->render('@lad/zedocFlexi', [
                'menuActive' => 'Facture',
                'menuLeft' => '',
                'messageError' => $trad->t('Le paramétrage de l\'url n\'est pas renseigné dans l\'application')

            ]);
        } elseif (Outils::getPreferredProtocol() == 'http://') {
            return $this->renderer->render('@lad/zedocFlexi', [
                'menuActive' => 'Facture',
                'menuLeft' => '',
                'messageError' => $trad->t('L\'application doit être en HTTPS pour pouvoir consulter la LAD')

            ]);
        }

        $payload = [
            'nameid'=> $_SESSION['Session_NumClient'].'_'.(new ParseBase1())->getBroker().'_'.$_SESSION['Session_Login'],
            'iss' => 'ABBY',
            'nbf' => time(),
            'exp' => time()+1000,
            'aud' => 'Oxaproc_'.uniqid()
        ];
        $privateKey = (string)Fichier::getContentFileEtc('OXALAD//Certificat//Flexi_KeyPrivate.pem');

        $base64UrlHeader = $this->base64UrlEncode((string)json_encode([
            'typ' => 'JWT',
            'alg' => 'RS256'
        ]));


        $base64UrlPayload =$this->base64UrlEncode((string)json_encode($payload));
        $signature = hash_hmac('sha256', "$base64UrlHeader.$base64UrlPayload", $privateKey, true);

        openssl_sign(
            "$base64UrlHeader.$base64UrlPayload",
            $signature,
            $privateKey,
            "sha256WithRSAEncryption"
        );

        $base64UrlSignature = $this->base64UrlEncode($signature);
        $token = "$base64UrlHeader.$base64UrlPayload.$base64UrlSignature";

        try {
            $client = new \GuzzleHttp\Client(['verify' => false]);

            $promise = $client->post(
                $urlZedoc.'/Verification/Server/Logoff',
                [
                    'headers' => [
                        'Cookie' => session_name().' : '.session_id(),
                        "Access-Control-Allow-Origin : *",
                        "Referrer-Policy: no-referrer",
                        "Access-Control-Allow-Methods: POST, GET, OPTIONS"
                    ],
                    'form_params' => [
                        'JwtToken' => $token,
                    ]

                ]
            );

            $xml = $promise->getBody()->getContents();

            $client = new \GuzzleHttp\Client(['verify' => false]);
            $promise = $client->post($urlZedoc.'/Server/jwt', [
                'headers' => [
                    'Cookie' => session_name().' : '.session_id(),
                    "Access-Control-Allow-Origin : *",
                    "Referrer-Policy: no-referrer",
                    "Access-Control-Allow-Methods: POST, GET, OPTIONS"
                ],
                'form_params' => [
                    'JwtToken' => $token,
                ]

            ]);

            $xml = $promise->getBody()->getContents();
            $xmlReturn = new \SimpleXMLElement($xml);
            $ticket = $xmlReturn->ticket;
            $arr_cookie_options = array (
                'expires' => time()+1000
            );

            $arr_cookie_options['samesite'] = 'None';
            $arr_cookie_options['secure'] = true;
            $arr_cookie_options['path'] = '/';
            $arr_cookie_options['httponly'] = true;

            setcookie('FlexiCaptureTmpPrn', 'Ticket='.$ticket, $arr_cookie_options);

            /**
             * Prise en compte de la langue
             */

            $langueParamDico = $paramDico->find(
                [
                    'TYPEDICO' => 'OXAFLEXI_LNG',
                    'ID1' => $_SESSION['Session_Langue'],
                    'ID3' => '',
                    'ID4' => ''
                ],
                ['LIBELLE']
            );
            if (isset($langueParamDico['LIBELLE'])) {
                setcookie('FCUserLang', $langueParamDico['LIBELLE'], $arr_cookie_options);
            }
        } catch (\GuzzleHttp\Exception\RequestException $e) {
            echo $e->getResponse()->getBody()->getContents();
        }

        /**
         * Prise en compte du numero de projet (pas d'actualité pour le moment)
         */


        // $paravrac = new Paravrac($this->pdo);
        // $numProjet = $paravrac->find(
        //     [
        //         'TYPEPARV' => 'OXAFLEXI',
        //         'CODEPARV' => 'FLEXI_PROJECTID',
        //     ],
        //     [
        //         'LIB01PARV'
        //     ]
        // );

        $urlZedocTmp = $urlZedoc;
        $urlZedoc = $urlZedoc."/Verification/custom";
        $urlZedoc1 = $urlZedocTmp."/Server/FCAuth";
        $urlZedocJWT = $urlZedocTmp."/Server/jwt";
        $urlZedocLoginAccessToken = $urlZedocTmp."/Login/AccessToken";

        return $this->renderer->render('@lad/zedocFlexi', [
            'menuActive' => 'Facture',
            'menuLeft' => '',
            'urlZedocURL' => $urlZedoc,
            'urlZedoc' => $urlZedoc,
            'urlZedoc1'=> $urlZedoc1,
            'urlZedocJWT' => $urlZedocJWT,
            'urlZedocLoginAccessToken' => $urlZedocLoginAccessToken,
            'ticket' => $ticket,
            'sessionID' => session_id(),
            'sessionName' => session_name(),
            'xml'=> $xml,
            'cookieTmp' => 'Ticket='.$ticket

        ]);
    }

    /**
     * @return false|string|Response
     */
    public function affichagPDFLADAction()
    {
        $post = $this->request->getParsedBody(true);

        $verify = (array)\Firebase\JWT\JWT::decode(trim($post['ficPDF']), new Key($this->JWTKEY, 'HS256'));
        $pdf = (array)$verify['doc'];
        $src = (array)$verify['src'];

        if ($src[0] == 'PJ') {
            $urlPDF = Fichier::getDirPj();
        } elseif ($src[0] == 'LADARCHIVE_PDF' || $src[0] == 'LADFACTSPOT_PDF') {
            $urlPDF = \Helpers\Outil\Sql::paravrac($this->pdo, 'PARAMGEN', $src[0]);
            $urlPDF = Outils::buildPath($urlPDF);
        } else {
            $urlPDF = fichier::getDirTmp();
        }

        if (empty($pdf[0])) {
            return $this->create404Response('File not found');
        }

        /**
         * Mise en place du header
         */
        Outils::getHeaderByFile($pdf[0]);

        return Fichier::getContentFile($pdf[0], $urlPDF);
    }

    public function base64UrlEncode(string $data): string
    {
        $base64Url = strtr(base64_encode($data), '+/', '-_');

        return rtrim($base64Url, '=');
    }

    public function listRejectedAction(): string
    {
        $trad = $this->getTranslationService();

        Ariane::generate(0, $trad->t('Gestion des rejets'));

        $listePDF = [];
        $ladService = new LadService($trad);
        if (is_dir($ladService->directoryLad)) {
            $listeFile = scandir($ladService->directoryLad);
            $ladService->getAllFileInDirectory($listeFile, $listePDF);
        }

        ksort($listePDF);

        return $this->renderer->render('@lad/rejected', [
            'menuActive' => 'Facture',

            'listePDF' => $listePDF,
            'trad' => $trad
        ]);
    }

    public function ajaxActionRejectedAction(): Response
    {
        $action = $this->request->getAttribute('action');
        $secto = $this->request->getAttribute('secto');
        $post = $this->request->getParsedBody(true);
        $fileName = $post['entity'];


        $ladService = new LadService($this->getTranslationService());
        $directoryLad = $ladService->directoryLad;

        if ($secto) {
            $directoryLad .= $secto.'\\';
        }

        $text = $action.' | '.date('Ymd').' | '.date('His').' | '.$_SESSION["Session_Login"].' | ';

        Fichier::createFichier($directoryLad, $fileName.'.action.txt', $text);

        return new Response(200);
    }


    /**
     * @return false|string
     */
    public function affichagPDFJRejectedAction()
    {
        $post = $this->request->getParsedBody(true);

        $ladService = new LadService($this->getTranslationService());
        $directoryLad = $ladService->directoryLad;

        if ($post['secto']??null) {
            $directoryLad .= $post['secto'].'\\';
        }

        /**
         * Mise en place du header
         */
        Outils::getHeaderByFile($directoryLad.$post['file']);
        return Fichier::getContentFile($post['file'], $directoryLad);
    }
}
