<?php

namespace Modules\Consultation\Controller;

use Helpers\Fichier\Fichier;
use Helpers\Phpspreadsheet\SpreadsheetHelper;
use Helpers\QueryBuilder\RawSqlExpr;
use Helpers\Session\Enums\MenuTopEnum;
use Helpers\Session\Session;
use Modules\Consultation\Repository\ConsultationLigneRepo;
use Skeleton\Controller\Controller;
use Helpers\Trad\Trad;
use Modules\Consultation\Repository\GestionConsultation;
use Modules\Consultation\Repository\AoEvent;
use Helpers\Ariane\ArianeSub;
use Entity\Model\Articles;
use GuzzleHttp\Psr7\Response;
use Helpers\Validator\Validator;
use Entity\Model\AoLigne;
use Entity\Model\DaLigne;
use Helpers\ChampsSupplementaire\ChampSupp;
use Helpers\Outil\Sql;
use Entity\Model\AoEntet;
use Entity\Model\AoPlann;
use Helpers\Outil\Date;
use Helpers\Pagination\PaginatorGestion;
use Entity\Model\AoQstTh;
use Entity\Model\ConvArt;
use Modules\GlobalApplication\Repository\Societe;
use Helpers\Parametres\Constante;

class ConsultationArticlesImportController extends Controller
{
    public function formImportAction() : string
    {
        $idAO = $this->request->getAttribute('idAO');
        
        $gestionConsu = new GestionConsultation($this->pdo);
        $consultation = $gestionConsu->getInfoAo($idAO);
        
        $aoEvent = new AoEvent($this->pdo);
        $AOEventCreat = $aoEvent->getNameCreate($idAO);

        return $this->renderer->render('@Consultation/Articles/formImport', [
            'menuActive'        =>  Session::verifySessionTypeMenuTop(MenuTopEnum::P2P)? 'eproc':'Consultations',
            'menuLeft'          => 'gestionAO',

            'idAO'              => $idAO,
            
            'consultation'      => $consultation,
            'AOEventCreat'      => $AOEventCreat,

            'formatQTE' => Constante::formatQTE,
            'formatPU' => Constante::formatPU,
            'formatMontant' => Constante::formatMontant,
            'dateFormat' => $_SESSION['DATE_FORMAT'],
        ]);
    }
    
    public function importAction() :Response
    {
        $idAO = $this->request->getAttribute('idAO');
        $post = $this->request->getParsedBody();

        $aoEntet = (new AoEntet($this->pdo))->find($idAO);
        if (empty($aoEntet)) {
            return new Response(404, [], 'Invalid AO');
        }

        $trad = $this->getTranslationService();
        $file = $this->request->getUploadedFiles()['importimport'] ?? null;

        if (empty($file)) {
            return new Response(400, [], Trad::strBuild(
                $trad->t('Le fichier @1@ est obligatoire.'),
                $trad->t('Excel')
            ));
        }
        $filepath = $file->getClientFilename();

        $validator = $this->createValidator();
        $validator->fileCheck(
            $trad->t('Excel'),
            $filepath,
            ['xls', 'xlsx'],
            '',
            $file->getSize()
        );

        if (!$validator->isValid()) {
            return new Response(400, [], $validator->getError());
        }

        //____________________
        // Load data from request
        
        $newPath = Fichier::UploadDocAtt($filepath);
        $file->moveTo($filepath = $newPath["racine"].$newPath["new_name"]);

        
        $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($filepath);
        $sheet = $spreadsheet->getSheet(0);

        $listAoLigne = [];
        foreach (range(1, $sheet->getHighestRow()) as $i) {
            $listAoLigne[] = [
                'NO_AO' => $idAO,
                'CODE_ART' =>  (string) $sheet->getCell([1,$i])->getValue(),
                'SSFAMILLE' => (string) $sheet->getCell([2,$i])->getValue(),
                'DES' =>       (string) $sheet->getCell([3,$i])->getValue(),
                'DCOMP' =>     (string) $sheet->getCell([4,$i])->getValue(), // TODO : MEMO
                'COD_FAB' =>   (string) $sheet->getCell([5,$i])->getValue(),
                'COD_GAM' =>   (string) $sheet->getCell([6,$i])->getValue(),
                'REF_FAB' =>   (string) $sheet->getCell([7,$i])->getValue(),
                'QTE' =>       (string) $sheet->getCell([8,$i])->getValue(),
                'UNITE' =>     (string) $sheet->getCell([9,$i])->getValue(),
                'PRIX_REF' =>  (string) $sheet->getCell([10,$i])->getValue(),
                'BUDGET' =>    (string) $sheet->getCell([11,$i])->getValue(),
                'DELAI' =>     SpreadsheetHelper::parseDate(
                    $sheet->getCell([12,$i])->getValue()
                ),
            ];
        }

        $mapArticle = array_column(
            (new Articles($this->pdo))->findAll([
                'CODE_ART' => array_unique(array_column($listAoLigne, 'CODE_ART')),
            ]),
            null,
            'CODE_ART'
        );

        //____________________
        // Validation

        $listError = [];
        $listWarning = [];
        foreach ($listAoLigne as $index => $aoLigne) {
            $validator = $this->createValidator();
            $validator->zoom('Articles', $aoLigne['CODE_ART'], $trad->t('Code article'), $this->pdo, true);
            $validator->isStringAvecEspace($trad->t('Désignation'), $aoLigne['DES'], 1, 60);
            $validator->isStringAvecEspace($trad->t('Désignation compl.'), $aoLigne['DCOMP'], 0, 3000);
            $validator->zoom('Fabricant', $aoLigne['COD_FAB'], $trad->t('Fabricant'), $this->pdo, true);
            $validator->zoom('Gamme', $aoLigne['COD_GAM'], $trad->t('Gamme'), $this->pdo, true);
            $validator->zoom('SousFamille', $aoLigne['SSFAMILLE'], $trad->t('Sous famille'), $this->pdo, false);
            $validator->isStringAvecEspace($trad->t('Réf. fabricant'), $aoLigne['REF_FAB'], 0, 30);
            $validator->isFloat($trad->t('Quantité'), $aoLigne['QTE'], Constante::formatQTE);
            $validator->uniteZoom(
                $aoLigne['UNITE'],
                $trad->t('Unité'),
                $this->pdo,
                false,
                ['ssFamille' => $aoLigne['SSFAMILLE']]
            );
            $validator->isFloat($trad->t('Prix référence'), $aoLigne['PRIX_REF'], constante::formatPU);
            $validator->isFloat($trad->t('Budget'), $aoLigne['BUDGET'], Constante::formatMontant);
            //$validator->isDate($aoLigne['DELAI'], '', '', true, $trad->t('Délai'));
            if (! $validator->isValid()) {
                $listError[] = [
                    'prefixe' => $trad->t('Ligne '.($index+1)).$trad->colon(),
                    'error' => $validator->getError(),
                ];
            }

            if (!empty($aoLigne['CODE_ART'])) {
                $article = $mapArticle[ $aoLigne['CODE_ART'] ] ?? [];
                //$article = (new Articles($this->pdo))->find($aoLigne['CODE_ART']);
                if ($article['SSFAM'] != $aoLigne['SSFAMILLE']) {
                    $listWarning[] = [
                        'prefixe' => $trad->t('Ligne '.($index+1)).$trad->colon(),
                        'error' => Trad::strBuild(
                            $trad->t('Le code sous-famille @1@ n’est pas cohérent avec le code article, celui-ci sera remplacé.'),
                            $aoLigne['SSFAMILLE']
                        ),
                    ];
                    $aoLigne['SSFAMILLE'] = $article['SSFAM'] ?? '';
                }
            }
        }

        if (! empty($listError)) {
            return new Response(400, [], implode('<br><br>', array_map(function ($item) {
                return $item['prefixe'] . $item['error'];
            }, $listError)));
        }

        if (!empty($listWarning) && !isset($post['confirm'])) {
            return $this->createJsonResponse(
                [
                    'type' => 'confirm',
                    'popupHtml' => $this->renderer->render('@popup-erreur/simpleWarning', [
                        'content' => implode('<br><br>', array_map(function ($item) {
                            return $item['prefixe'] . $item['error'];
                        }, $listWarning)),
                    ]),
                ],
                400
            );
        }

        //____________________
        // Update BD

        $this->pdo->beginTransaction();

        $nextId = (new AoLigne($this->pdo))->getNextId($aoEntet['NO_AO']);

        foreach ($listAoLigne as $index => &$aoLigne) {
            $aoLigne['NO_PO'] = $nextId + $index;
            $aoLigne['NM_DCOMP'] = Sql::updateMemo($this->pdo, '', $aoLigne['DCOMP']);
            unset($aoLigne['DCOMP']);
        }

        (new ConsultationLigneRepo($this->pdo))
            ->multiInsert('AO_LIGNE', $listAoLigne);

        $this->pdo->commit();

        //____________________

        return new Response(200);
    }
}
