<?php

namespace Modules\Administration\Service;

use Entity\Model\Alias\ParamUtilisateur;
use Entity\Model\Centre;
use Entity\Model\Codecomp;
use Entity\Model\DomaineFonctionnel;
use Entity\Model\FoncUsr;
use Entity\Model\Hastutil;
use Entity\Model\ParamDico;
use Entity\Model\PrOxaCat;
use Entity\Model\Sectimpu;
use Entity\Model\Societe;
use Entity\Model\Sscptana;
use Entity\Model\SSiteSto;
use Entity\Model\UO;
use Helpers\Form\AbsFormService;
use Helpers\Outil\Roles;
use Helpers\Trad\ITrad;
use Modules\GlobalApplication\Repository\LicenceOxalys;
use Psr\Container\ContainerInterface;

class FormUtilisateur extends AbsFormService
{
    private \PDO $pdo;

    public function __construct(\PDO $pdo)
    {
        $this->pdo = $pdo;
    }

    /**
     * Label is required by zoom validator and such
     * @todo codify validator error and move this to client side
     * @param array<\stdClass> $form
     * @return array<\stdClass>
     */
    public function getView(ITrad $trad, array $form)
    {
        foreach ($form as &$input) {
            $input->label = $this->getInputLabel($trad, $input->name);
        }
        return $form;
    }

    /**
     * Label is required by zoom validator and such
     * @todo move somewhere else
     */
    protected function getInputLabel(ITrad $trad, string $inputName) :string
    {
        switch ($inputName) {
            case 'CODE_STE':
                return $trad->t('Société');
            case 'FONCTION':
                return $trad->t('Fonction');
            case 'SUPHIER':
                return $trad->t('Supérieur hiérarchique');
            case 'CODE_UO':
                return $trad->t('Unité Organisationnelle');
            case 'SI':
                return $trad->t('Section d’imputation');
            case 'CDC':
                return $trad->t('Code complémentaire');
            case 'SCA':
                return $trad->t('Sous-compte d’analyse');
            case 'CTR_ADR':
                return $trad->t('Centre émetteur');
            case 'CTRLIV':
                return $trad->t('Centre de livraison');
            case 'list_domfonc':
                return $trad->t('Domaines fonctionnels de l’utilisateur');
            case 'DEL_PREF':
                return $trad->t('Délégataire préféré');
            case 'site_stk':
                return $trad->t('Site de stock');
            case 'fichier_signature':
                return $trad->t('Image de signature');
            default:
        }
        return '';
    }
    
    /**
     * @return array<string|int,\stdClass>
     */
    protected function getBaseForm()
    {
        $paravrac = new ParamUtilisateur($this->pdo);
        $hasControlFonction = $paravrac->getFlag('PARAMGEN', 'CONTROLE_FONCTION_UTILISATEUR');
        return array_column(array_merge(
            [
                (object) [
                    'name' => 'CODE_STE',
                    'type' => 'ZOOM',
                    'entity' => Societe::class,
                    'validator' => ['mandatory' => true],
                ],
                (object) [
                    'name' => 'NOM',
                    'type' => 'TEXT',
                    'validator' => ['max' => '60', 'mandatory' => true],
                ],
                (object) [
                    'name' => 'FONCTION',
                    'type' => ($hasControlFonction ? 'ZOOM' : 'TEXT'),
                    'entity' => FoncUsr::class,
                    'validator' => ['mandatory' => $hasControlFonction],
                ],
            ],
            ($paravrac->hasSupHierChoice() ? [
                (object) [
                    'name' => 'SUPHIER',
                    'type' => 'ZOOM',
                    'entity' => Hastutil::class,
                    'validator' => ['mandatory' => true],
                    'zoom_filter' => ['USRSUPHIE' => 'T'],
                    'zoom_dependency' => ['CODE_STE'],
                ],
            ] : []),
            ($paravrac->hasUOChoice() ? [
                (object) [
                    'name' => 'CODE_UO',
                    'type' => 'ZOOM',
                    'entity' => UO::class,
                    'validator' => ['mandatory' => true],
                    'zoom_dependency' => ['CODE_STE'],
                ],
            ] : []),
            [
                $this->simpleText('TEL', 16),
                $this->simpleText('GSM', 16),
                $this->simpleText('FAX', 16),
                $this->simpleText('EMAIL', 50),// TODO : add vali email ?
                (object) [
                    'name' => 'SI',
                    'type' => 'ZOOM',
                    'entity' => Sectimpu::class,
                    'zoom_dependency' => ['CODE_STE'],
                    'validator' => ['mandatory' => false],
                ],
                (object) [
                    'name' => 'CDC',
                    'type' => 'ZOOM',
                    'entity' => Codecomp::class,
                    'zoom_dependency' => ['CODE_STE'],
                    'validator' => ['mandatory' => false],
                ],
                (object) [
                    'name' => 'SCA',
                    'type' => 'ZOOM',
                    'entity' => Sscptana::class,
                    'zoom_dependency' => ['CODE_STE'],
                    'validator' => ['mandatory' => false],
                ],
                (object) [
                    'name' => 'CTR_ADR',
                    'type' => 'ZOOM',
                    'entity' => Centre::class,
                    'zoom_filter' => ['filter_EMISSION' => 'T'],
                    'zoom_path' => 'Ajax.liste.centreEmetteur',
                    'zoom_dependency' => ['CODE_STE'],
                    'validator' => ['mandatory' => true],
                ],
                (object) [
                    'name' => 'CTRLIV',
                    'type' => 'ZOOM',
                    'entity' => Centre::class,
                    'zoom_filter' => ['filter_LIVRAISON' => 'T'],
                    'zoom_path' => 'Ajax.liste.centreLivraison',
                    'zoom_dependency' => ['CODE_STE'],
                    'validator' => ['mandatory' => true],
                ],
            ],
            //_____________________________________
            // Messagerie
            ( $paravrac->hasSmtpChoice() ? [
                (object) [
                    'name' => 'USRMSG',
                    'type' => 'TEXT',
                    'validator' => ['max' => 100],
                ],
                (object) [
                    'name' => 'MDPMSG',
                    'type' => 'PASSWORD',
                    'validator' => ['max' => 30],
                ],
            ]: []),
            [
                //_____________________________________
                // Domaines fonctionnels
                (object) [
                    'name' => 'list_domfonc',
                    'type' => 'ZOOM_MULTI',
                    'entity' => DomaineFonctionnel::class,
                ],
            ],
            //_____________________________________
            // Mode de connexion

            // Note : isSingleSignOn and NOMDOM cannot be both selected
            ($paravrac->getFlag('PARAMGEN', 'CNX_SSO') ? [
                $this->switch('isSingleSignOn'),
            ] : []),
            ($paravrac->getFlag('PARAMGEN', 'CNX_ACTIVE_DIRECTORY') ? [
            (object) [
                'name' => 'NOMDOM', // Active directory
                'type' => 'SELECT',
                'choices' => function (ITrad $trad) {
                    return
                        (new ParamDico($this->pdo))->listLdapDomaine()
                        + ['' => $trad->t('Aucun')];
                },
                'choices_value' => function () {
                    return array_merge(
                        array_keys((new ParamDico($this->pdo))->listLdapDomaine()),
                        ['']
                    );
                }
            ],
            ] : []),
            //_____________________________________
            // Copie cache
            [
                $this->switch('BCC_MBDC') //'mail_cache_ca',
            ],
            //_________________________
            // Module eproc
            (Roles::isAdmin() || $paravrac->hasEprocDemande() ? array_merge(
                [
                    $this->switch('AUTOCC'),
                    $this->switch('AuthLigneManuelle'),
                ],
                ((new PrOxaCat($this->pdo))->isPublicationGeneric() ? [
                    $this->switch('AuthLigneGenerique'),
                    $this->switch('AuthLigneSFamille'),
                ] : []),
                [
                    $this->switch('AuthLigneLibre'),
                    (object) [
                        'name' => 'SeuilCde',
                        'type' => 'DEVISE',
                        'devise' => 'EUR',
                    ],
                ]
            ) : []),
            [
                $this->switch('DEMAND'), // demandeur
                $this->switch('DEMVALBR'), // email_br_val
                $this->switch('DEMREJDA'), // email_da_rej
                $this->switch('EMADATRAI'), // email_da_traitee
                $this->switch('EMACOMPAO'), // email_comp_ao
                $this->switch('DEMREJCA'), // email_ca_rej
                $this->switch('EMA_DEM_MODIF_PL_CDE'), // email_modif_planning_ca
                //_________________________
                // Module signature
                $this->switch('SIG_DA'),
                $this->switch('MAILSIDA'),
                $this->switch('SIG_CDE'),
                $this->switch('MAILSICA'),
                $this->switch('SIG_BAP'),
                $this->switch('MAILSIBA'), // mail_sig_bap
            ],
            (roles::droitsUtilisateur($this->pdo, 'HA_MODIMSI') ? [
                (object) [
                    'name' => 'fichier_signature',
                    'type' => 'FILE',
                    //'validator' => ['mandatory' => true]
                ],
            ] : []),
            [
                (object) [
                    'name' => 'DEL_PREF',
                    'type' => 'ZOOM',
                    'entity' => Hastutil::class, // TODO : class Delegataire with it's own validator
                    'zoom_path' => 'Ajax.liste.delegatairePref',
                    'zoom_dependency' => ['CODE_STE'], // TODO : handle context of another user
                ],
            ],
            //_________________________
            // Module suivi des bons de sortie
            (((new LicenceOxalys($this->pdo))->stockActive()) ? [
                $this->switch('MAGASIN'),
                (object) [
                    'name' => 'site_stk',
                    'type' => 'ZOOM',
                    'entity' => SSiteSto::class,
                    'zoom_dependency' => ['CODE_STE'],
                ],
            ] : []),
            //______________________________
            // Module Reception
            [
                $this->switch('OXTRBRDAU'),
            ]
        ), null, 'name');
    }

    

    // TODO : merge with src\Modules\Index\views\creationCompte\formulaireCreation.twig
    // public function getFormAutodeclare()
    // {
    //     $base = $this->getBaseForm();
    //     unset($base['NOM']);
    //     return $base + array_column([
    //         (object) [
    //             'name' => 'prenom',
    //             'type' => 'TEXT',
    //             'validator' => ['max' => '60', 'mandatory' => true],
    //         ],
    //         (object) [
    //             'name' => 'nom',
    //             'type' => 'TEXT',
    //             'validator' => ['max' => '60', 'mandatory' => true],
    //         ],

    //

    //         ...
    //     ], null, 'name');
    // }

    /**
     * Form for user to edit his own profile
     * @return array<string|int,\stdClass>
     */
    public function getFormProfileEdit()
    {
        $form = $this->getBaseForm();

        // Disable 'Commande eproc'
        foreach ([
            'AUTOCC', 'SeuilCde',
            'AuthLigneManuelle', 'AuthLigneGenerique',
            'AuthLigneSFamille', 'AuthLigneLibre',
        ] as $inputName) {
            if (!isset($form[ $inputName ])) {
                continue;
            }
            $form[ $inputName ]->disabled = true;
        }

        // "Mark" with approb required
        foreach ([
            // 'PRENOM', // Only for form autodeclare
            'CODE_STE', 'NOM', 'SUPHIER', 'CODE_UO', 'list_domfonc',
            'AUTOCC', 'MAGASIN', 'DEMAND',
            'SIG_DA', 'SIG_CDE', 'SIG_BAP',
            'OXTRBRDAU'
        ] as $inputName) {
            if (!isset($form[ $inputName ])) {
                continue;
            }
            $form[ $inputName ]->approbRequired = true;
        }
        
        // Remove option "Mode connexion"
        // unset($form['isSingleSignOn']);
        // unset($form['NOMDOM']);

        return $form;
    }

    /**
     * @return array<string|int,\stdClass>
     */
    public function getFormApprob()
    {
        $form = $this->getBaseForm();
        return $form;
    }

    /**
     * @return array<string|int,\stdClass>
     */
    public function getFormEdit()
    {
        $form = $this->getBaseForm();
        return $form;
    }

    /**
     * @return array<\stdClass>
     */
    public function getFormPassword(ContainerInterface $container) :array
    {
        return array_column([
            (object) [
                'name' => 'pass',
                'type' => 'PASSWORD',
                'validator' => ['mandatory' => true]
            ],
            (object) [
                'name' => 'new_pass',
                'type' => 'PASSWORD',
                'validator' => [
                    'mandatory' => true,
                    'max' => (new ParamDico($this->pdo))->getPasswordMaxLength($container)
                ],
            ],
        ], null, 'name');
    }
}
