<?php

namespace Modules\Connexion\Service;

use Entity\Model\Hastutil;
use Entity\Model\OxaUsers;
use Entity\Model\Societe;
use Helpers\Outil\Outils;
use Helpers\Session\ParseBase1;
use Helpers\Session\Session;
use Helpers\Trad\ITrad;
use Modules\GlobalApplication\Repository\LicenceOxalys;
use Modules\Index\Repository\Connexion;
use Helpers\Outil\Sql;
use Modules\Index\Repository\User;
use Modules\Index\Service\SessionService;
use Helpers\Outil\Roles;
use Helpers\Outil\Date;
use Helpers\Trad\Trad;
use Modules\Panier\Service\OutilPanierService;
use Psr\Container\ContainerInterface;

class InitialisationSessionUser
{
    public function __construct(
        public \PDO $pdo,
        public \PDO $pdoOxaFT,
        private ITrad $trad,
    ) {
    }

    public function initSessionUser(string $login, ?string $langue = null):void
    {
        OutilPanierService::checkRechercheActif($this->pdoOxaFT);
                
        if (Outils::isHttps()) {
            session_set_cookie_params(["samesite" => "None", 'Secure' => true]);
        }

        Session::initSessionActive();

        if (strtoupper($login) != 'OXAUSER' && strtoupper($login) != 'ADMIN') {
            $hastutil = (new Connexion($this->pdo))->getInfoUser($login);
        } else {
            $hastutil['CODE'] = strtoupper($login);
            $hastutil['CODE_STE'] = (new User($this->pdo))->getSocieteOuverteMulti()['CODE_STE'];
            $hastutil['SIG_DA'] = true;
            $hastutil['SIG_CDE'] = true;
            $hastutil['SIG_BAP'] = true;
            $hastutil['SIG_REF'] = true;
            $hastutil['MAGASIN'] = true;
            $hastutil['OXTRBRDAU'] = true;
            $hastutil['ACCOXTRA'] = true;
            $hastutil['ACCOXAPR'] = true;
        }
        
        $_SESSION['Session_Login'] = strtoupper($login);
        $_SESSION['Session_UO'] = $hastutil['CODE_UO']??'';
        $_SESSION['NiveauConfidentialite'] = (int)($hastutil['NIV_CONF']??0);
        $_SESSION['Session_UsrMultiSoc'] = sql::toBool($hastutil['UTIMULTI']??true);
        $_SESSION['Session_UsrPluriSoc'] = $_SESSION['Session_UsrMultiSoc']? false:(!empty((new Connexion($this->pdo))->listeSocForUserCurrent()));
        $_SESSION['SuperieurHierarchique'] = sql::toBool($hastutil['USRSUPHIE']??false);

        $_SESSION['SIG_DA']  = sql::toBool($hastutil['SIG_DA']);
        $_SESSION['SIG_CDE'] = sql::toBool($hastutil['SIG_CDE']);
        $_SESSION['SIG_BAP'] = sql::toBool($hastutil['SIG_BAP']);
        $_SESSION['SIG_REF'] = sql::toBool($hastutil['SIG_REF']);
        $_SESSION['User']['Hastutil'] = $hastutil;

        $_SESSION['SIG_DELEGATION'] = ($_SESSION['SIG_DA'] || $_SESSION['SIG_CDE'] || $_SESSION['SIG_BAP']);

        $_SESSION['AdmLocal']   = (strtoupper($login) == 'OXAUSER' || strtoupper($login) == 'ADMIN')? true:sql::toBool($hastutil['ADMLOCAL']);
        $_SESSION['AdmCentral'] = (strtoupper($login) == 'OXAUSER' || strtoupper($login) == 'ADMIN')? true:sql::toBool($hastutil['ADMCENTR']);

        $_SESSION['AccesRecept'] = (new LicenceOxalys($this->pdo))->brActive() && roles::droitsUtilisateur($this->pdo, 'HA_BR_VIS');

        $_SESSION['AcessFacture'] = roles::droitsUtilisateur($this->pdo, 'HA_FA_VISU'); // HA_FA_VISU && module facture
        $_SESSION['IS_CG_ACTIVE'] = (new LicenceOxalys($this->pdo))->codeGestionActive();

        if (!$_SESSION['Session_Langue']) {
            $_SESSION['Session_Langue'] = $langue ?? Roles::droit($this->pdo, 'LNGBDD', 'PARAMOXA', true);
        }

        $societe = $this->checkSocieteOpen($hastutil);
        $this->societeActive($societe);
        
        $_SESSION['Session_SocUsrProfil'] = $societe;

        //PARAM USER
        $this->initAuthLigne($login);

        $this->updateLoginUser($login, $langue, $societe, $hastutil);

        $user = (new OxaUsers($this->pdo))->find(['upper(login)' => strtoupper($login)]);
        $_SESSION['id_user'] = $user['id_user'];

        $sessionService = new SessionService($this->pdo);
        $valeur_init_session = $sessionService->getAllValueInitSessionByUserAndSociete($login, $societe);
        
        $sessionService->setAllFieldsSessionUser($valeur_init_session);
        
        $_SESSION['Session_NumClient'] = sql::getNumClient($this->pdo);

        $paramUser = Sql::getParamUser($this->pdo, $_SESSION["Session_Login"], 'RECHERCHE', 'NB_ART_PAGE_RECH');
        if ($paramUser) {
            $_SESSION['NB_ART_PAGE_RECH'] = $paramUser;
        } else {
            $param = sql::paravrac($this->pdo, 'OXAPROC', 'NBLIGPAGE');
            $explodeParam = explode('|', $param);

            if ($param && $explodeParam[1]) {
                $_SESSION['NB_ART_PAGE_RECH'] = $explodeParam[1];
            } else {
                $_SESSION['NB_ART_PAGE_RECH'] = 20;
            }
        }

        $formatDate = (new Connexion($this->pdo))->getNumFormatDate($_SESSION['Session_Langue']);
        $_SESSION['DATE_FORMAT'] = Date::getDateFormatByNumDate($formatDate['FORMAT_LNG']??$formatDate['LANGUEDEF']);

        //licence
        $_SESSION['AccesStock'] = (sql::toBool($hastutil['MAGASIN']) || (strtoupper($login) == 'OXAUSER' || strtoupper($login) == 'ADMIN')) && (new LicenceOxalys($this->pdo))->stockActive()&& (new LicenceOxalys($this->pdo))->bsActive();

        $_SESSION['BR_UniqSesDemandes'] = $_SESSION['AccesRecept']? sql::toBool($hastutil['OXTRBRDAU']):false;

        if ($_COOKIE['MODE_AFFICHAGE_ARTICLE']??'') {
            $_SESSION['MODE_AFFICHAGE_ARTICLE'] = $_COOKIE['MODE_AFFICHAGE_ARTICLE'];
        } elseif (!array_key_exists('MODE_AFFICHAGE_ARTICLE', $_SESSION)) {
            $sqlRecherchePrestation = sql::paravrac($this->pdo, 'OXAPROC', 'RECHERCHE_PRESENTATION');
            $_SESSION['MODE_AFFICHAGE_ARTICLE'] = ($sqlRecherchePrestation)?$sqlRecherchePrestation:'S';
        }

        $_SESSION['ETAT_STAT_SPEC'] = file_exists((new ParseBase1())->getRep()->application.'\oxaproc\src\Modules\Additional\Specifique\Client'.((int)$_SESSION['Session_NumClient']).'\Modules\EtatStatistique\Controller');

        $_SESSION['ConnexionOXASRM']    = sql::toBool($hastutil['ACCOXTRA']);
        $_SESSION['ConnexionEproc']     = sql::toBool($hastutil['ACCOXAPR']);

        (new OxaUsers($this->pdo))->update([
            'CodeCtrLivraison'  => $_SESSION['Session_CodeCtrLivraison']??'',
        ], ['login' => $login]);
    }

    /**
     * @param array<mixed> $infoUser
     * @return string
     */
    private function checkSocieteOpen($infoUser):string
    {
        $infoSociete = (new Societe($this->pdo))->find($infoUser['CODE_STE']);

        if ($infoSociete['DTEVALMIN'] <= date('Ymd') && ($infoSociete['DTEVALMAX'] == '00000000' || $infoSociete['DTEVALMAX'] >= date('Ymd'))) {
            return $infoUser['CODE_STE'];
        } else {
            $societeFound = (new User($this->pdo))->getSocieteOuvertePluri($infoUser['CODE']);

            if ($societeFound) {
                return $societeFound['CODE_STE'];
            } elseif (sql::toBool($infoUser['UTIMULTI'])) {
                $societeFound = (new User($this->pdo))->getSocieteOuverteMulti();
                if ($societeFound) {
                    return $societeFound['CODE_STE'];
                }
            }
        }

        return $infoUser['CODE_STE'];
    }

    private function societeActive(string $codeSte) : void
    {
        // Mise à jour de la variable de session indiquant si la societe est valide
        $paramDebut = sql::paravrac($this->pdo, 'PARAMGEN', 'CMIN_SODA');
        $paramFin = sql::paravrac($this->pdo, 'PARAMGEN', 'CMAX_SODA');
        $societe = (new Connexion($this->pdo))->getInfoSte($codeSte);
        $today = date('Ymd');
        
        if (($paramDebut == 'B' && $societe['DTEVALMIN'] != '00000000' && $today < $societe['DTEVALMIN']) || ($paramFin == 'B' && $societe['DTEVALMAX'] != '00000000' && $today < $societe['DTEVALMIN'])) {
            $_SESSION['IS_STE_VALIDE'] = false;
        } else {
            $_SESSION['IS_STE_VALIDE'] = true;
        }
    }

    private function initAuthLigne(string $login): void
    {
        if (strtoupper($login)=='OXAUSER' || strtoupper($login)=='ADMIN') {
            $_SESSION['GLOB_AuthLigneGenerique']    = true;
            $_SESSION['GLOB_AuthLigneSFamille']     = true;
            $_SESSION['GLOB_AuthLigneManuelle']     = true;
            $_SESSION['GLOB_AuthLigneLibre']        = true;
    
            $_SESSION['AuthLigneManuelle']          = true;
        } else {
            $dilispecLigne = sql::dilispec($this->pdo, 'OXAPPARUSR', strtoupper($login));
            $explodeLigne = explode('|', $dilispecLigne);

            $infoPublication = (new Connexion($this->pdo))->isPublicationGenerique()['PARAVAL']??'0';

            if ($infoPublication == 1) {
                $_SESSION['GLOB_AuthLigneGenerique'] = true;
                $_SESSION['GLOB_AuthLigneSFamille'] = true;
            } elseif ($infoPublication == 'AG') {
                $_SESSION['GLOB_AuthLigneGenerique'] = true;
                $_SESSION['GLOB_AuthLigneSFamille'] = sql::boolSql($explodeLigne[4]??false);
            } elseif ($infoPublication == 'SF') {
                $_SESSION['GLOB_AuthLigneGenerique'] = sql::boolSql($explodeLigne[3]??false);
                $_SESSION['GLOB_AuthLigneSFamille'] = true;
            } else {
                $_SESSION['GLOB_AuthLigneGenerique'] = sql::boolSql($explodeLigne[3]??false);
                $_SESSION['GLOB_AuthLigneSFamille'] = sql::boolSql($explodeLigne[4]??false);
            }
    
            $_SESSION['GLOB_AuthLigneManuelle']         = sql::boolSql($explodeLigne[0]??false);
            $_SESSION['GLOB_AuthLigneLibre']            = sql::boolSql($explodeLigne[5]??false);
    
            $_SESSION['AuthLigneManuelle']              = sql::boolSql($explodeLigne[0]??false);
        }
        //Select LIB01DICO from DILISPEC where TYPEDICO='OXAPPARUSR' and CODEDICO=<Utilisateur>
        // explode[0] AuthLigneManuelle
        // explode[3] AuthLigneGenerique
        // explode[4] AuthLigneSFamille
        // explode[5] AuthLigneLibre
    }

    /**
     * @param string $login
     * @param string $langue
     * @param string $societe
     * @param array<mixed> $loginTry
     * @return void
     */
    private function updateLoginUser(string $login, string $langue, string $societe, $loginTry):void
    {
        $login = strtoupper($login);
        $connexionSQL = new Connexion($this->pdo);

        $param = sql::paravrac($this->pdo, 'OXAPROC', 'NBLIGPAGE');
        $explodeParam = explode('|', $param);

        if ($login=='OXAUSER' || $login=='ADMIN') {
            $buf_user = (new Connexion($this->pdo))->getUserOxaproc($login);
            if (!$buf_user) {
                $result = [
                    'ExpirationMdP'     => false,
                    'NbLignePagination' => $explodeParam[0],
                    'AuthLigneManuelle' => $_SESSION['AuthLigneManuelle'],
                    'GestionMotdePasse' => true,
                    'CodeCtrLivraison'  => $_SESSION['Session_CodeCtrLivraison']??'',
                    'NomUser'           => $login,
                ];
                $connexionSQL->insertOxaUser($login, $result);

                $buf_user = (new Connexion($this->pdo))->getUserOxaproc($login);
            }
            $_SESSION['id_user'] = $buf_user['id_user'];
            $_SESSION['id_panier'] = 0;
            $_SESSION['sys_panier'] = 'SYS';
            return;
        }
        if (!Sql::paramDico($this->pdo, 'TRACELOGIN', (string)session_id(), '', $login)) {
            $connexionSQL->insertConnexionUser($login, $langue, $societe);
        }
        
        if (sql::boolSql($loginTry['MMDPCNX'])) {
            $expireMdp = true;
        } elseif ($loginTry['TYP_LOGIN'] == '' || $loginTry['TYP_LOGIN'] == 'H') {
            $dateDerniere = $loginTry['DATDMMDP'];
            $validiteMdp = sql::paravrac($this->pdo, 'PARAMGEN', 'DUR_VAL_MDP');

            if (!$validiteMdp) {
                $validiteMdp = 90;
            }

            $dateMax = date('Ymd', (int)strtotime($dateDerniere. ' + '.$validiteMdp.' day'));

            $expireMdp = date('Ymd')>=$dateMax;
        } else {
            $expireMdp = false;
        }

        $result = [
            'ExpirationMdP'     => $expireMdp,
            'NbLignePagination' => $explodeParam[0],
            'AuthLigneManuelle' => $_SESSION['AuthLigneManuelle'],
            'GestionMotdePasse' => true,
            'CodeCtrLivraison'  => $_SESSION['Session_CodeCtrLivraison']??'',
            'NomUser'           => $loginTry['NOM'],
        ];

        if ($connexionSQL->infoOxaUser($login)) {
            $connexionSQL->updateOxaUser($login, $result);
        } else {
            $connexionSQL->insertOxaUser($login, $result);
        }

        $buf_user = $connexionSQL->getUserOxaproc($login);
        if ($buf_user) {
            $_SESSION['id_user'] = $buf_user['id_user'];
            $_SESSION['id_panier'] = 0;
            $_SESSION['sys_panier'] = 'SYS';
            
            $result['id_user'] = $_SESSION['id_user'];
            
            if (!$connexionSQL->existePanierUser($buf_user)) {
                $connexionSQL->insertPanierUser(
                    $_SESSION['id_user'],
                    $this->trad->t('En cours')
                );
            }
        }
    }
}
