<?php
namespace Modules\Index\Controller;

use Entity\Model\Paravrac;
use Helpers\Outil\Outils;
use Skeleton\Controller\Controller;
use Helpers\Outil\Sql;
use GuzzleHttp\Psr7\Response;
use Helpers\Fichier\Fichier;
use Helpers\Securite\Securite;
use Helpers\Trad\Trad;
use Modules\Index\Repository\Connexion;
use Modules\Index\Outil\OutilConnexion;
use Modules\Panier\Repository\PanierLigne;
use Helpers\Supervision\Supervision;
use Modules\Index\Service\MagicSaml2Service;
use Psr\Http\Message\ResponseInterface;

class ADFSController extends Controller
{
    public $droitAcces = true;

    private string $nameMagicSession = 'OXA_MAGIC_PASSERELLE_SAML2';

    public function init()
    {
        unset($_SESSION['SAML2_CONNECT']);
    }
    
    /**
     * ssoInterneAction
     *
     * @return mixed
     */
    public function ssoInterneAction()
    {
        $token = $this->request->getAttribute('token');
        /** @phpstan-ignore-next-line */
        $bodyToken =  explode('|', Securite::decryptTokenCSRF(
            /** @phpstan-ignore-next-line */
            str_replace(
                'spluss',
                '+',
                str_replace(
                    'segals',
                    '=',
                    str_replace('sslachs', '/', $token)
                )
            ),
            true,
            true
        ));

        if ($bodyToken[0]>time()) {
            return $this->ADFSAction($bodyToken[1]);
        } else {
            return (new Response())->withStatus(301)->withHeader('Location', $this->contenaire->get('urlOxaproc').'/index.php');
        }
    }
    
    /**
     * ADFSAction
     * TODO : BBA change le nom de la classe et de la fonction car c'est une erreur d'appelations
     * Faire une grosse refactorisation quand on reprendra la connexion en PHP
     * @param  string $login
     * @return mixed
     */
    public function ADFSAction(string $login = '')
    {
        if ($login != '') {
            $saml2Actif = false;
        } else {
            $saml2Actif = true;
            $post = $this->request->getParsedBody(true);
            $ADFS = new \Helpers\SSO\ADFS($this->contenaire, $post, $this->pdo, false, $this->request->getAttribute('logout'));
            $login = $ADFS->getLogin();

            /**
             * Connexion SSO SAML with Magic
             */
            if (!empty($login) &&
                isset($_SESSION[$this->nameMagicSession])
                ) {
                /**
                 * get token uuid in SESSION
                 */
                $uuid = $_SESSION[$this->nameMagicSession];

                /**
                 *  Delete session
                 */
                unset($_SESSION[$this->nameMagicSession]);
                
                (new MagicSaml2Service($this->pdo))
                ->getStringForMagic($uuid, $login);
                
                return new Response(
                    200,
                    [],
                    $this->renderer->render(
                        '@magicSaml2/renderSaml2',
                        []
                    )
                );
            }
        }
        $debutConnexion = microtime(true);
        $redirect = $this->request->getAttribute('redirect');

        $access = $this->request->getAttribute('access');
        $mail = $this->request->getAttribute('mail');
        $id = $this->request->getAttribute('id');
        $profil = $this->request->getAttribute('profil');
        $menu = $this->request->getAttribute('menu');



        $connexionOutil = new OutilConnexion($this->pdo, $this->pdoOxaFT, $this->contenaire);
        if (!isset($_SESSION['OxaParams'])) {
            $connexionOutil->AllParamsInit();
        }
        
        // @phpstan-ignore-next-line
        $VersionProduit = getVersionProduit();

        if (!file_exists('../../../application/webroot/php/include/source_control_' . $VersionProduit . '.oxa')) {
            return $this->redirect('Index.Index.errorIntegrite');
        }
        /**
         * Initialisation des variables
         */
        $messageErreur = '';
        $redirectionAutorise = true;
        
        $panierLigneSQL = new PanierLigne($this->pdo);
        $connexionSQL = new Connexion($this->pdo);
        $infoEnvironnement = $connexionOutil->controlVersion($VersionProduit);
        $trad = $this->getTranslationService();
       
        // Reception des informations

        if (isset($login) && $login !='') {
            Supervision::setHeureDebut();
            
            $result = $connexionSQL->getInfoUser($login);
            
            $Wsdl = new \Modules\Index\WebService\Utilisateur($this->pdo);
            $xmlResult = $Wsdl->WsdlIdent($login, '', $result['COD_LNG'], [], false, null, 1);
            
            // $response = new \SimpleXMLElement($xmlResult->responseData);
            $xml = simplexml_load_string($xmlResult->responseData);
            $json = json_encode($xml);
            $resultat = json_decode($json, true);

            
            if ($resultat['ConnexionReussie'] == 'true') {
                if (Outils::getPreferredProtocol() == 'https://') {
                    session_id(bin2hex(random_bytes(16)));
                }
                $connexionOutil->getEnv();

                $paravrac = new Paravrac($this->pdo);
                $getUrl = $paravrac->find([
                    'TYPEPARV' => 'PARAMADFS',
                    'CODEPARV' => 'URLRETOURCLIENT'
                    ]);
                if ($saml2Actif) {
                    if (is_array($getUrl) && count($getUrl)) {
                        $_SESSION['ADFS_URL_DECONNEXION'] = $getUrl['LIB01PARV'];
                    }
                    $_SESSION['SAML2_CONNECT']  = true;
                }
                if ($redirectionAutorise) {
                    if ($access == 'mail') {
                        $_SESSION['REDIRECTION'] = true;
                        $_SESSION['ID_TMP'] = $id;
                        $_SESSION['PROFIL_TMP'] = $profil;
                        $_SESSION['MENU_TMP'] = $menu;
                        
                        switch ($profil) { // Ses informations permettront une redirection suite à  l'authentification de l'user
                            case 'SupHier':
                                // Permet de passer le champ imput login à  display: none
                                // $array['viewer']['fiche_ident']['accesExt'] = array(
                                //     '!display' => 'none'
                                // );
                                // Permet de présenter le login en dur dans un TD
                                // $array['viewer']['fiche_ident']['login'] = array('!texte' => $_GET['id'],'!flg_affiche' => 1, 'flg_input' => 1);
                                // $array['viewer']['fiche_ident']['login']['!texte'] = $_GET['id'];
                                
                                break;
                            case 'Dem':
                                // On redirige le demandeur vers la page suivi d'activation de compte
                                return (new Response())->withStatus(301)->withHeader('Location', $this->contenaire->get('base').'/suivi_compte.php');
                        }
                    } else {
                        // On supprime les infos de redirections si connexion directe
                        unset($_SESSION['REDIRECTION']);
                        unset($_SESSION['ID_TMP']);
                        unset($_SESSION['PROFIL_TMP']);
                        unset($_SESSION['MENU_TMP']);
                    }

                    if ($result) {
                        if ($result['HAST_PGDEFAULT_PAGE'] && $result['HAST_PGDEFAULT_MODULE']) {
                            $connexion_redirect = true;
                            $data_redirection=[
                                'onglet' => $result['HAST_PGDEFAULT_PAGE'],
                                'module' => $result['HAST_PGDEFAULT_MODULE'],
                            ];
                        }
                        
                        if (!$_SESSION['Session_Langue']) {
                            if (isset($_COOKIE['OxaprocDeflangue'])) {
                                $_SESSION['Session_Langue'] = $_COOKIE['OxaprocDeflangue'];
                            } else {
                                $_SESSION['Session_Langue'] = $result['COD_LNG'];
                            }
                        }

                        $_SESSION['OXAPRC_LOGUSR_XML'] = & $xmlResult->responseData;
                        $resultSession = $connexionOutil->gestionSessionConnexion($resultat, $login, $result['COD_LNG']);
                        $result_connexion = $resultSession['ConnexionReussie'];
                        $result_oxasrm = $resultSession['ConnexionOXASRM'];
                        $result_oxaproc = $resultSession['ConnexionEproc'];
                        if (isset($_SESSION['MobileTypeConnexion'])) {
                            $result_oxaproc =true;
                        }
                        
                        // Tracage de la connexion
                        $connexionSQL->trackConnexionIn($_SESSION['Session_Login']);
                    }
                }
            } else {
                // $messageErreur = $resultat['MsgAnomalie'];
                return $this->redirect('Index.Connexion.connexion', ['redirect' => 1 , 'error' => 'errorSSO']);
            }
        }

        if ($infoEnvironnement['bloquant']) {
            $redirectionAutorise = false;
            $message = $trad->t('La version de vos programmes a changé. Des opérations de mise à niveau de la base de données sont nécessaires. Veuillez contacter votre administrateur.');
            
            if ($messageErreur) {
                $messageErreur = '<br />'.$message;
            } else {
                $messageErreur = $message;
            }
        }

        if ($result_connexion) {
            if (isset($result['INT_COUL']) && $result['INT_COUL']!='') {
                $_SESSION['SESSION_SKIN_CODE'] = $result['INT_COUL'];
            }
            
            if (! isset($_SESSION['connexionModeSSO'])) {
                $_SESSION['connexionModeSSO'] = 0;
            }
            
            if ($result_oxaproc || $result_oxasrm) {
                Supervision::setIdUser($_SESSION['Session_Login']);
                Supervision::setTypeTraitement('IL');
                
                if ($result_oxaproc) {
                    $nblignes = $panierLigneSQL->getNbLignePanier(0, $_SESSION['id_user']);
                    $panierEntete = $connexionSQL->getInfoPannier(0, $_SESSION['id_user']);
                    
                    if ($nblignes == 0) {
                        $societeTmp = $_SESSION['Session_SocUsrProfil'];
                        $_SESSION['Tampon_SocUsr'] = $_SESSION['Session_SocUsrProfil'];
                    } else {
                        $societeTmp = $panierEntete['CODE_STE'];
                        $_SESSION['Tampon_SocUsr'] = $panierEntete['CODE_STE'];
                    }

                    //TODO V12
                    //(new OutilConnexion($this->pdo, $this->pdoOxaFT, $this->contenaire))->setSociete($societeTmp);

                    $ch = curl_init();
                    
                    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
                    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
                    curl_setopt($ch, CURLOPT_COOKIESESSION, true);
                    curl_setopt($ch, CURLOPT_COOKIE, session_name() . '=' . session_id());
                    curl_setopt($ch, CURLOPT_URL, Outils::getRootUrl(true) . $this->contenaire->get('base').'passerelleV1V2.php?fonction=setSociete&societe='.$societeTmp);
                    session_write_close();
                    curl_exec($ch);
                    
                    curl_close($ch);


                    if (Outils::getPreferredProtocol() == 'https://') {
                        session_set_cookie_params(["samesite" => "None", 'Secure' => true]);
                    }
                    session_name('__OxaProc-PHPSESSID');
                    @session_start();

                    if (empty($_SESSION['id_panier'])) {
                        $_SESSION['id_panier'] = 0;
                    }
                } elseif ($result_oxasrm) {
                    $_SESSION['link_ria'] = '';
                    
                    $_SESSION['SocUsr'] = $_SESSION['Session_SocUsrProfil'];
                }

                if (!Sql::paramDico($this->pdo, 'TRACELOGIN', session_id(), '', $_SESSION['Session_Login'])) {
                    $connexionSQL->insertConnexionUser($_SESSION['Session_Login'], (string)$_SESSION['Session_Langue'], (string)$result['SocUsr']);
                }
                $_SESSION['Tampon_SocUsr'] = (array_key_exists('SocUsr', $_SESSION)) ? $_SESSION['SocUsr'] : '';

                $valeur_init_session = $connexionOutil->getAllValueInitSessionByUserAndSociete($_SESSION['Session_Login'], $_SESSION['Session_SocUsr']);
                $connexionOutil->setAllFieldsSessionUser($valeur_init_session);
                
                $_SESSION['user_is_logged'] = true;
                
                /**
                 * On enregistre dans un cookie l'heure de démarrage de la session
                 */
                $start_sessionTmp = microtime(false);
                $start_session = explode(' ', $start_sessionTmp);
                $session_expireTmp = session_get_cookie_params();
                $session_expire = $session_expireTmp['lifetime'];
                
                $arr_cookie_options = array (
                    'expires' =>  time() + $session_expire,
                    //'secure' => true,     // or false
                    //'httponly' => true,    // or false
                    //'samesite' => 'None' // None || Lax  || Strict
                    );
                if (Outils::isHttps()) {
                    $arr_cookie_options['samesite'] = 'None';
                    $arr_cookie_options['secure'] = true;
                }
                setCookie('start_session', 'start_session=' . $start_session[1], $arr_cookie_options);
                
                Supervision::executionAsynchrone($this->router->generateUri('GlobalApplication.Outil.supervision'));

                //MOBILITY
                if (isset($_SESSION['ContexteMobile']) && $_SESSION['ContexteMobile']==true) {
                    return $this->redirect('Index.MobilityConnexion.returnResponse');
                }
                // FIN Mobility
                
                if ($result_oxaproc) {
                    $utilisateurSQL = new \Modules\GlobalApplication\Repository\Utilisateur($this->pdo);
                    $user = $utilisateurSQL->rqInfoUserByLogin($_SESSION['Session_Login']);
                    $_SESSION['id_user'] = $user['id_user'];

                    $finConnexion = microtime(true);
                    $tempo = (int) (($finConnexion - $debutConnexion) * 1000);
                    sql::logAudit($this->pdo, 'LOGIN', 'ENTREE', 'CONNEXION OK', '', '', $tempo);
                    
                    if ($user['ExpirationMdP'] == 1 && $user['GestionMotdePasse']) {
                        return $this->redirect($this->contenaire->get('base').'change_password.php');
                    }
                } else {
                    return $this->redirect($this->contenaire->get('base').'portail_ipade.php');
                }

                // Init Session pour V1
                $_SESSION['initConnexion'] = 1;
                
                if (isset($_SESSION['redirect'])) {
                    $redirect = $_SESSION['redirect'];
                    unset($_SESSION['redirect']);
                    return $this->redirect($redirect);
                }

                if ($connexion_redirect && $result['HAST_PGDEFAULT_PAGE'] && $result['HAST_PGDEFAULT_MODULE']) {
                    $_SESSION['typeMenu'] = $data_redirection['onglet'];


                    switch ($data_redirection['module']) {
                        case 'Accueil':
                            return $this->redirect('Index.Index.index');
                        case 'Recherche':
                            return $this->redirect('RechercheArticles.RechercheArticles.recherche');
                        case 'Facture':
                            return $this->redirect('Facture.GestionFacture.index');
                        case 'Contrat':
                            return $this->redirect('Contrat.accord-cadre.index', ['type' => 'ALL', 'idacc' => 'ALL']);
                        case 'Fourniss':
                            return $this->redirect('Fournisseur.GestionFournisseur.index');
                        case 'Admin':
                            return $this->redirect($this->contenaire->get('base').'session_ipad.php?call=Administration');
                        case 'EtatStat':
                            return $this->redirect('EtatStatistiques.GestionStatistique.listeEtats');
                        case 'Collecte':
                            return $this->redirect('GlobalApplication.CollecteDesBesoins.index');
                        case 'Consultation':
                            //return $this->redirect($this->contenaire->get('base').'session_ipad.php?call=Consultation');
                            return $this->redirect('Consultation.GestionConsultation.index');
                        case 'Projet':
                            //return $this->redirect($this->contenaire->get('base').'session_ipad.php?call=ProjetAchat');
                            return $this->redirect('ProjetAchat.GestionProjetAchat.tableauBord');
                        case 'Eval':
                            return $this->redirect('Evaluation.Evaluation.index');
                        case 'Tableau':
                            return $this->redirect('Index.Index.index');
                        default:
                            $_SESSION['typeMenu'] = $_SESSION['typeMenu']?? 'P2P';
                            //return $this->redirect($this->contenaire->get('base').'session_ipad.php');
                            return $this->redirect('Index.TableauDeBord.index');
                    }
                } else {
                    $_SESSION['typeMenu'] = $_SESSION['typeMenu']?? 'P2P';
                    return $this->redirect('Index.TableauDeBord.index');
                }
            } else {
                $finConnexion = microtime(true);
                $tempo = (int) (($finConnexion - $debutConnexion) * 1000);
                sql::logAudit($this->pdo, 'LOGIN', 'ENTREE', 'ECHOUE', '', '', $tempo);
                
                $messageErreur = $trad->t('Aucune application n\'est disponible pour votre compte.');
            }
        } else {
            if (isset($_SESSION['MESSAGE_ERREUR_WEBSERVICE']) && $_SESSION['MESSAGE_ERREUR_WEBSERVICE'] != '') {
                $messageErreur = $_SESSION['MESSAGE_ERREUR_WEBSERVICE'];
            }
        }
        
        return $this->redirect('Index.Connexion.connexion');
    }
    
 
    public function metadataAction()
    {
        
        header("Content-type: text/xml");
        $post = $this->request->getParsedBody(true);
        return new \Helpers\SSO\ADFS($this->contenaire, $post, $this->pdo, true);
    }

    
    public function connectMagicSaml2Action() : ResponseInterface
    {
        $uuid =  $this->request->getAttribute('uuid');

        /**
         * Create session for context
         */
        $_SESSION[$this->nameMagicSession] = $uuid;

        return  $this->ADFSAction();
    }
}
