<?php

namespace Modules\Stock\Service\Validation;

use Entity\Model\SbentLo;
use Exception;
use Helpers\Additional\Specifique\Specifique;
use Helpers\Trad\ITrad;
use Modules\Stock\Enum\CodeParametreVracEnum;
use Modules\Stock\Validator\BonEntreeValidator;
use Modules\Stock\Validator\LigneBonEntreeValidator;
use PDO;

class BonEntreeValidationService extends AbstractEnteteValidationService
{
    private BonEntreeValidator $bonEntreeValidator;


    public function __construct(PDO $pdo, ITrad $trad)
    {
        $this->pdo = $pdo;
        $this->trad = $trad;
        $this->bonEntreeValidator = new BonEntreeValidator($pdo, $trad);
    }

    /**
     * @param array<string,mixed> $enteteEntity
     * @param array<int,array<string,mixed>> $ligneEntities
     * @return $this
     * @throws Exception
     */
    public function validate(array $enteteEntity, array $ligneEntities): self
    {
        $this->bonEntreeValidator
            ->validateLignesBonEntree($ligneEntities)
            ->validateProvenance($enteteEntity)
            ->validateSiteOuvert($enteteEntity)
            ->validateMagasinierOuvert($enteteEntity)
            ->validateCs('SBE_ENTE', [$enteteEntity['NO_BE'], null])
        ;

        $this->bloquantErrors = $this->createErrors($this->bonEntreeValidator->getError(), 'Bloquant', null, $this->trad);
        $this->nonBloquantErrors = $this->createErrors($this->bonEntreeValidator->getErrorNonBloquant(), 'Non Bloquant', null, $this->trad);

        $sbentLo = new SbentLo($this->pdo);
        foreach ($ligneEntities as $ligneBonEntree) {
            $ligneBonEntreeValidator = new LigneBonEntreeValidator($this->pdo, $this->trad);
            $lotsBonEntree = $sbentLo->findAll([
                'NO_BE' => $ligneBonEntree['NO_BE'],
                'NO_LIG' => $ligneBonEntree['NO_LIG_BE']
            ]);

            $ligneBonEntreeValidator
                ->validateQteEnt($ligneBonEntree)
                ->validateCodgest($ligneBonEntree)
                ->validateStockArticle($ligneBonEntree)
                ->validateCodeArt($ligneBonEntree, $enteteEntity)
                ->validateArticleOuvert($ligneBonEntree, $enteteEntity)
                ->validateMouvementOuvert($ligneBonEntree, $enteteEntity)
                ->validateLots($ligneBonEntree, $lotsBonEntree, true)
                ->validateCs('SBE_LIGN', [$ligneBonEntree['NO_BE'], $ligneBonEntree['NO_LIG_BE']])
                ->validateSCADate($ligneBonEntree, CodeParametreVracEnum::IMP_VA_SCA_BE)
                ->validateSectimpDate($ligneBonEntree, CodeParametreVracEnum::IMP_VA_SI_BE)
                ->validateCodeCDCDate($ligneBonEntree, CodeParametreVracEnum::IMP_VA_CDC_BE)
                ->validateSectimp($ligneBonEntree, CodeParametreVracEnum::IMP_BO_SI__BE, $enteteEntity['CODE_STE'])
                ->validateCodeComp($ligneBonEntree, CodeParametreVracEnum::IMP_BO_CDC_BE, $enteteEntity['CODE_STE'])
                ->validateSscpteana($ligneBonEntree, CodeParametreVracEnum::IMP_BO_SCA_BE, $enteteEntity['CODE_STE'])
            ;

            $this->bloquantErrors = array_merge(
                $this->bloquantErrors,
                $this->createErrors($ligneBonEntreeValidator->getError(), 'Bloquant', $ligneBonEntree['NO_LIG_BE'], $this->trad)
            );
            $this->nonBloquantErrors = array_merge(
                $this->nonBloquantErrors,
                $this->createErrors($ligneBonEntreeValidator->getErrorNonBloquant(), 'Non Bloquant', $ligneBonEntree['NO_LIG_BE'], $this->trad)
            );
        }


        $specifique = new Specifique();
        $namespaceSpecifique = $specifique->specifiqueFunction('\\Modules\\Stock\\Validator\\BonEntreeValidatorSpecifique');
        if (class_exists($namespaceSpecifique)) {
            $error = Specifique::specifique('\\Modules\\Stock\\Validator\\BonEntreeValidatorSpecifique', 'validate', $this->pdo, $this->trad, $enteteEntity, $ligneEntities);
        
            if (isset($error['nonBloquantErrors'])) {
                $this->nonBloquantErrors = array_merge(
                    $this->nonBloquantErrors,
                    $error['nonBloquantErrors'],
                );
            }

            if (isset($error['bloquantErrors'])) {
                $this->bloquantErrors = array_merge(
                    $this->bloquantErrors,
                    $error['bloquantErrors'],
                );
            }
        }

        $this->errors = array_merge($this->nonBloquantErrors, $this->bloquantErrors);

        if (count($this->bloquantErrors) > 0) {
            $this->isValid = false;
        }

        return $this;
    }
}
