<?php

namespace Modules\Evaluation\Controller;

use Entity\Model\EvalModelCategory;
use GuzzleHttp\Psr7\Response;
use Helpers\Ariane\Ariane;
use Helpers\ExportTo\Outils;
use Helpers\Fichier\Fichier;
use Helpers\Filter\FiltreAvance\Generator;
use Helpers\Outil\Roles;
use Helpers\Pagination\PaginatorGestion;
use Helpers\Trad\Trad;
use Helpers\Validator\Validator;
use Modules\Evaluation\MenuContextuel\CategoryMenuContextuel;
use Modules\Evaluation\Repository\Category;
use PhpOffice\PhpSpreadsheet\IOFactory;
use Skeleton\Controller\Controller;
use Helpers\Session\Enums\MenuTopEnum;
use Helpers\Session\Session;

class CategoryController extends Controller
{
    /**
     * @var array<mixed>
     */
    protected array $droits = [];

    /**
     * init
     * gestion des droits
     *
     * @return void
     */
    public function init()
    {
        $droits = [
            'HA_MQUESCM' => Roles::droitsUtilisateur($this->pdo, 'HA_MQUESCM', $_SESSION["Session_Login"]), // Droit de création et modification des modèles et les catégories de modèles
            'HA_CEVAVIS' => Roles::droitsUtilisateur($this->pdo, 'HA_CEVAVIS', $_SESSION["Session_Login"]), // Droit de visu des campagnes
            'HA_CEVALCM' => Roles::droitsUtilisateur($this->pdo, 'HA_CEVALCM', $_SESSION["Session_Login"]), // Droit de création et modification des campagnes
            'HA_CEVASUP' => Roles::droitsUtilisateur($this->pdo, 'HA_CEVASUP', $_SESSION["Session_Login"]), // Droit de suppression des campagnes d'évaluation
            'HA_BIBQTCM' => Roles::droitsUtilisateur($this->pdo, 'HA_BIBQTCM', $_SESSION["Session_Login"]), // Droit de création et modification de questionnaire
        ];

        $this->droits = $droits;
    }
    // protected $categoryRepository = new Category($this->pdo, $this->pdoStorage);

    public function indexAction() : string
    {
        $post = $this->request->getParsedBody();
        $categoryRepository = new Category($this->pdo, $this->pdoStorage);

        $paginator = new PaginatorGestion();
        $paginator->generate('', 'LIB_GRILLE', 'ASC');

        $categoryList = $categoryRepository->categoryList($post);
        $menuContextuel   = new CategoryMenuContextuel($this->pdo, $this->router, $this->getTranslationService());

        foreach ($categoryList as &$cat) {
            $cat['menuContextuel'] = $menuContextuel->generate($cat['ID_GRILLE'], $cat['LIB_GRILLE']);
        }

        $pagingInfo = PaginatorGestion::getInfoPagination();

        // $droits['HA_EVALCAT'] = Roles::getDroit($this->pdo, 'HA_EVALCAT', 'PARAMGEN');

        $trad = $this->getTranslationService();

        $deleteMessage = $trad->t('Voulez-vous supprimer la catégorie "@1@" ?');

        $menuActive = 'Evaluations';

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

        $advancedFilter = new Generator($post);
        $advancedFilter->setFiltre('ID_GRILLE', 'text', $trad->t('Code'));
        $advancedFilter->setFiltre('LIB_GRILLE', 'text', $trad->t('Libellé'));

        return $this->renderer->render('@Evaluation/Categorie/index', [
            'menuActive'        => Session::verifySessionTypeMenuTop(MenuTopEnum::S2C) ? 'Consultations' : $menuActive,
            'categoryList'      => $categoryList,
            'filtreAvance'      => $advancedFilter->getFiltres(),
            'initFiltreAvance'  => $advancedFilter->getInit(),
            'post'              => $post,
            'infoPagination'    => $pagingInfo,
            'titre'             => $trad->t('Catégories de modèles et campagnes'),
            'droits'            => $this->droits,
        ]);
    }
    
    /**
     * creationCategorieAction
     *
     * @return  string|Response
     */
    public function creationCategorieAction()
    {
        $post = $this->request->getParsedBody();
        $trad = $this->getTranslationService();

        if (\is_array($post) && \count($post) > 0) {
            $categoryRepository = new Category($this->pdo, $this->pdoStorage);
            // Faire un find avec la valeur de ton post si il n'existe pas c'est ok sinon souci
            $categoryList = $categoryRepository->categoryList();

            foreach ($categoryList as $category) {
                if (\strtoupper($post['CODE']) == \strtoupper($category['ID_GRILLE'])) {
                    return new Response(200, [], (string) \json_encode([
                        'statut' => 'E',
                        'erreur' => $trad->t('Le code saisi est déjà utilisé.')
                    ]));
                }
            }

            $validator = $this->createValidator();

            $validator->isStringSansEspace("Code", $post['CODE'], 1, 10);
            $validator->isStringAvecEspace("Libellé", $post['LIBELLE'], 1, 30);

            if (!$validator->isValid()) {
                return new Response(200, [], (string) \json_encode([
                    'statut' => 'E',
                    'erreur' => $validator->getError()
                ]));
            } else {
                $insert = [
                    ':ID_GRILLE'      => $post['CODE'],
                    ':LIB_GRILLE'     => $post['LIBELLE'],
                ];
                $categoryRepository->categoryNew($insert);

                return new Response(200, [], (string) \json_encode([
                    'statut'    => 'O',
                    'path'      => $this->router->generateUri('Evaluation.Category.index')
                ]));
            }
        } else {
            $categoryRepository = new Category($this->pdo, $this->pdoStorage);

            Ariane::generate(1, $trad->t('Nouvelle catégorie'));

            return $this->renderer->render('@Evaluation/Categorie/creationCategorie', [
                'menuLeft'          => 'Evaluation.Category.index',
                'menuActive'        => Session::verifySessionTypeMenuTop(MenuTopEnum::S2C) ? 'Consultations' : 'Evaluations',
                'post'              => $post,
                'title'             => $trad->t('Catégories de modèles et campagnes'),
                'droits'            => $this->droits, //['HA_EVALCAT' => true] //$droits
            ]);
        }
    }
    
    /**
     * modificationCategorieAction
     *
     * @return  string|Response
     */
    public function modificationCategorieAction()
    {
        $post = $this->request->getParsedBody();
        $idCat = $this->request->getAttribute('idCat');

        $categoryRepo = new Category($this->pdo, $this->pdoStorage);
        $category = $categoryRepo->categoryDetail($idCat);

        if (\is_array($post) && \count($post) > 0) {
            $validator = $this->createValidator();

            $validator->isStringSansEspace("Code", $post['CODE'], 1, 10);
            $validator->isStringAvecEspace("Libellé", $post['LIBELLE'], 1, 30);

            if (!$validator->isValid()) {
                $post['erreurValid'] = true;
                return $this->renderer->render('@popup-erreur/ErreurCreation', [
                    'ErreurValid' => $validator->getError(),
                ]);
            } else {
                $update = [
                    ':ID_GRILLE'      => $post['CODE'],
                    ':LIB_GRILLE'     => $post['LIBELLE'],
                ];

                $categoryRepo->categoryUpdate($update);
            }

            return new Response(443, [], (string) \json_encode([
                'path'      => $this->router->generateUri('Evaluation.Category.index')
            ]));
        } else {
            $trad = $this->getTranslationService();

            Ariane::generate(1, $trad->t('Modification catégorie'));

            return $this->renderer->render('@Evaluation/Categorie/modificationCategorie', [
                'menuLeft'          => 'evaluations.Category.index',
                'menuActive'        => Session::verifySessionTypeMenuTop(MenuTopEnum::S2C) ? 'Consultations' : 'Evaluations',
                'category'          => $category,
                'post'              => $post,
                'title'             => $trad->t('Modification catégorie'),
                'droits'            => $this->droits, //['HA_EVALCAT' => true] //$droits
            ]);
        }
    }
    
    /**
     * suppressionCategorieAction
     *
     * @return Response
     */
    public function suppressionCategorieAction()
    {
        $idCat = $this->request->getAttribute('idCat');
        $categoryRepo = new Category($this->pdo, $this->pdoStorage);

        $delete = [
            ':ID_GRILLE'      => $idCat,
        ];

        $categoryRepo->categoryDelete($delete);

        return new Response();
    }

    public function exportAction() : string
    {
        $categoryRepository  = new Category($this->pdo, $this->pdoStorage);
        $categoryList = $categoryRepository->categoryList();
        $categoryModel = new EvalModelCategory($this->pdo);

        // Récupération des formats des champs
        $fieldList = $categoryModel->getArchitecture($this->getTranslationService());

        // On génère l'entête du fichier d'export
        $tab = [];
        foreach ($fieldList as $key => $field) {
            $tab[\substr($categoryModel->table, 0, 9) . '.' . $key] = $field['nomChamp'];
        }

        Outils::gestionEmailAsync2(
            "export_liste_categories",
            $categoryList,
            $this->JWTKEY,
            $this->router,
            $this->getTranslationService(),
            $tab
        );
        return 'ok';
    }

    public function importIndexAction() : string
    {
        $trad = $this->getTranslationService();

        Ariane::generate(1, $trad->t('Import catégorie'));

        return $this->renderer->render('@Evaluation/Categorie/import/import', [
            'menuActive'        => Session::verifySessionTypeMenuTop(MenuTopEnum::S2C) ? 'Consultations' : 'Evaluations',
            'menuLeft'          => 'category',
            'title'             => $trad->t('Gestion catégories'),
            ]);
    }
    
    /**
     * importAction
     *
     * @return string|Response
     */
    public function importAction()
    {
        $trad = $this->getTranslationService();
        $file = $this->request->getUploadedFiles();

        if ($file) {
            $filename = $file['importFile']->getClientFilename();
            $fileSize = $file['importFile']->getSize();
        } else {
            $filename = null;
            $fileSize = 0;
        }

        $validator = $this->createValidator();
        $validator->fileCheck($trad->t('Fichier d\'import'), $filename ?? '', ['xsl', 'xlsx', 'csv'], '', $fileSize);

        if ($validator->isValid()) {
            // on enregistre le fichier d'import dans les fichiers temporaires
            $newPath = Fichier::UploadDocAtt($filename);
            $file['importFile']->moveTo($newPath["racine"] . $newPath["new_name"]);
            $newName = $newPath["racine"] . $newPath["new_name"];

            // on récupère les valeurs des colonnes qui nous intéressent
            $spreadsheet = IOFactory::load($newName);
            $sheet = $spreadsheet->getSheet(0);
            $totalRows = $sheet->getHighestRow();

            $arrayImport = [];
            $temporaryValue = '';
            $temporaryKey = '';
            foreach ($sheet->getRowIterator(2, $totalRows) as $row) {
                $i = 1;
                foreach ($row->getCellIterator('A', 'B') as $cell) {
                    $value = $cell->getCalculatedValue();
                    if ($i % 2 == 1) {
                        $arrayImport[$value] = $temporaryValue;
                        $temporaryKey = $value;
                    } else {
                        $arrayImport[$temporaryKey] = $value;
                    }
                    $i++;
                }
            }

            // Les doublons de codes catégorie sont automatiquement supprimés car l'index du tableau correspond au code catégorie ==> seule la dernière valeur est sauvegardée en cas de codes répétés

            // on vérifie les codes catégorie reçus et on retourne le compte de catégories OK et la liste des catégories qui étaient déjà enregistrées
            $categoryRepo = new Category($this->pdo, $this->pdoStorage);
            $import = $categoryRepo->categoryImport($arrayImport);
            $existingCategories = $import['existingCategories'] ?? [];
            $totalImportedCategories = $import['count'];
            
            // import par lot de 500 fournisseurs (append dans un fichier pour les logs)
            // faire un helper pour l'insert table temp
            // gérer l'entity dans le helper

            return new Response(443, [], (string) \json_encode([
                'statut' => 'O',
                'path' => $this->router->generateUri('Evaluation.Category.importSummary'),
                'postGestion' => [
                    'existingCategories'         => $existingCategories,
                    'totalImportedCategories'    => $totalImportedCategories,
                ],
            ]));
        } else {
            return $this->renderer->render('@popup-erreur/ErreurCreation', [
                'ErreurValid' => $validator->getError(),
                'desactiveRow' => true,
            ]);
        }
    }
    
    public function importSummaryAction() : string
    {
        $post = $this->request->getParsedBody();
        $trad = $this->getTranslationService();

        $existingCategories = $post['existingCategories'];
        $totalImportedCategories = $post['totalImportedCategories'];
        
        if ($totalImportedCategories > 0) {
            $message = Trad::strBuild($trad->t('Nombre de catégories importées depuis le fichier : @1@'), $totalImportedCategories);
        } else {
            $message = $trad->t('Aucune catégorie n\'a été importée.');
        }

        Ariane::generate(1, $trad->t('Récapitulatif import'));

        return $this->renderer->render('@Evaluation/Categorie/import/summary', [
            'menuActive'                    => Session::verifySessionTypeMenuTop(MenuTopEnum::S2C) ? 'Consultations' : 'Evaluations',
            'menuLeft'                      => 'categorie',
            'existingCategories'            => $existingCategories ?? [],
            'message'                       => $message,
            ]);
    }
}
