<?php

namespace Modules\Stock\Controller\Parametrage;

use Entity\Model\Paravrac;
use Entity\Model\ParTxco;
use Entity\Model\Sparamet;
use Exception;
use GuzzleHttp\Psr7\Response;
use Helpers\Outil\Sql;
use Modules\Stock\Enum\CodeParametreVracEnum;
use Modules\Stock\Enum\TypeParametreVracEnum;
use Modules\Stock\Service\ListManagerService;
use Modules\Stock\Service\ParametrageService;
use Modules\Stock\Service\VaParametresVracDataTransformer;
use Modules\Stock\Trait\Controller\StockContollerTrait;
use Modules\Stock\Validator\ParavracValidator;
use Skeleton\Controller\Controller;

class VracController extends Controller
{
    use StockContollerTrait;

    /**
     * @throws Exception
     */
    public function diversFormAction(): string
    {
        $trad = $this->getTranslationService();
        $listManagerService = new ListManagerService($trad);
        $listeChoixFournisseurs = $listManagerService->getChoixFournisseursList();
        $listeCodeparvsDivers = $listManagerService->getCodeParametreDiversList();
        $listeChoixArticlesEnModeSimplifies = $listManagerService->getChoixArticlesEnModeSimplifiesList();
        $parametres = (new ParametrageService($this->pdo))->getParametres('PARAMSTO', $listeCodeparvsDivers);

        return $this->renderer->render('@Stock/Parametrage/Vrac/divers', [
            'menuActive' => 'Stock',
            'parametres' => $parametres,
            'current_route' => $this->router->getNameRoute(),
            'listeChoixFournisseurs' => $listeChoixFournisseurs,
            'menuLeft' => 'Stock.Vrac.numerotation',
            'parametreDivers' => (new ParTxco($this->pdo))->find(['CLE' => 1]),
            'parametreStock' => (new Sparamet($this->pdo))->find(['CLE' => 1]),
            'listeChoixArticlesEnModeSimplifies' => $listeChoixArticlesEnModeSimplifies,
        ]);
    }

    /**
     * @throws Exception
     */
    public function diversAction(): Response
    {
        $parTxco = new ParTxco($this->pdo);
        $sparamet = new Sparamet($this->pdo);
        $trad = $this->getTranslationService();
        $post = $this->request->getParsedBody();
        $validator = new ParavracValidator($this->pdo, $trad);

        $parametres = $post['PARAVRAC'];
        $parametreDivers = $post['PAR_TXCO'];
        $parametreStock = $post['SPARAMET'];

        $validator
            ->validateTauxMarge($parametreDivers)
            ->validateChxfourpr($parametres[CodeParametreVracEnum::CHXFOURPR->name])
            ->validateReapproModeArtSimplifies($parametres[CodeParametreVracEnum::REAPPRO_MODE_ARTSIMPLIFIES->name]);

        if ($validator->isValid()) {
            $paravrac = new Paravrac($this->pdo);

            $this->pdo->beginTransaction();

            foreach ($parametres as $parametre) {
                match ($parametre['CODEPARV']) {
                    CodeParametreVracEnum::ST_STONEGINTERDIT_SANSRESA->name => $parametre['LIB01PARV'] = Sql::toBool($parametre['LIB01PARV']) ? 'N': 'O',
                    CodeParametreVracEnum::INV_MASQUER_QTE_THEO->name, CodeParametreVracEnum::OXAPROC_MODE_REAPPRO_ACTIF->name, CodeParametreVracEnum::MONOCORMVT->name, CodeParametreVracEnum::BT_MULTISOCIETE->name, CodeParametreVracEnum::ST_VISIPRIXACTIF->name, CodeParametreVracEnum::ST_STONEGINTERDIT->name => $parametre['LIB01PARV'] =  Sql::convertBooleenCheckboxForWsdl($parametre['LIB01PARV']),
                    default => null
                };

                $paravrac->updateEntity($parametre);
            }
            $parTxco->processAndMerge($parametreDivers);
            $sparamet->processAndMerge($parametreStock);

            $this->pdo->commit();

            return $this->createJsonResponse([
                'statut' => 'OK',
                'redirectRoute' => $this->router->generateUri('Stock.Vrac.diversForm')
            ]);
        } else {
            return $this->createBloquantJsonErrorResponse([], $validator->getError());
        }
    }

    public function imputationsFormAction(): string
    {
        $trad = $this->getTranslationService();
        $listManager = new ListManagerService($trad);
        $listeCodeparvsBo = $listManager->getCodeParametreBoList();
        $listeCodeparvsVa = $listManager->getCodeParametreVaList();
        $parametrageService = new ParametrageService($this->pdo);
        $listeChoixDateValiditeImputation = $listManager->getChoixDateValiditeList();

        $parametres = [
            'BO' => $parametrageService->getParametres(TypeParametreVracEnum::PARASTOGEN->name, $listeCodeparvsBo),
            'VA' => $parametrageService->getParametres(TypeParametreVracEnum::PARASTOGEN->name, $listeCodeparvsVa),
            'BT' => $parametrageService->getParametres(TypeParametreVracEnum::PARASTOGEN->name, [CodeParametreVracEnum::BLANCINTERDIT_TIERS->name => 'N']),
        ];

        $parametres['VA'] = VaParametresVracDataTransformer::output($parametres['VA']);

        return $this->renderer->render('@Stock/Parametrage/Vrac/imputations_form', [
            'menuActive' => 'Stock',
            'parametres' => $parametres,
            'current_route' => $this->router->getNameRoute(),
            'menuLeft' => 'Stock.GestionParametrage.numerotation',
            'listeChoixDateValiditeImputation' => $listeChoixDateValiditeImputation,
        ]);
    }

    /**
     * @throws Exception
     */
    public function imputationsAction(): Response
    {
        $paravrac = new Paravrac($this->pdo);
        $trad = $this->getTranslationService();
        $post = $this->request->getParsedBody();
        $validator = new ParavracValidator($this->pdo, $trad);

        $parametres = $post['PARAVRAC'];
        foreach ($parametres['VA'] as $parametre) {
            $validator->validateDateDeValiditeImputation($parametre);
        }

        if ($validator->isValid()) {
            foreach ($parametres['BO'] as &$parametreBO) {
                $parametreBO['LIB01PARV'] = Sql::convertBooleenCheckboxForWsdl($parametreBO['LIB01PARV']);
            }
            $parametres['VA'] = VaParametresVracDataTransformer::input($parametres['VA']);
            $parametres['BT'][CodeParametreVracEnum::BLANCINTERDIT_TIERS->name]['LIB01PARV'] = Sql::convertBooleenCheckboxForWsdl($parametres['BT'][CodeParametreVracEnum::BLANCINTERDIT_TIERS->name]['LIB01PARV']);

            $this->pdo->beginTransaction();

            foreach ($parametres as $parametresSection) {
                foreach ($parametresSection as $parametre) {
                    $paravrac->updateEntity($parametre);
                }
            }

            $this->pdo->commit();

            return $this->createJsonResponse([
                'statut' => 'OK',
                'redirectRoute' => $this->router->generateUri('Stock.Vrac.imputationsForm')
            ]);
        } else {
            return $this->createBloquantJsonErrorResponse([], $validator->getError());
        }
    }

    public function controleBudgetsFormAction(): string
    {
        $trad = $this->getTranslationService();
        $listManager = new ListManagerService($trad);
        $parametres = (new ParametrageService($this->pdo))->getParametres(
            TypeParametreVracEnum::PARAMGEN->name,
            $listManager->getCodeParameterParamgenList()
        );

        return $this->renderer->render('@Stock/Parametrage/Vrac/controle_budgets_form', [
            'menuActive' => 'Stock',
            'parametres' => $parametres,
            'current_route' => $this->router->getNameRoute(),
            'menuLeft' => 'Stock.GestionParametrage.numerotation',
            'listeChoixControleGlobal' => $listManager->getChoixControleGlobalList(),
            'listeChoixControleBonsDeSortie' => $listManager->getChoixDateValiditeList()
        ]);
    }

    /**
     * @throws Exception
     */
    public function controleBudgetsAction(): Response
    {
        $paravrac = new Paravrac($this->pdo);
        $trad = $this->getTranslationService();
        $post = $this->request->getParsedBody();
        $validator = new ParavracValidator($this->pdo, $trad);

        $parametres = $post['PARAVRAC'];

        $validator
            ->validateGlobalPeriode($parametres[CodeParametreVracEnum::VERIF_BUDGSI->name], 'Section d\'imputation')
            ->validateGlobalPeriode($parametres[CodeParametreVracEnum::VERIF_BUDCDC->name], 'Code complémentaire')
            ->validateGlobalPeriode($parametres[CodeParametreVracEnum::VERIF_BUDSCA->name], 'Sous-compte d\'analyse')
            ->validateGlobalPeriode($parametres[CodeParametreVracEnum::CTRLBUDCPTBS->name], 'Contrôle sur bons de sortie')
            ->validateBonsDeSortie($parametres[CodeParametreVracEnum::VERBS_CTRLSI->name], 'Section d\'imputation')
            ->validateBonsDeSortie($parametres[CodeParametreVracEnum::VERBS_CTLCDC->name], 'Code complémentaire')
            ->validateBonsDeSortie($parametres[CodeParametreVracEnum::VERBS_CTLSCA->name], 'Sous-compte d\'analyse')
            ->validateTauxDavancement($parametres[CodeParametreVracEnum::VERBS_TXAVSI->name], 'Section d\'imputation')
            ->validateTauxDavancement($parametres[CodeParametreVracEnum::VERBS_TXVCDC->name], 'Code complémentaire')
            ->validateTauxDavancement($parametres[CodeParametreVracEnum::VERBS_TXVSCA->name], 'Sous-compte d\'analyse')
        ;

        if ($validator->isValid()) {
            $parametres[CodeParametreVracEnum::BS_ACTIVATION_CUMULS->name]['LIB01PARV'] = Sql::toBool($parametres[CodeParametreVracEnum::BS_ACTIVATION_CUMULS->name]['LIB01PARV']);

            $this->pdo->beginTransaction();

            foreach ($parametres as $parametre) {
                $paravrac->updateEntity($parametre);
            }

            $this->pdo->commit();

            return $this->createJsonResponse([
                'statut' => 'OK',
                'redirectRoute' => $this->router->generateUri('Stock.Vrac.controleBudgetsForm')
            ]);
        } else {
            return $this->createBloquantJsonErrorResponse([], $validator->getError());
        }
    }
}
