<?php

namespace Modules\Stock\Controller;

use Entity\Model\CsDon;
use Entity\Model\Sarticle;
use Entity\Model\SbtEnte;
use Entity\Model\SbtLign;
use Entity\Model\SbtLots;
use Entity\Model\SSiteSto;
use Exception;
use GuzzleHttp\Psr7\Response;
use Helpers\ChampsSupplementaire\ChampSupp;
use Modules\Stock\Enum\TypeEnteteEnum;
use Modules\Stock\Repository\LigneBonTransfertRepo;
use Modules\Stock\Service\CsInitializerService;
use Modules\Stock\Service\Form\LigneBonTransfertFormService;
use Modules\Stock\Trait\Controller\LigneControllerTrait;
use Modules\Stock\Trait\Controller\StockContollerTrait;
use Modules\Stock\Validator\LigneBonTransfertValidator;
use Skeleton\Controller\Controller;

class LigneBonTransfertController extends Controller
{
    use LigneControllerTrait;
    use StockContollerTrait;

    /**
     * @throws Exception
     */
    public function ligneAction(): string
    {
        $noBt = (int) $this->request->getAttribute('noBt');
        $noLigne = (int) $this->request->getAttribute('noLigne');
        $ligneBonTransfert = (new SbtLign($this->pdo))->find(['NO_BT' => $noBt, 'NO_LIG' => $noLigne]);

        return $this->getLigneResponse($noBt, $noLigne, $ligneBonTransfert, 'SBT_LIGN', TypeEnteteEnum::BT);
    }

    /**
     * @throws Exception
     */
    public function ajouterFormAction(): string
    {
        $post = $this->request->getParsedBody();
        $noBt = $this->request->getAttribute('noBt');
        $bonTransfert = (new SbtEnte($this->pdo))->find(['NO_BT' => $noBt]);
        $noLigne = (new LigneBonTransfertRepo($this->pdo))->getNouveauNoLigne($noBt, 'NO_LIG', 'SBT_LIGN', 'NO_BT');
        $codeEnr = ChampSupp::autoCompletCodeEnr($noBt, $noLigne, 'SBT_LIGN');

        (new CsInitializerService($this->pdo))->initializeCs($post, 'SBT_LIGN', $codeEnr, [['SBT_ENTE', $noBt]]);

        return $this->renderer->render('@Stock/LigneBonTransfert/ajouter_form', [
            'noBt'         => $noBt,
            'post'         => $post,
            'noLigne'      => $noLigne,
            'bonTransfert' => $bonTransfert,
            'siteStock'    => (new SSiteSto($this->pdo))->find(['SITE' => $bonTransfert['SITE']])
        ]);
    }

    /**
     * @throws Exception
     */
    public function ajouterAction(): Response
    {
        $trad = $this->getTranslationService();
        $post = $this->request->getParsedBody();
        $noBt = $this->request->getAttribute('noBt');
        $formService = new LigneBonTransfertFormService($this->pdo);
        $validator = new LigneBonTransfertValidator($this->pdo, $trad);

        $ligneBonTransfert = $formService->initEntity($post['SBT_LIGN'], ['NO_BT' => $noBt]);
        if ((new SbtLign($this->pdo))->find(['NO_BT' => $ligneBonTransfert['NO_BT'], 'NO_LIG' => $ligneBonTransfert['NO_LIG']])) {
            return $this->createJsonResponse(['statut' => 'OK', 'message' => $trad->t('Ligne existante')]);
        }

        $bonTransfert = (new SbtEnte($this->pdo))->find($noBt);

        $isValid = $validator
            ->validatePrix($ligneBonTransfert)
            ->validateQteTrf($ligneBonTransfert)
            ->validateCodeArt($ligneBonTransfert, $bonTransfert)
            ->validateLots($ligneBonTransfert, $post['SBT_LOTS'], $bonTransfert['SITE'])
            ->validateCs('SBT_LIGN', [$ligneBonTransfert['NO_BT'], $ligneBonTransfert['NO_LIG']], $post)
            ->isValid()
        ;

        if (!$isValid) {
            return $this->createBloquantJsonErrorResponse([], $validator->getError());
        }

        $post['QTE_TRF_VAR'] = $formService->getQteVar(0, $ligneBonTransfert['QTE_TRF']);
        $post['BON_TRANSFERT'] = $bonTransfert;
        $formService->flushData($ligneBonTransfert, $post);

        return $this->createJsonResponse(['statut' => 'OK']);
    }

    /**
     * @throws Exception
     */
    public function modifierFormAction(): string
    {
        $noBt = $this->request->getAttribute('noBt');
        $noLigne = $this->request->getAttribute('noLigne');
        $bonTransfert = (new SbtEnte($this->pdo))->find(['NO_BT' => $noBt]);
        $ligneBonTransfert = (new SbtLign($this->pdo))->find(['NO_BT' => $noBt, 'NO_LIG' => $noLigne]);
        $stockArticle = (new Sarticle($this->pdo))->find(['CODE_ART' => $ligneBonTransfert['CODE_ART']]);
        $maxQteTrf = LigneBonTransfertValidator::getMaxQteSortie($this->pdo, $ligneBonTransfert, (float) $ligneBonTransfert['QTE_TRF']);
        $ligneBonTransfert['SBT_LOTS'] = (new SbtLots($this->pdo))->findAll(['NO_BT' => $ligneBonTransfert['NO_BT'], 'NO_LIG_BT' => $ligneBonTransfert['NO_LIG']]);

        return $this->renderer->render('@Stock/LigneBonTransfert/modifier_form', [
            'noBt' => $noBt,
            'noLigne' => $noLigne,
            'maxQteTrf' => $maxQteTrf,
            'ligneBonTransfert' => $ligneBonTransfert,
            'bonTransfert' => $bonTransfert,
            'stockArticle' => $stockArticle,
            'uniteStockee' => $stockArticle['UNITE_STK'],
            'siteStock' => (new SSiteSto($this->pdo))->find(['SITE' => $bonTransfert['SITE']]),
        ]);
    }

    /**
     * @throws Exception
     */
    public function modifierAction(): Response
    {
        $post = $this->request->getParsedBody();
        $noBt = $this->request->getAttribute('noBt');
        $noLigne = $this->request->getAttribute('noLigne');
        $formService = new LigneBonTransfertFormService($this->pdo);
        $validator = new LigneBonTransfertValidator($this->pdo, $this->getTranslationService());

        $bonTransfert = (new SbtEnte($this->pdo))->find($noBt);
        $ligneBonTransfert = (new SbtLign($this->pdo))->find(['NO_BT' => $noBt, 'NO_LIG' => $noLigne]);

        $previousQteTrf = floatval($ligneBonTransfert['QTE_TRF']);
        $qteTrfVar = $formService->getQteVar($previousQteTrf, $post['SBT_LIGN']['QTE_TRF']);
        $ligneBonTransfert = array_merge($ligneBonTransfert, $post['SBT_LIGN']);

        $isValid = $validator
            ->validatePrix($ligneBonTransfert)
            ->validateCodeArt($ligneBonTransfert, $bonTransfert)
            ->validateQteTrf($ligneBonTransfert, 'Quantité transférée', $previousQteTrf)
            ->validateLots($ligneBonTransfert, $post['SBT_LOTS'], $bonTransfert['SITE'])
            ->validateCs('SBT_LIGN', [$ligneBonTransfert['NO_BT'], $ligneBonTransfert['NO_LIG']], $post)
            ->isValid()
        ;

        if (!$isValid) {
            return $this->createBloquantJsonErrorResponse([], $validator->getError());
        }

        $post['QTE_TRF_VAR'] = $qteTrfVar;
        $post['BON_TRANSFERT'] = $bonTransfert;
        $formService->flushData($ligneBonTransfert, $post);

        return $this->createJsonResponse(['statut' => 'OK']);
    }

    /**
     * @throws Exception
     */
    public function supprimerAction(): Response
    {
        $noBt = $this->request->getAttribute('noBt');
        $noLigne = $this->request->getAttribute('noLigne');
        $bonTransfert = (new SbtEnte($this->pdo))->find($noBt);
        $formService = new LigneBonTransfertFormService($this->pdo);
        $codeEnr = ChampSupp::autoCompletCodeEnr($noBt, $noLigne, 'SBT_LIGN');
        $ligneBonTransfert = (new SbtLign($this->pdo))->find(['NO_BT' => $noBt, 'NO_LIG' => $noLigne]);
        $qteTrfVar = $formService->getQteVar($ligneBonTransfert['QTE_TRF'], 0);

        $this->pdo->beginTransaction();

        (new SbtLign($this->pdo))->delete(['NO_BT' => $noBt, 'NO_LIG' => $noLigne]);
        (new CsDon($this->pdo))->delete(['COD_TAB' => 'SBT_LIGN', 'COD_ENR' => $codeEnr]);
        $formService->updateResteLigneDemandeService($ligneBonTransfert, $ligneBonTransfert['QTE_TRF']);
        $formService->updateQteReserveeStockLocal($ligneBonTransfert, $qteTrfVar, $bonTransfert['SITE'], 'CODE_ART');
        (new SbtLots($this->pdo))->delete(['NO_BT' => $noBt, 'NO_LIG_BT' => $noLigne]);

        $this->pdo->commit();

        return $this->createJsonResponse(['statut' => 'OK']);
    }
}
