<?php

namespace Modules\Stock\Validator;

use Entity\Model\Paravrac;
use Entity\Model\Slotloc;
use Exception;
use Helpers\Parametres\Constante;
use Helpers\Trad\ITrad;
use Helpers\Trad\Trad;
use Helpers\Validator\Validator;
use Modules\Ajax\Repository\Listes;
use Modules\Stock\Helper\NumberHelper;
use Modules\Stock\Trait\Validator\LigneValidatorTrait;
use Modules\Stock\Trait\Validator\ValidatorTrait;
use PDO;

class LigneBonTransfertValidator extends Validator
{
    use ValidatorTrait;
    use LigneValidatorTrait;

    private readonly Listes $listes;
    /** @phpstan-ignore-next-line */
    private readonly Paravrac $paravrac;

    public function __construct(PDO $pdo, ITrad $trad)
    {
        parent::__construct($pdo, $trad);
        $this->listes = new Listes($pdo);
        $this->paravrac = new Paravrac($pdo);
    }

    /**
     * @param array<string,mixed> $ligneBonTransfert
     * @return $this
     * @throws Exception
     */
    public function validateQteTrf(array $ligneBonTransfert, string $nomChamps = 'Quantité transférée', ?float $previousQteSorti = null): self
    {
        $this->isFloat($this->trad->t($nomChamps), $ligneBonTransfert['QTE_TRF'], Constante::formatQTE, true, null, 0);

        if ($ligneBonTransfert['NO_DS'] && $previousQteSorti) {
            $maxQteSorti = self::getMaxQteSortie($this->pdo, $ligneBonTransfert, $previousQteSorti);

            if ($ligneBonTransfert['QTE_TRF'] > $maxQteSorti) {
                $this->setError($this->trad->t('La quantité transférée ne peut être supérieur à ' . $maxQteSorti));
            }
        }

        return $this;
    }

    /**
     * @param array<string, mixed> $ligneBonTransfert
     * @return LigneBonTransfertValidator
     */
    public function validatePrix(array $ligneBonTransfert): self
    {
        $this->isFloat($this->trad->t('Prix'), $ligneBonTransfert['PRIX'], Constante::formatPU);

        return $this;
    }

    /**
     * @param array<string,mixed> $ligneBonTransfert
     * @param array<int,array<string,mixed>> $lotsBonTransfert
     * @return $this
     * @throws Exception
     */
    public function validateLots(array $ligneBonTransfert, ?array &$lotsBonTransfert, string $site): self
    {
        if (empty($lotsBonTransfert)) {
            return $this;
        }

        $qteLotsSum = 0;
        $slotloc = new Slotloc($this->pdo);

        foreach ($lotsBonTransfert as $key => &$lotBonTransfert) {
            $this->isObligatoire($lotBonTransfert['NO_LOT'], Trad::strBuild($this->trad->t('N° Lot (ligne n°@1@ de la répartition des lots)'), $key + 1));
            if (!$lotLocal = $slotloc->find(['NO_LOT' => $lotBonTransfert['NO_LOT'], 'SITE' => $site, 'CODE_ART' => $ligneBonTransfert['CODE_ART']], ['QTE_LOC', 'QTE_INDIS'])) {
                $this->setError(Trad::strBuild($this->trad->t('Le lot N°@1@ n\'existe pas'), $lotBonTransfert['NO_LOT']));
            }

            $qteLotLabel = Trad::strBuild($this->trad->t('Quantité (ligne n°@1@ de la répartition des lots)'), $key + 1);
            $this->isObligatoire($lotBonTransfert['QTE_LOT'], $qteLotLabel);
            $this->isFloat($qteLotLabel, $lotBonTransfert['QTE_LOT'], Constante::formatQTE);

            $qteDisponible = floatval($lotLocal['QTE_LOC']) - floatval($lotLocal['QTE_INDIS']);
            if ($lotLocal && $qteDisponible < floatval($lotBonTransfert['QTE_LOT'])) {
                $this->setError(Trad::strBuild($this->trad->t('La quantité saisie (ligne n°@1@ de la répartition des lots) excède la quantité disponible du lot local associé'), $key + 1));
            }

            $qteLotsSum += NumberHelper::toFloat($lotBonTransfert['QTE_LOT']);
        }

        if (floatval($qteLotsSum) !== floatval($ligneBonTransfert['QTE_TRF'])) {
            $this->setError($this->trad->t('La somme des quantités des lots doit être égale à la quantité transférée de la ligne'));
        }

        return $this;
    }
}
