<?php

namespace Modules\Stock\Trait\Validator;

use Entity\Model\SdsLign;
use Entity\Model\Snoreser;
use Exception;
use Helpers\Outil\Sql;
use Helpers\Trad\Trad;
use Modules\Stock\Enum\TypeEnteteEnum;
use Modules\Stock\Enum\TypeNumerotationEnum;

trait EnteteValidatorTrait
{
    /**
     * @param array<string,mixed> $entity
     * @param null|array<string,mixed> $parametreNumerotation
     * @return self
     * @throws Exception
     */
    public function validateNo(array $entity, ?array $parametreNumerotation, TypeEnteteEnum $typeEnteteEnum, string $enteteLabel): self
    {
        if (!$parametreNumerotation) {
            return $this;
        }

        $snoreser = new Snoreser($this->pdo);
        $noColName = $typeEnteteEnum->getColName();

        if ($parametreNumerotation['TYPE_NUM'] === TypeNumerotationEnum::M->name) {
            $this->isObligatoire($entity[$noColName], $this->trad->t('N° de ' . $enteteLabel));
        }
        if (in_array($parametreNumerotation['TYPE_NUM'], [TypeNumerotationEnum::I->name, TypeNumerotationEnum::M->name])) {
            if ($entity[$noColName] === "") {
                return $this;
            }

            /** @phpstan-ignore-next-line */
            if ($entity[$noColName] && $this->enteteRepo->isNoUtilise($typeEnteteEnum, $entity[$noColName])) {
                $this->setError(Trad::strBuild($this->trad->t('Le numéro de @1@ est déjà utilisé'), $enteteLabel));

                return $this;
            }

            if ($numeroReserve = $snoreser->find([$noColName => $entity[$noColName]])) {
                if ($numeroReserve['UTIL'] !== $_SESSION['Session_Login']) {
                    $this->setError(Trad::strBuild($this->trad->t('Le numéro de @1@ est déjà réservé par un autre utilisateur'), $enteteLabel));
                }
            }

            if (!Sql::toBool($parametreNumerotation['RECH_TROU'])) {
                if ((int) $entity[$noColName] < (int) $parametreNumerotation['PROCH_NO']) {
                    $this->setError($this->trad->t('Le numéro de '.$enteteLabel.' doit être supérieur ou égal à '.$parametreNumerotation['PROCH_NO']));
                }
            }
        }

        return $this;
    }

    /**
     * @param array<string,mixed> $enteteEntity
     * @throws Exception
     */
    public function validateSite(array $enteteEntity, ?string $expectedSite = null): self
    {
        $this->zoom(
            'SSiteSto',
            $enteteEntity['SITE'],
            $this->trad->t('Site'),
            $this->pdo,
            false,
            ['filter_SITE' => $enteteEntity['SITE']]
        );

        if ($expectedSite && $expectedSite !== $enteteEntity['SITE']) {
            $this->setError($this->trad->t('Le site de stockage doit être le même que celui de la demande de service'));
        }

        return $this;
    }

    /**
     * @param array<string,mixed> $post
     * @throws Exception
     */
    public function validateLignes(array $post, string $collectionName, string $noDs): self
    {
        if ($noDs !== "" && empty($post[$collectionName])) {
            $this->setError($this->trad->t('Vous devez sélectionner au moins une ligne de demande de service'));
        }

        $sdsLign = new SdsLign($this->pdo);
        foreach ($post[$collectionName] as $ligneEntity) {
            $ligneDemandeService = $sdsLign->find(['NO_DS' => $noDs, 'NO_LIG_DS' => $ligneEntity['NO_LIG_DS']]);
            if ($ligneDemandeService['RESTE'] < $ligneEntity['QTE']) {
                $this->setError(Trad::strBuild($this->trad->t('La quantité saisie sur la ligne n°@1@ excède le reste à servir de
                 la ligne de demande de service correspondante'), $ligneEntity['NO_LIG_DS']));
            }
        }

        return $this;
    }
}
