<?php

namespace Modules\Evaluation\Controller;

use GuzzleHttp\Psr7\Response;
use Helpers\Ariane\ArianeSub;
use Helpers\Fichier\Fichier;
use Helpers\Trad\ITrad;
use Helpers\Trad\Trad;
use Modules\Evaluation\Repository\Import\ImportInfo;
use Modules\Evaluation\Service\CampaignService;
use PhpOffice\PhpSpreadsheet\IOFactory;
use Skeleton\Controller\Controller;
use Helpers\Session\Enums\MenuTopEnum;
use Helpers\Session\Session;

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

    /**
     * init
     * gestion des droits
     *
     * @return void
     */
    public function init()
    {
    }

    /**
     * ImportindexAction
     *
     * @return string
     */
    public function ratersImportIndexAction(): string
    {
        $trad = $this->getTranslationService();
        $campaignId = $this->request->getAttribute('id');
        $campaign = (new CampaignService($this->pdo, $this->getTranslationService()))
            ->campaignDetail(
                $campaignId,
                $this->router,
                $this->droits
            );

        ArianeSub::generate(
            1,
            0,
            $trad->t('Import évaluateurs'),
            $this->router->generateUri('Evaluation.ImportEvaluateur.supplierImportIndex', ['id' => $campaignId]),
            1
        );

        return $this->renderer->render('@Evaluation/Campaign/detail', [
            'menuActive' => Session::verifySessionTypeMenuTop(MenuTopEnum::S2C) ? 'Consultations' : 'Evaluations',
            'menuLeft' => 'ratings',
            'campaign' => $campaign,
            'tab' => 'Import/Raters/import',
            'id' => $campaignId,
            'droits' => $this->droits,
        ]);
    }

    /**
     * raterImportAction
     *
     * @return  string|Response
     */
    public function ratersImportAction()
    {
        $campaignId = $this->request->getAttribute('id');
        $trad = $this->getTranslationService();
        $file = $this->request->getUploadedFiles();

        return $this->_processImport($campaignId, $trad, $file, 'raters');
    }

    public function ratersImportSummaryAction(): string
    {
        $post = $this->request->getParsedBody();
        $trad = $this->getTranslationService();
        $campaignId = $this->request->getAttribute('id');

        $data = $this->_processDataSummary($post, $trad, $campaignId);

        return $this->renderer->render('@Evaluation/Campaign/detail', [
            'menuActive' => Session::verifySessionTypeMenuTop(MenuTopEnum::S2C) ? 'Consultations' : 'Evaluations',
            'menuLeft' => 'ratings',
            'tab' => 'Import/Raters/summary',
            'missingRaters' => $data['missingRaters'],
            'alreadyRegisteredRaters' => $data['alreadyRegisteredRaters'],
            'message' => $data['message'],
            'id' => $campaignId,
            'campaign' => $data['campaign'],
            'droits' => $this->droits,
        ]);
    }

    /**
     * groupsImportIndexAction
     *
     * @return string
     */
    public function groupsImportIndexAction(): string
    {
        $trad = $this->getTranslationService();

        $campaignId = $this->request->getAttribute('id');
        $campaign = (new CampaignService($this->pdo, $this->getTranslationService()))
            ->campaignDetail(
                $campaignId,
                $this->router,
                $this->droits
            );

        ArianeSub::generate(
            1,
            0,
            $trad->t('Import évaluateurs'),
            $this->router->generateUri('Evaluation.ImportEvaluateur.supplierImportIndex', ['id' => $campaignId]),
            1
        );

        return $this->renderer->render('@Evaluation/Campaign/detail', [
            'menuActive' => Session::verifySessionTypeMenuTop(MenuTopEnum::S2C) ? 'Consultations' : 'Evaluations',
            'menuLeft' => 'ratings',
            'campaign' => $campaign,
            'tab' => 'Import/Groups/import',
            'id' => $campaignId,
            'droits' => $this->droits,
        ]);
    }

    /**
     * groupsImportAction
     *
     * @return  string|Response
     */
    public function groupsImportAction()
    {
        $campaignId = $this->request->getAttribute('id');
        $trad = $this->getTranslationService();
        $file = $this->request->getUploadedFiles();

        return $this->_processImport($campaignId, $trad, $file, 'groups');
    }
    
    /**
     * groupsImportSummaryAction
     *
     * @return string
     */
    public function groupsImportSummaryAction(): string
    {
        $post = $this->request->getParsedBody();
        $trad = $this->getTranslationService();
        $campaignId = $this->request->getAttribute('id');

        $data = $this->_processDataSummary($post, $trad, $campaignId);

        return $this->renderer->render('@Evaluation/Campaign/detail', [
            'menuActive' => Session::verifySessionTypeMenuTop(MenuTopEnum::S2C) ? 'Consultations' : 'Evaluations',
            'menuLeft' => 'ratings',
            'tab' => 'Import/Groups/summary',
            'missingRaters' => $data['missingRaters'],
            'missingGroups' => $data['missingGroups'],
            'alreadyRegisteredRaters' => $data['alreadyRegisteredRaters'],
            'message' => $data['message'],
            'id' => $campaignId,
            'campaign' => $data['campaign'],
            'droits' => $this->droits,
        ]);
    }

    /**
     * suppliersImportIndexAction
     *
     * @return string
     */
    public function suppliersImportIndexAction(): string
    {
        $trad = $this->getTranslationService();

        $campaignId = $this->request->getAttribute('id');
        $campaign = (new CampaignService($this->pdo, $this->getTranslationService()))
            ->campaignDetail(
                $campaignId,
                $this->router,
                $this->droits
            );

        ArianeSub::generate(
            1,
            0,
            $trad->t('Import évaluateurs'),
            $this->router->generateUri('Evaluation.ImportEvaluateur.suppliersImportIndex', ['id' => $campaignId]),
            1
        );

        return $this->renderer->render('@Evaluation/Campaign/detail', [
            'menuActive' => Session::verifySessionTypeMenuTop(MenuTopEnum::S2C) ? 'Consultations' : 'Evaluations',
            'menuLeft' => 'ratings',
            'campaign' => $campaign,
            'tab' => 'Import/Suppliers/import',
            'id' => $campaignId,
            'droits' => $this->droits,
        ]);
    }

    /**
     * suppliersImportAction
     *
     * @return  string|Response
     */
    public function suppliersImportAction()
    {
        $campaignId = $this->request->getAttribute('id');
        $trad = $this->getTranslationService();
        $file = $this->request->getUploadedFiles();

        return $this->_processImport($campaignId, $trad, $file, 'suppliers');
    }
    
    /**
     * suppliersImportSummaryAction
     *
     * @return string
     */
    public function suppliersImportSummaryAction(): string
    {
        $post = $this->request->getParsedBody();
        $trad = $this->getTranslationService();
        $campaignId = $this->request->getAttribute('id');

        $data = $this->_processDataSummary($post, $trad, $campaignId);

        return $this->renderer->render('@Evaluation/Campaign/detail', [
            'menuActive' => Session::verifySessionTypeMenuTop(MenuTopEnum::S2C) ? 'Consultations' : 'Evaluations',
            'menuLeft' => 'ratings',
            'tab' => 'Import/Suppliers/summary',
            'missingRaters' => $data['missingRaters'],
            'missingSuppliers' => $data['missingSuppliers'],
            'alreadyRegisteredRaters' => $data['alreadyRegisteredRaters'],
            'message' => $data['message'],
            'id' => $campaignId,
            'campaign' => $data['campaign'],
            'droits' => $this->droits,
        ]);
    }
    
    /**
     * _processDataSummary
     *
     * @param  array<mixed> $post
     * @param  ITrad $trad
     * @param  int $campaignId
     * @return array<mixed>
     */
    private function _processDataSummary(array $post, ITrad $trad, int $campaignId): array
    {
        $campaign = (new CampaignService($this->pdo, $this->getTranslationService()))
            ->campaignDetail(
                $campaignId,
                $this->router,
                $this->droits
            );

        $alreadyRegisteredRaters = $post['alreadyRegisteredRaters'] ?? [];
        $missingRaters = $post['missingRaters'] ?? [];
        $missingGroups = $post['missingGroups'] ?? [];
        $missingSuppliers = $post['missingSuppliers'] ?? [];
        $totalImportedRaters = $post['totalImportedRaters'];

        if ($totalImportedRaters > 0) {
            $message = Trad::strBuild($trad->t('Évaluateurs importés depuis le fichier : @1@'), $totalImportedRaters);
        } else {
            $message = $trad->t('Aucun évaluateur n\'a été importé.');
        }

        ArianeSub::generate(1, 0, $trad->t('Récapitulatif import'), $this->router->generateUri('Evaluation.ImportEvaluateur.raterImportSummary', ['id' => $campaignId]), 1);

        return [
            'missingRaters' => $missingRaters,
            'missingGroups' => $missingGroups,
            'missingSuppliers' => $missingSuppliers,
            'alreadyRegisteredRaters' => $alreadyRegisteredRaters,
            'message' => $message,
            'id' => $campaignId,
            'campaign' => $campaign,
        ];
    }

    /**
     * _processImport
     *
     * @param  int $campaignId
     * @param  ITrad $trad
     * @param  array<mixed> $file
     * @param  string $type
     * @return string|Response
     */
    private function _processImport(int $campaignId, ITrad $trad, array $file, string $type)
    {
        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 ?? '', ['xls', '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"];

            $arrayImport = $this->_getArrayImport($type, $newName);

            // on vérifie les noteurs reçus et on retourne le compte de noteurs OK, la liste des noteurs qui n'existent pas et la liste des noteurs qui étaient déjà enregistrés dans la campagne
            $import = (new ImportInfo($this->pdo, $this->pdoStorage))->importRaters($campaignId, $arrayImport, $type);
            $missingRaters = $import['missingRaters'] ?? [];
            $missingGroups = $import['missingGroups'] ?? [];
            $missingSuppliers = $import['missingSuppliers'] ?? [];
            $alreadyRegisteredRaters = $import['alreadyRegisteredRaters'] ?? [];
            $totalImportedRaters = $import['count'] ?? [];

            // import par lot de 500 noteurs (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.ImportEvaluateur.' . $type . 'ImportSummary', ['id' => $campaignId]),
                'postGestion' => [
                    'missingRaters' => $missingRaters,
                    'missingGroups' => $missingGroups,
                    'missingSuppliers' => $missingSuppliers,
                    'alreadyRegisteredRaters' => $alreadyRegisteredRaters,
                    'totalImportedRaters' => $totalImportedRaters,
                ],
            ]));
        } else {
            return $this->renderer->render('@popup-erreur/ErreurCreation', [
                'ErreurValid' => $validator->getError(),
                'desactiveRow' => true,
            ]);
        }
    }
    
    /**
     * _getArrayImport
     *
     * @param  string $type
     * @param  string $fileName
     * @return array<mixed>
     */
    private function _getArrayImport(string $type, string $fileName): array
    {
        // on récupère les valeurs des colonnes qui nous intéressent (ici la première uniquement)
        $spreadsheet = IOFactory::load($fileName);
        $sheet = $spreadsheet->getSheet(0);
        $totalRows = $sheet->getHighestRow();
        
        $arrayImport = [];
        $temporaryKey = '';
        if ($type === 'raters') {
            foreach ($sheet->getRowIterator(1, $totalRows) as $row) {
                foreach ($row->getCellIterator('A', 'A') as $cell) {
                    $value = $cell->getCalculatedValue();
                    $arrayImport[] = $value;
                }
            }
        } else {
            foreach ($sheet->getRowIterator(1, $totalRows) as $row) {
                $i = 1;
                foreach ($row->getCellIterator('A', 'B') as $cell) {
                    $value = $cell->getCalculatedValue();
                    if ($i % 2 == 1) {
                        $temporaryKey = $value;
                    } else {
                        $arrayImport[$temporaryKey][] = $value;
                    }
                    $i++;
                }
            }
        }

        return $arrayImport;
    }
}
