<?php

namespace Modules\Index\WebService;

use Entity\Model\Alias\ParamUtilisateur;
use Entity\Model\UO;
use Helpers\Fichier\Fichier;
use Helpers\Outil\ArrayHelper;
use Helpers\Outil\Outils;
use Helpers\Outil\Roles;
use Helpers\Trad\ITrad;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\UploadedFileInterface;
use Skeleton\Router;

class UtilisateurWsdl
{
    private ?ContainerInterface $contenaire;
    private \PDO $pdo;
    
    public function __construct(?ContainerInterface $contenaire = null)
    {
        $this->contenaire = $contenaire;
        $this->pdo = $contenaire->get('PDO.oxasql');
    }

    public function getRouter() :Router
    {
        return $this->contenaire->get(Router::class);
    }
    
    public function callWSDLForTestSMTP(string $LoginMessagerie, string $MdPMessagerie, string $Mail, ITrad $trad) :\Helpers\Webservice\Wsdl
    {

        $corps = $trad->t('Bonjour,') . PHP_EOL
            . $trad->t('Si vous recevez ce message, c\'est que le test de vos paramètres de messagerie a été effectué avec succès.') . PHP_EOL
            . $trad->t('Cordialement, Votre administrateur');
        
        $sujet = $trad->t("Test de connexion au serveur de messagerie");

        $envoi = '<MailIn>';

        $envoi .='<ListDest>';
        $envoi .='<Mail>'.$Mail.'</Mail>';
        $envoi .='</ListDest>';

        $envoi .='<User></User>';

        $envoi .='<AdrMailUser>'.$Mail.'</AdrMailUser>';

        $envoi .='<LoginMessagerie>'.$LoginMessagerie.'</LoginMessagerie>';
        $envoi .='<MdPMessagerie>'.$MdPMessagerie.'</MdPMessagerie>';

        $envoi .='<Sujet>'.htmlspecialchars($sujet).'</Sujet>';

        $envoi .='<Corps>'.htmlspecialchars($corps).'</Corps>';

        $envoi .='</MailIn>';

        return new \Helpers\Webservice\Wsdl('Oxaproc_CreatMod_User', 'OXAPRC_ENVOIMAIL', $envoi, false);
    }
    
    /**
     * @param array<mixed> $array
     * @param string $FichierImageSignature
     */
    public function creationCompte($array, $FichierImageSignature = '') :\Helpers\Webservice\Wsdl
    {

        if ($array['SUPHIERARCHIQUE']) {
            $codeAppro = $array['SUPHIERARCHIQUE'];
        } else {
            $codeAppro = (new UO($this->pdo))->find(['CODE_UO' => $array['Uo']], ['RESP_HIER'])['RESP_HIER']??'';
        }

        $UrlConnectSignataire = $this->contenaire->get('urlOxaproc') . '/index.php?acces=mail&amp;id=' . ($codeAppro) . '&amp;profil=SupHier&amp;menu=Inscription&amp;refDemande=';
        $UrlSuiviDemandeur    = $this->contenaire->get('urlOxaproc') . '/index.php?acces=mail&amp;id=' . $array['MAIL'] . '&amp;profil=Dem&amp;menu=SuiviDem&amp;refDemande=';
        
        $domaine = $array['DOMFONCT'];
        $listeDomaine = explode('/', $domaine);
        
        $envoi = "<UserIn LngUtilisation='".$_SESSION['Session_Langue']."'>
                      <UserActiveDirectory>".$this->wsdlBool($array['ActiveDirectory'])."</UserActiveDirectory>
                      <ListDomFonctionnels>";
        
        foreach ($listeDomaine as $domaine) {
            $envoi .= "<DomFonctionnel>{$domaine}</DomFonctionnel>";
        }
        
        $array['MDP'] = htmlspecialchars($array['MDP']);
        $array['MDP_SIGNA'] = htmlspecialchars($array['MDP_SIGNA']);
        
        $envoi .= "   </ListDomFonctionnels>
                      <DomaineActiveDirectory>".$array['DOMAINE']."</DomaineActiveDirectory>
                      <LoginMessagerie>".$array['CODE_UTILISATEUR']."</LoginMessagerie>
                      <MdPMessagerie>".$array['MessagerieMdp']."</MdPMessagerie>
                      <CdeEproc>".$this->wsdlBool($array['commandeEproc']??'')."</CdeEproc>
                      <SaisieLibreArt>".$this->wsdlBool($array['LIGNE_MANUELLE']??'')."</SaisieLibreArt>
                      <SaisieLibreGene>false</SaisieLibreGene>
                      <SaisieLibreSsfam>false</SaisieLibreSsfam>
                      <SaisieLibreRecherche>".$this->wsdlBool($array['LIGNE_LIBRE']??'')."</SaisieLibreRecherche>
                      <SeuilCde>".$array['CDE_EPROC']."</SeuilCde>
                      <Abonnements>
                        <ModuleApprovisionnement>
                          <Actif>".$this->wsdlBool($array['modeAppro']??'')."</Actif>
                          <MailSaisieBR>".$this->wsdlBool($array['SAISIE_VALIDE']??'')."</MailSaisieBR>
                          <MailApprobDA>".$this->wsdlBool($array['SIGNA_DA']??'')."</MailApprobDA>
                          <MailDATraitee>".$this->wsdlBool($array['DA_TRAIT']??'')."</MailDATraitee>
                          <MailComparAO>".$this->wsdlBool($array['COMP_AO']??'')."</MailComparAO>
                          <MailApprobCA>".$this->wsdlBool($array['SIG_CDE']??'')."</MailApprobCA>
                        </ModuleApprovisionnement>
                        <ModuleRecep>
                          <Actif>".$this->wsdlBool($array['mdouleSaisieRecep']??'')."</Actif>
                        </ModuleRecep>
                        <ModuleApprobation>
                          <Actif>".$this->wsdlBool($array['ModuleSignature']??'')."</Actif>
                          <ApprobDA>".$this->wsdlBool($array['DEMANDE_ACHAT']??'')."</ApprobDA>
                          <MailDA>".$this->wsdlBool($array['DA_SIG']??'')."</MailDA>
                          <ApprobCde>".$this->wsdlBool($array['COMMANDE']??'')."</ApprobCde>
                          <MailCde>".$this->wsdlBool($array['CDE_SIG']??'')."</MailCde>
                          <ApprobBAP>".$this->wsdlBool($array['BONAP']??'')."</ApprobBAP>
                          <MailBAP>".$this->wsdlBool($array['BAP_SIG']??'')."</MailBAP>
                          <FichierImageSignature>$FichierImageSignature</FichierImageSignature>
                        </ModuleApprobation>
                        <ModuleBonSortie>
                          <Actif>".$this->wsdlBool($array['ModuleSuivi']??'')."</Actif>
                          <CodeSiteStock>".$array['SITE_STK']."</CodeSiteStock>
                        </ModuleBonSortie>
                      </Abonnements>
                      <Mode>C</Mode>
                      <Societe>".$array['SOCIETE']."</Societe>
                      <IdUser></IdUser>
                      <Nom>".$array['NOM']."</Nom>
                      <Prenom>".$array['PRENOM']."</Prenom>
                      <NomComplet>".$array['NOM']."</NomComplet>
                      <Fonction>".$array['FONCTION']."</Fonction>
                      <Hierarchique>".$array['SUPHIERARCHIQUE']."</Hierarchique>
                      <Tel>".$array['TEL_FIX']."</Tel>
                      <Mobile>".$array['TEL_MOB']."</Mobile>
                      <Fax>".$array['FAX']."</Fax>
                      <Mail>".$array['MAIL']."</Mail>
                      <SectImp>".$array['SI']."</SectImp>
                      <CodeComp>".$array['CDC']."</CodeComp>
                      <SCptAna>".$array['SCA']."</SCptAna>
                      <UnitOrganisationnelle>".$array['Uo']."</UnitOrganisationnelle>
                      <CtrEmetteur>".$array['Emtteur']."</CtrEmetteur>
                      <CtrLivraison>".$array['LIVRAISON']."</CtrLivraison>
                      <MotdePasse>".$array['MDP']."</MotdePasse>
                      <DelPref>".$array['MDP_SIGNA']."</DelPref>
                      <MailEnvoiBDC>".$this->wsdlBool($array['ENV_FOURN']??'')."</MailEnvoiBDC>
                      <UserSSO>".$this->wsdlBool($array['SingleOne']??'')."</UserSSO>
                      <UrlConnectSignataire>$UrlConnectSignataire</UrlConnectSignataire>
                      <UrlSuiviDemandeur>$UrlSuiviDemandeur</UrlSuiviDemandeur>
                    </UserIn>
        ";
        
        return new \Helpers\Webservice\Wsdl('Oxaproc_CreatMod_User', 'OXAPRC_CREATMODUSR', $envoi, false);
    }

    /**
     * @param array<mixed> $data
     */
    public function createDemModifUser(string $userId, array $data) :\SimpleXMLElement
    {
        return $this->editUtilisateur('M', $userId, $data);
    }

    /**
     * @param array<mixed> $data
     */
    public function updateUser(string $userId, array $data) :\SimpleXMLElement
    {
        return $this->editUtilisateur('U', $userId, $data);
    }

    /**
     * @param array<mixed> $data
     */
    public function updateDemUser(string $userId, array $data, string $demId) :\SimpleXMLElement
    {
        return $this->editUtilisateur('D', $userId, $data, $demId);
    }

    public function approbDemUser(
        string $demId,
        string $password,
        ?string $newUserCode
    ) :\SimpleXMLElement {
        return $this->signDem('S', $demId, $password, null, $newUserCode);
    }

    public function refusDemUser(
        string $demId,
        string $password,
        string $comment
    ) :\SimpleXMLElement {
        return $this->signDem('R', $demId, $password, $comment);
    }
    
    private function signDem(
        string $type/* S | R */,
        string $demId,
        string $password,
        ?string $comment = null,
        ?string $newUserCode = null
    ) :\SimpleXMLElement {
        $envoi = '<SigUsrIn LngUtilisation="'.$_SESSION['Session_Langue'].'">
            <Utilisateur>'.htmlspecialchars($_SESSION['Session_Login']).'</Utilisateur>
            <MotdePasse>'.htmlspecialchars($password).'</MotdePasse>
            <Mode>'.$type.'</Mode>
            <RefDemande>'.$demId.'</RefDemande>
            <Signataire>'.htmlspecialchars($_SESSION['Session_Login']).'</Signataire>
            <Comment>'.htmlspecialchars($comment ?? '').'</Comment>
            <SigParAdmin>'.$this->wsdlBool(Roles::isAdmin()).'</SigParAdmin>
            <CodUsrACreer>'.htmlspecialchars(strtoupper($newUserCode ?? '')).'</CodUsrACreer>
            <Url>'.htmlspecialchars(
                $this->genUrlIndexReset(
                    'signataire',
                    'SupHier',
                    $demId
                )
            ).'</Url>
        </SigUsrIn>';
        $xml = new \Helpers\Webservice\Wsdl('Oxaproc_CreatMod_User', 'OXAPRC_SIGNCREMODUSR', $envoi, false);
        return new \SimpleXMLElement($xml->responseData);
    }

    /**
     * Fonction appelant le WSDL de modification de demande de création de l'utilisateur
     * @param string $mode enum 'C' (Creation) | 'U' (Modification) | 'M' (Create a demand of modification )
     * @param array<mixed> $data
     */
    protected function getPayload(
        string $mode,
        string $userId,
        array $data,
        ?string $demId = null
    ) :string {
        $fileSignPath = null;
        $file = $data['fichier_signature'] ?? null;
        if ($file instanceof UploadedFileInterface && $file->getSize() != 0) {
            $path_info = pathinfo($file->getClientFilename());
            $new_name = Fichier::genUniqName('file', $path_info['extension'] ?? 'bin');
            $file->moveTo(Fichier::getDirImg() . $new_name);
            $fileSignPath = '%_images%'.$new_name;
        }
        
        // En mode création on envoie 1 mail à l'utilisateur afin qu'il accède au suivi et 1 mail au responsable afin qu'il consulte rapidement et directement la demande
        $superHier = (new ParamUtilisateur($this->pdo))->hasSupHierChoice() ?$data['SUPHIER'] :(new UO($this->pdo))->find($data['UO']??$data['CODE_UO'])['RESP_HIER'];
        if (!$superHier) {
            $superHier = (new UO($this->pdo))->find($data['UO']??$data['CODE_UO'])['RESP_HIER'];
        }
        
        $urlDemandeur = '';
        if ($mode == 'C') {
            $urlSupHier = $this->genUrlIndexReset(
                $superHier,
                'SupHier',
            );
            $urlDemandeur = $this->genUrlIndexReset(
                $data['EMAIL'],
                'Dem',
            );
        }

        // Approb required
        if ($mode == 'M') {
            $urlSupHier = $this->genUrlIndexReset(
                $superHier,
                'SupHier',
            );
        }
        
        $listDomFonc = $data['list_domfonc'] ?? [];
        if (is_string($listDomFonc)) {
            $listDomFonc = explode('/', $listDomFonc);
        }
        
        // Si l'utilisateur a sélectionné le mode de connexion lié à Active Directory
        $nomDom = $data['NOMDOM'] ?? '';
        
        // On utilise ici le mode D du wsdl => Modification de la demande par un administrateur
        return
            '<UserIn LngUtilisation="'.$_SESSION['Session_Langue'].'">'
            . (!empty($listDomFonc) ?
                '<ListDomFonctionnels>'
                . implode('', array_map(function ($value) {
                    return '<DomFonctionnel>'.htmlspecialchars($value).'</DomFonctionnel>';
                }, $listDomFonc))
                . '</ListDomFonctionnels>' :
                ''
            )

            . (!empty($nomDom) ?
                '<UserActiveDirectory>true</UserActiveDirectory>
                <DomaineActiveDirectory>'.htmlspecialchars($nomDom).'</DomaineActiveDirectory>' :
                '<UserActiveDirectory>false</UserActiveDirectory>
                <DomaineActiveDirectory></DomaineActiveDirectory>'
            )

            . '<LoginMessagerie>' . htmlspecialchars($data['USRMSG'] ?? '') . '</LoginMessagerie>
            <MdPMessagerie>' . htmlspecialchars($data['MDPMSG'] ?? '') . '</MdPMessagerie>'
            
            // Actual condition: if Roles::isAdmin() || $paravrac->hasEprocDemande()
            . (array_key_exists('AuthLigneLibre', $data) ?
                '<CdeEproc>'.$this->wsdlBool($data['AUTOCC']).'</CdeEproc>
                <SaisieLibreArt>'.$this->wsdlBool($data['AuthLigneManuelle']).'</SaisieLibreArt>
                <SaisieLibreGene>'.$this->wsdlBool($data['AuthLigneGenerique'] ?? false).'</SaisieLibreGene>
                <SaisieLibreSsfam>'.$this->wsdlBool($data['AuthLigneSFamille'] ?? false).'</SaisieLibreSsfam>
                <SaisieLibreRecherche>'.$this->wsdlBool($data['AuthLigneLibre']).'</SaisieLibreRecherche>
                
                <SeuilCde>'.htmlspecialchars($data['SeuilCde']).'</SeuilCde>' : ''
            )
            . '<Abonnements>
                <ModuleApprovisionnement>
                    <Actif>'.$this->wsdlBool($data['DEMAND']).'</Actif>
                    <MailSaisieBR>'.$this->wsdlBool($data['DEMAND'] && $data['DEMVALBR']).'</MailSaisieBR>
                    <MailDATraitee>'.$this->wsdlBool($data['DEMAND'] && $data['DEMREJDA']).'</MailDATraitee>
                    <MailApprobDA>'.$this->wsdlBool($data['DEMAND'] && $data['DEMREJDA']).'</MailApprobDA>
                    <MailComparAO>'.$this->wsdlBool($data['DEMAND'] && $data['EMACOMPAO']).'</MailComparAO>
                    <MailApprobCA>'.$this->wsdlBool($data['DEMAND'] && $data['DEMREJCA']).'</MailApprobCA>
                    <MailModifPlanningCA>'.$this->wsdlBool($data['DEMAND'] && $data['EMA_DEM_MODIF_PL_CDE']).'</MailModifPlanningCA>
                </ModuleApprovisionnement>
                <ModuleRecep>
                    <Actif>'.$this->wsdlBool($data['OXTRBRDAU']).'</Actif>
                </ModuleRecep>
                <ModuleApprobation>
                    <Actif>'.$this->wsdlBool(
                        in_array(
                            true,
                            ArrayHelper::filterByKey(
                                $data,
                                ['SIG_DA', 'SIG_CDE','SIG_BAP']
                            )
                        )
                    ).'</Actif>
                    <ApprobDA>'.$this->wsdlBool($data['SIG_DA']).'</ApprobDA>
                    <MailDA>'.$this->wsdlBool($data['MAILSIDA']).'</MailDA>
                    <ApprobCde>'.$this->wsdlBool($data['SIG_CDE']).'</ApprobCde>
                    <MailCde>'.$this->wsdlBool($data['MAILSICA']).'</MailCde>
                    <ApprobBAP>'.$this->wsdlBool($data['SIG_BAP']).'</ApprobBAP>
                    <MailBAP>'.$this->wsdlBool($data['MAILSIBA']).'</MailBAP>'
                    . ($fileSignPath !== null ?
                        '<FichierImageSignature>'.htmlspecialchars($fileSignPath).'</FichierImageSignature>' : ''
                    )
                    // (array_key_exists('new_pass_sign',$array) ?
                    //     '<MotdePasse>' . $array['new_pass_sign'] . '</MotdePasse>' : '').
                    . '<DelPref>' . htmlspecialchars($data['DEL_PREF']) . '</DelPref>
                </ModuleApprobation>
                <ModuleBonSortie>
                    <Actif>'.$this->wsdlBool($data['MAGASIN']).'</Actif>
                    <CodeSiteStock>'.($data['MAGASIN'] ? htmlspecialchars($data['site_stk']) : '').'</CodeSiteStock>
                </ModuleBonSortie>
            </Abonnements>
            <Mode>'.$mode.'</Mode>
            <Societe>' . htmlspecialchars($data['CODE_STE']) . '</Societe>
            <IdUser>' . htmlspecialchars($userId) . '</IdUser>
            <Nom>' . htmlspecialchars($data['NOM']) . '</Nom><Prenom></Prenom>'
            
            // if ($mode == 'C')
            //     $envoi.='<Nom>' . $array['nom'] . '</Nom><Prenom>' . $array['prenom'] . '</Prenom>';
            // else
            //     $envoi.='<Nom>' . $array['nom'] . '</Nom><Prenom></Prenom>';
                
            .'<NomComplet>' . htmlspecialchars($data['NOM']) . '</NomComplet>
            <Fonction>' . htmlspecialchars($data['FONCTION']) . '</Fonction>
            <Hierarchique>' . htmlspecialchars($data['SUPHIER'] ?? '') . '</Hierarchique>
            <Tel>' . htmlspecialchars($data['TEL']) . '</Tel>
            <Mobile>' . htmlspecialchars($data['GSM']) . '</Mobile>
            <Fax>' . htmlspecialchars($data['FAX']) . '</Fax>
            <Mail>' . htmlspecialchars($data['EMAIL']) . '</Mail>
            <SectImp>' . htmlspecialchars($data['SI']) . '</SectImp>
            <CodeComp>' . htmlspecialchars($data['CDC']) . '</CodeComp>
            <SCptAna>' . htmlspecialchars($data['SCA']) . '</SCptAna>'
            . (array_key_exists('CODE_UO', $data) ?
                '<UnitOrganisationnelle>' . htmlspecialchars($data['CODE_UO']) . '</UnitOrganisationnelle>' : ''
            )
            
            . '<CtrEmetteur>'  . htmlspecialchars($data['CTR_ADR']) . '</CtrEmetteur>
            <CtrLivraison>'  . htmlspecialchars($data['CTRLIV']) . '</CtrLivraison>
            <RefDemande>'  . htmlspecialchars($demId ?? ''). '</RefDemande>'
                
            // (array_key_exists('new_pass',$array)    ? '<MotdePasse>'   . $array['new_pass'] . '</MotdePasse>' : '').
            . '<MailEnvoiBDC>' . $this->wsdlBool($data['BCC_MBDC']) . '</MailEnvoiBDC>
            <UserSSO>' . $this->wsdlBool($data['isSingleSignOn'] ?? false) . '</UserSSO>
            <UrlConnectSignataire>'.htmlspecialchars($urlSupHier ?? '').'</UrlConnectSignataire>
            <UrlSuiviDemandeur>'.htmlspecialchars($urlDemandeur).'</UrlSuiviDemandeur>
            <DelegFavori>' . htmlspecialchars($data['DEL_PREF']) . '</DelegFavori>
        </UserIn>';
    }

    private function genUrlIndexReset(string $id, string $profil, string $demId = '') :string
    {
        return
            (Outils::isHttps() ? 'https' : 'http')
            . '://' . $_SERVER['HTTP_HOST']
            . $this->getRouter()->generateUri('Index.Index.indexReset')
            . '?' . http_build_query([
                'access' => 'mail',
                'id' => $id,
                'profil' => $profil,
                'refDemande' => $demId, // Magic will complite this part, MUST ALWAYS BE LAST
            ]);
    }

    /**
     * @param array<mixed> $data
     */
    public function editUtilisateur(
        string $mode,
        string $userId,
        array $data,
        ?string $demId = null
    ) :\SimpleXMLElement {
        return new \SimpleXMLElement(
            (new \Helpers\Webservice\Wsdl(
                'Oxaproc_CreatMod_User',
                'OXAPRC_CREATMODUSR',
                $this->getPayload($mode, $userId, $data, $demId),
                false
            ))->responseData
        );
    }
    
    public function changePassword(
        string $userId,
        string $oldPassword,
        string $password,
        bool $isSignat
    ) :\SimpleXMLElement {
        $envoi = '<MdPIn LngUtilisation="'.$_SESSION['Session_Langue'].'">
            <Utilisateur>'.htmlspecialchars($userId).'</Utilisateur>
            <NewMdP>'.htmlspecialchars($password).'</NewMdP>
            <Mode>'.($isSignat ? 'S' : 'L').'</Mode>
            <OldMdP>'.htmlspecialchars($oldPassword).'</OldMdP>
            <ModeOubliMdp>false</ModeOubliMdp>
        </MdPIn>';
        $xml = new \Helpers\Webservice\Wsdl('Oxaproc_InfoUser', 'OXAPRC_MODMDP_XML', $envoi, false);
        return new \SimpleXMLElement($xml->responseData);
    }

    public function unblock(string $userId) :\SimpleXMLElement
    {
        $envoi = '<DebloqUtilIn LngUtilisation="'.$_SESSION['Session_Langue'].'">
            <Utilisateur>'.htmlspecialchars($_SESSION['Session_Login']).'</Utilisateur>
            <UtilisateurADebloq>'.htmlspecialchars($userId).'</UtilisateurADebloq>
        </DebloqUtilIn>';
        $xml = new \Helpers\Webservice\Wsdl('', 'OXAPRC_UTIL_DEBLOQ', $envoi, false);
        return new \SimpleXMLElement($xml->responseData);
    }
    
    /**
     * @param mixed $value
     */
    public function wsdlBool($value) :string
    {
        if ($value) {
            return 'true';
        }
        return 'false';
    }
}
