<?php

namespace Modules\Reception\Controller;

use Entity\Model\Hastutil;
use GuzzleHttp\Psr7\Response;
use Helpers\Ariane\Ariane;
use Helpers\Ariane\ArianeSub;
use Helpers\Filter\FiltreAvance\Generator;
use Helpers\Outil\Roles;
use Helpers\Outil\Sql;
use Helpers\Pagination\PaginatorGestion;
use Helpers\Trad\Trad;
use Modules\Ajax\Repository\Listes;
use Modules\Reception\Outil\GestionBonRecepDatatable;
use Modules\Reception\Repository\CreationBR;
use Modules\Reception\Repository\GestionBR;
use Modules\Reception\Service\CreationBRService;
use Modules\Reception\WebService\BR;
use SimpleXMLElement;
use Skeleton\Controller\Controller;

class GestionBRController extends Controller
{
    /**
     * @var mixed $repository
     */
    protected $repository;

    /** @var array<mixed> $droits */
    protected array $droits;

    const PREFIX_CS = 'CS_EXTENSION_BR_RECEP_';

    public function init(): void
    {
        $this->repository = new GestionBR($this->pdo);

        $hastUtil = new Hastutil($this->pdo);

        $droits = [
            'CHOIX_UO'      => Sql::paravrac($this->pdo, 'OXAPROC', 'CHOIX_UO') == 'O',
            'SOURCE_SI'     => sql::paravrac($this->pdo, 'OXAPROC', 'SOURCE_SI') == 'O',
            'OX_SUITTUO'    => Roles::droitsUtilisateur($this->pdo, 'OX_SUITTUO', $_SESSION["Session_Login"]),
            'HA_DA_TTDM'    => Roles::droitsUtilisateur($this->pdo, 'HA_DA_TTDM', $_SESSION["Session_Login"]),
            'HA_DA_TTCE'    => Roles::droitsUtilisateur($this->pdo, 'HA_DA_TTCE', $_SESSION["Session_Login"]),
            'HA_DA_TTCT'    => Roles::droitsUtilisateur($this->pdo, 'HA_DA_TTCT', $_SESSION["Session_Login"]),
            'HASTUTIL'      => $hastUtil->find($_SESSION['Session_Login'], ['ACHETEUR', 'OXTRBRDAU', 'NIV_CONF'], [], $this->pdo::FETCH_ASSOC),
            'SUIVI_EXCLURE_LIENDOC_UO_HASTUTIL' => sql::paravrac($this->pdo, 'OXAPROC', 'SUIVI_EXCLURE_LIENDOC_UO_HASTUTIL') == 'O',
            'CODE_SI_LOCK'  => '',
            'SISECTOR'      => Roles::droit($this->pdo, 'SISECTOR', 'PARAMSTE'),
            'CDCSECTO'      => Roles::droit($this->pdo, 'CDCSECTO', 'PARAMSTE'),
            'SCASECTO'      => Roles::droit($this->pdo, 'SCASECTO', 'PARAMSTE'),
            'HA_BR_PX'      => Roles::droitsUtilisateur($this->pdo, 'HA_BR_PX'),
            'HA_CA_SPM'     => Roles::droitsUtilisateur($this->pdo, 'HA_CA_SPM'),
        ];
        $this->droits = $droits;
    }

    public function indexAction(): string
    {
        $post = $this->request->getParsedBody();
        $type = $this->request->getAttribute('type') ?? 'reception';

        $trad = $this->getTranslationService();

        $listReceptionAttendues = [
            '' => $trad->t('Toutes'),
            'today' => $trad->t('Aujourd\'hui'),
            'week' => $trad->t('Cette semaine'),
            'month' => $trad->t('Ce mois'),
            'nextMonth' => $trad->t('Mois prochain'),
        ];

        $paramsForView = [];
        $nbItems = 0;
        $societeUser = $_SESSION['Session_SocUsr'];
        $gestionBR = new GestionBR($this->pdo);
        $filtreAvance = new Generator($post);

        $sectimpu = new \Entity\Model\Sectimpu($this->pdo);
        $Codecomp = new \Entity\Model\Codecomp($this->pdo);
        $Sscptana = new \Entity\Model\Sscptana($this->pdo);
        $Directio = new \Entity\Model\Directio($this->pdo);
        $Natana   = new \Entity\Model\Natana($this->pdo);
        $Centrana = new \Entity\Model\Centrana($this->pdo);


        switch ($type) {
            default:
            case "reception":
                /* PARAMETRAGE DES AXES D'IMPUTATION */
                $steSi = '';
                $steCdc = '';
                $steSca = '';

                if (!$post) {
                    $post['filter_RECEPTION'] = 'today';
                    $post['filter_CODE_STE'] = $_SESSION["Session_SocUsrProfil"];
                }
                $listeSiDirection = [
                    'si'        => $trad->t('SI'),
                    'direction' => $trad->t('Direction')
                ];
                $listeCdc         = [
                    'cdc'   => $trad->t('CDC'),
                    'na'    => $trad->t('Nature analytique')
                ];
                $listeSca         = [
                    'sca'   => $trad->t('SCA'),
                    'ca'    => $trad->t("Centre d'analyse"),
                ];

                $userMonoSociete = !$_SESSION['Session_UsrMultiSoc'] && !$_SESSION['Session_UsrPluriSoc'];
                if ($userMonoSociete) {
                    // Si l'utilisateur est monon-société, on initialise le filtre société avec sa société paramétrée.
                    $post['filter_CODE_STE'] = $_SESSION['Session_SocUsrProfil'];
                }
                $existPostSociete = isset($post['filter_CODE_STE']) && $post['filter_CODE_STE'] != '';

                if ($this->droits['SISECTOR']) {
                    if (!$existPostSociete) {
                        $post['CODE_SI'] = $post['filter_CODE_DIR'] = $post['ID_CG'] = '';
                    }
                    $this->droits['CODE_SI_LOCK'] = !$existPostSociete && !$userMonoSociete;
                    $steSi = $post['filter_CODE_STE'] ?? '';
                }

                if ($this->droits['CDCSECTO']) {
                    if (!$existPostSociete) {
                        $post['filter_CODE_CDC'] = $post['CODNAN'] = '';
                    }
                    $this->droits['CODE_CDC_LOCK'] = !$existPostSociete && !$userMonoSociete;
                    $steCdc = $post['filter_CODE_STE'] ?? '';
                }

                if ($this->droits['SCASECTO']) {
                    if (!$existPostSociete) {
                        $post['filter_CODE_SCA'] = $post['CODE_CTA'] = '';
                    }
                    $this->droits['CODE_SCA_LOCK'] = !$existPostSociete && !$userMonoSociete;
                    $steSca = $post['filter_CODE_STE'] ?? '';
                }

                if (isset($post['CODE_SI']) && $post['CODE_SI'] != '') {
                    $sectimpu = $sectimpu->find(['CODE_SI' => $post['CODE_SI'], 'CODE_STE' => $steSi]);
                    $post['CODE_SI_LIBELLE'] = $sectimpu['LIBELLE'] . ' (' . $post['CODE_SI'] . ')';
                }

                if (isset($post['filter_CODE_DIR']) && $post['filter_CODE_DIR'] != '') {
                    $Directio = $Directio->find(['CODE_DIR' => $post['filter_CODE_DIR'], 'CODE_STE' => $steSi]);
                    $post['CODE_DIR_LIBELLE'] = $Directio['LIBELLE'] . ' (' . $post['filter_CODE_DIR'] . ')';
                }

                if (isset($post['CODECOMP']) && $post['CODECOMP'] != '') {
                    $Codecomp = $Codecomp->find(['CODE_CDC' => $post['CODECOMP'], 'CODE_STE' => $steCdc]);
                    $post['CODE_CDC_LIBELLE'] = $Codecomp['LIBELLE'] . ' (' . $post['CODECOMP'] . ')';
                }

                if (isset($post['filter_SSCPTEANA']) && $post['filter_SSCPTEANA'] != '') {
                    $Sscptana = $Sscptana->find(['CODE_SCA' => $post['CODE_SCA'], 'CODE_STE' => $steSca]);
                    $post['CODE_SCA_LIBELLE'] = $Sscptana['LIBELLE'] . ' (' . $post['filter_SSCPTEANA'] . ')';
                }

                if (isset($post['CODNAN']) && $post['CODNAN'] != '') {
                    $codNan = $Natana->find(['CODNAN' => $post['CODNAN'], 'CODE_STE' => $steCdc]);
                    $post['CODNAN_LIBELLE'] = $codNan['LIBELLE'] . ' (' . $post['CODNAN'] . ')';
                }

                if (isset($post['CODE_CTA']) && $post['CODE_CTA'] != '') {
                    $CA = $Centrana->find(['CODE_CTA' => $post['CODE_CTA'], 'CODE_STE' => $steSca]);
                    $post['CODE_CTA_LIBELLE'] = $CA['LIBELLE'] . ' (' . $post['CODE_CTA'] . ')';
                }

                if (($post['selectOptionSietDirection'] ?? '') === 'si') {
                    $_SESSION['bulleFiltre']['CODE_SI']['titre']         = $trad->t('SI');
                    $_SESSION['bulleFiltre']['CODE_SI']['value']         = $post['text_CODE_SI'] ?? '';
                } elseif (($post['selectOptionSietDirection'] ?? '') === 'direction') {
                    $_SESSION['bulleFiltre']['filter_CODE_DIR']['titre']        = $trad->t('Direction');
                    $_SESSION['bulleFiltre']['filter_CODE_DIR']['value']        = $post['text_filter_CODE_DIR'] ?? '';
                }

                if (($post['SELECT_CDC_NA'] ?? '') === 'cdc') {
                    $_SESSION['bulleFiltre']['CODECOMP']['titre']        = $trad->t('Code complémentaire');
                    $_SESSION['bulleFiltre']['CODECOMP']['value']        = $post['CODECOMP'] ?? '';
                } elseif (($post['SELECT_CDC_NA'] ?? '') === 'na') {
                    $_SESSION['bulleFiltre']['CODNAN']['titre']          = $trad->t('Nature analytique');
                    $_SESSION['bulleFiltre']['CODNAN']['value']          = $post['text_CODNAN'] ?? '';
                }

                if (($post['selectOptionSCAetCA'] ?? '') === 'sca') {
                    $_SESSION['bulleFiltre']['filter_SSCPTEANA']['titre']       = $trad->t('Sous-compte d\'analyse');
                    $_SESSION['bulleFiltre']['filter_SSCPTEANA']['value']       = $post['text_filter_SSCPTEANA'] ?? '';
                } elseif (($post['selectOptionSCAetCA'] ?? '') === 'ca') {
                    $_SESSION['bulleFiltre']['CODE_CTA']['titre']        = $trad->t('Centre d\'analyse');
                    $_SESSION['bulleFiltre']['CODE_CTA']['value']        = $post['CODE_CTA'] ?? '';
                }

                $paginator = new PaginatorGestion();
                $paginator->generate(0, 'NO_CDE');
                $commandes = $gestionBR->getListeCommande($post);
                $nbItems = PaginatorGestion::getNbrArticle();
                $infoPagination = PaginatorGestion::getInfoPagination();
                $liste = new Listes($this->pdo);
                $arrayTemp = $liste->typeAchat([]);
                $listeTypeAchat = [];

                foreach ($arrayTemp as $row) {
                    $listeTypeAchat[$row['TYP_ACH']] = $row['LIB_TAC'];
                }

                $listeDocument = [];
                $listeTypeDocument = $liste->listeTypeDoc([]);
                foreach ($listeTypeDocument as $document) {
                    $listeDocument[$document['TYPE']] = $document['LIBELLE'];
                }

                $filtreAvance->setFiltre('CA_LIGNE.DES_SOMM', 'text', $trad->t('Dont la désignation'));
                $filtreAvance->setFiltre('CA_ENTET.ACH', 'text', $trad->t('Acheteur de la commande'));
                $filtreAvance->setFiltre('CA_ENTET.DTE_VALID', 'date', $trad->t('Date de validation commande'));
                $filtreAvance->setFiltre('CA_ENTET.COD_TAC', 'liste', $trad->t("Type d’achat"), '', 'Ajax.liste.typeAchat', 'TypeAchat');
                $filtreAvance->setFiltre('CA_ENTET.TYP_DOC', 'liste', $trad->t('Type de document'), '', 'Ajax.liste.typeDoc', 'TypeDoc');
                $filtreAvance->setFiltre('CA_ENTET.OBJET_CA', 'text', $trad->t('Objet de la commande'));
                $filtreAvance->setFiltre('CA_ENTET.NO_CDE', 'text', $trad->t('N° de commande'));

                $paramsForView = [
                    'items' => $commandes,
                    'listReceptionAttendues' => $listReceptionAttendues,
                    'centreEmetteur' => $_SESSION['Session_CodeCtrEmetteur'] ?? '',
                    'centreLivraison' => $_SESSION['Session_CodeCtrLivraison'] ?? '',
                    'listeTypeDeDocument' => $listeDocument,
                    'listeTypeAchat' => $listeTypeAchat,
                    'filtreAvance' => $filtreAvance->getFiltres(),
                    'initFiltreAvance' => $filtreAvance->getInit(),
                    'infoPagination' => $infoPagination,
                    'listeSiDirection' => $listeSiDirection,
                    'listeCdcNa' => $listeCdc,
                    'listeScaCa' => $listeSca,
                    'userMonoSociete' => $userMonoSociete,
                ];
                break;

            case "retour":
                $paginator = new PaginatorGestion();
                $paginator->generate(0, 'NUM_BR');
                if (!$post) {
                    $post['filter_egal_CODE_STE'] = $_SESSION['Session_SocUsr'] ?? '';
                }
                $bons = $gestionBR->getListeBR($post);


                $nbItems = PaginatorGestion::getNbrArticle();
                $infoPagination = PaginatorGestion::getInfoPagination();
                $paramsForView = [
                    'items' => $bons,
                    'infoPagination' => $infoPagination,
                ];
                break;
        }

        Ariane::init();
        ArianeSub::init();


        Ariane::generate(0, $trad->t('Vos critères de recherche'), $post, $nbItems);
        ArianeSub::generate(
            0,
            0,
            $trad->t('Créer un bon de réception'),
            $this->router->generateUri('Reception.GestionBR.index', ['type' => 'reception']),
            ($type == 'reception') ? 1 : 0
        );
        ArianeSub::generate(
            0,
            1,
            $trad->t('Créer un bon de retour'),
            $this->router->generateUri('Reception.GestionBR.index', ['type' => 'retour']),
            ($type == 'retour') ? 1 : 0
        );

        $defaultParamsViews = [
            'menuActive' => 'eproc',
            'menuLeft' => 'Eprocurement',
            'type' => $type,
            'userSociete' => $societeUser,
            'post' => $post,
            'droits' => $this->droits,
        ];

        return $this->renderer->render('@Reception/GestionBR/index', array_merge($defaultParamsViews, $paramsForView));
    }

    public function ajaxDetailEnteteAction(): string
    {
        $numBR = $this->request->getAttribute('idBR');

        $gestionBR_REPO = new GestionBR($this->pdo);
        $ligneBR = $gestionBR_REPO->listeLigneBR($numBR);

        return $this->renderer->render('@Reception/GestionBR/detailBR', [
            'listeLigneBR' => $ligneBR,
        ]);
    }

    /**
     * @return mixed
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    public function listAction()
    {
        $post = $this->request->getParsedBody();

        // TODO : filter
        // demandeur
        // obj de la commande


        // TODO : date 00/00/0000
        // TODO : deploy line
        // TODO : action button

        // TODO : bug add filter date_*
        // TODO : bug add filter type*

        // TODO : sort out labelCreateur

        $trad = $this->getTranslationService();

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


        $table = new GestionBonRecepDatatable(
            new GestionBR($this->pdo),
            new Generator($post)
        );

        $userCode = $_SESSION['Session_Login'];
        $user = (new Hastutil($this->pdo))->find($userCode);

        return $this->renderer->render('@Reception/GestionBR/bonrecep_list', [
            'baseUrl' => $this->contenaire->get('baseUrl'),
            'user' => [
                'code' => $userCode,
                'label' => $user['NOM'],
                'droits' => $this->droits,
            ],

            'table' => $table,
            'filtreAvance' => $table->getAdvFilter()->getFiltres(),
            'initFiltreAvance' => $table->getAdvFilter()->getInit(),

            'post' => $post,

            'menuActive' => 'eproc',
            'menuLeft' => 'Eprocurement',
        ]);
    }

    /**
     * viewPreviousReturnVouchersAction
     *
     * @return Response
     */
    public function viewPreviousReturnVouchersAction(): Response
    {
        $br = $this->request->getAttribute('br');
        $gestionBR = new GestionBR($this->pdo);
        $trad = $this->getTranslationService();

        // on récupère la liste des bons de retour enregistrés sur la commande du BR initial
        $previousReturnVouchers = $gestionBR->getPreviousBR($br);

        return new Response(200, [], $this->renderer->render('@Reception/Creation/Popup/receptionList', [
            'titrePopup'    => $trad->t('Liste des bons de retour'),
            'list'          => $previousReturnVouchers,
        ]));
    }

    /**
     * valDevalSuppAction
     *
     * @return Response
     */
    public function valDevalSuppAction(
        BR $brWsdl,
        CreationBR $creationBR
    ): Response {
        $br = $this->request->getAttribute('br');
        $action = $this->request->getAttribute('action');
        $trad = $this->getTranslationService();

        $wsdl = $brWsdl->valDevalSuppBr($action, $br);
        $returnWsdl = new SimpleXMLElement($wsdl->responseData);

        $message = '';
        switch ($action) {
            case 'V':
                $message = Trad::strBuild($trad->t("Le bon n°@1@ est validé."), $br);
                break;
            case 'D':
                $message = Trad::strBuild($trad->t("Le bon n°@1@ est dévalidé."), $br);
                break;
            case 'S':
                $message = Trad::strBuild($trad->t("Le bon n°@1@ est supprimé."), $br);
                break;
        }

        if ((string)$returnWsdl->Statut === 'E') {
            return new Response(443, [], $this->renderer->render('@popup-erreur/erreurAlerteEtAvertissement', [
                'params' => [
                    'alerte' => $returnWsdl->MsgErreur ?? '',
                ],
                'statut' => 'E',
            ]));
        }

        if ($action === 'V') {
            if (!$creationBR->isOrderSettled($br) && $this->droits['HA_CA_SPM']) {
                $order = (new CreationBRService($this->pdo, $trad))->getOrderFromBr($br);
                return new Response(400, [], $this->renderer->render('@Reception/Creation/Popup/settleOrderConfirmation', [
                    'message' => $message
                        . '</br></br>'
                        . Trad::strBuild(
                            $trad->t('La commande @1@ n\'est pas soldée physiquement par cette réception. Souhaitez-vous accéder à l\'écran de gestion du solde manuel du reliquat de la commande ?'),
                            $order
                        ),
                    'continuePath' => $this->router->generateUri(
                        'Commande.solderCommande.physiquement',
                        ['idCommande' => $order]
                    ),
                    'returnPath'   => $this->router->generateUri('Suivi.SuiviRecep.liste'),
                    'titrePopup'   => $trad->t('Avertissement')
                ]));
            }
        }

        return new Response(400, [], $this->renderer->render('@popup-erreur/information', [
            'uriRetour' => $this->router->generateUri('Suivi.SuiviRecep.liste'),
            'message'   => $message,
        ]));
    }
}
