<?php

namespace Modules\Stock\Service\Form;

use Entity\Model\Devise;
use Entity\Model\SbtEnte;
use Entity\Model\SbtLign;
use Entity\Model\SdsLign;
use Entity\Model\Snoreser;
use Entity\Model\Sstocklo;
use Exception;
use Helpers\ChampsSupplementaire\ChampSupp;
use Modules\Stock\Enum\Operation;
use Modules\Stock\Enum\TypeNumerotationEnum;
use Modules\Stock\Helper\NumberHelper;
use Modules\Stock\Interface\FormServiceInterface;
use Modules\Stock\Repository\BonTransfertRepo;
use PDO;

readonly class BonTransfertFormService implements FormServiceInterface
{
    public function __construct(private PDO $pdo)
    {
    }

    /**
     * @param array<string,mixed> $post
     * @param array<string,mixed> $data
     * @return array<string,mixed>
     * @throws Exception
     */
    public function initEntity(array $post, array $data = []): array
    {
        $devise = (new Devise($this->pdo))->find($data['SITE_STOCK']['DEVISE']);

        $post['NO_DS'] = $post['NO_DS'] === "" ? 0: $post['NO_DS'];
        $post['CODE_STE'] = $data['SITE_STOCK']['CODE_STE'];
        $post['DEVISE'] = $data['SITE_STOCK']['DEVISE'];
        $post['VAL_DEVIS'] = $devise['VALEUR'];

        $this->initNo($data['PARAMETRE_NUMEROTATION'], $post);

        return $post;
    }

    /**
     * @throws Exception
     * @param array<string,mixed> $entity
     */
    public function flushData(array $entity, array $post = []): void
    {
        $this->pdo->beginTransaction();

        if ($post['operation'] === Operation::CREATE) {
            $champSupp = new ChampSupp($this->pdo);
            $champSupp->copyDefault('SBT_ENTE', [$entity['NO_BT'], null], 'SOCIETE', $entity['CODE_STE']);
            $champSupp->copyDefault('SBT_ENTE', [$entity['NO_BT'], null], 'SSITESTO', $entity['SITE']);
            $champSupp->copyDefault('SBT_ENTE', [$entity['NO_BT'], null], 'HASTUTIL', $entity['MAG']);

            $this->createLignesBonTransfert($entity, $post);
        }

        (new SbtEnte($this->pdo))->merge($entity);
        ChampSupp::updateCS($post, $this->pdo);
        (new Snoreser($this->pdo))->delete(['NO_BT' => $entity['NO_BT']]);

        $this->pdo->commit();
    }

    /**
     * @param array<string,mixed> $parametreNumerotation
     * @param array<string,mixed> $entity
     * @return void
     * @throws Exception
     */
    public function initNo(array $parametreNumerotation, array &$entity): void
    {
        if ($parametreNumerotation['TYPE_NUM'] === TypeNumerotationEnum::A->name
            || ($parametreNumerotation['TYPE_NUM'] === TypeNumerotationEnum::I->name && $entity['NO_BT'] === '')
        ) {
            $entity['NO_BT'] = (new BonTransfertRepo($this->pdo))->getAutomatiqueNo($parametreNumerotation);
        }
    }

    /**
     * Création de lignes de bon de transfert à partir des inputs contenus dans SBT_LIGNS constitués à partir
     * de lignes d'une demande de service.
     *
     * @param array<string,mixed> $entity
     * @param array<string,mixed> $post
     * @return void
     * @throws Exception
     */
    private function createLignesBonTransfert(array $entity, array $post): void
    {
        if (!empty($post['SBT_LIGNS'])) {
            $noDs = $entity['NO_DS'];
            $sbtLign = new SbtLign($this->pdo);
            $sdsLign = new SdsLign($this->pdo);
            $sstocklo = new Sstocklo($this->pdo);
            $champSupp = new ChampSupp($this->pdo);

            foreach ($post['SBT_LIGNS'] as $key => $ligneBonTransfert) {
                $ligneDemandeService = $sdsLign->find(['NO_DS' => $noDs, 'NO_LIG_DS' => $ligneBonTransfert['NO_LIG_DS']]);
                $nouvelleLigneBonTransfert = [
                    'NO_BT' => $entity['NO_BT'],
                    'NO_LIG' => $key + 1,
                    'NO_DS' => $noDs,
                    'NO_LIG_DS' => $ligneBonTransfert['NO_LIG_DS'],
                    'CODE_ART' => $ligneDemandeService['ART'],
                    'QTE_TRF' => $ligneBonTransfert['QTE'],
                    'PRIX' => $sstocklo->find(['SITE' => $entity['SITE'], 'CODE_ART' => $ligneDemandeService['ART']], ['VAL_LOCAL'])['VAL_LOCAL'],
                    'REAPPRO_FAIT' => 0x46
                ];

                $ligneDemandeService['RESTE'] -= $ligneBonTransfert['QTE'];
                $sbtLign->processAndMerge($nouvelleLigneBonTransfert);
                $sdsLign->processAndMerge($ligneDemandeService);

                $codeEnrDestination = [$entity['NO_BT'], $nouvelleLigneBonTransfert['NO_LIG']];
                $champSupp->copyDefault('SBT_LIGN', $codeEnrDestination, 'SBT_ENTE', $entity['NO_BT']);
                $champSupp->copyDefault('SBT_LIGN', $codeEnrDestination, 'SSTOCKLO', $entity['SITE'] . $nouvelleLigneBonTransfert['CODE_ART']);
                $champSupp->copyDefault('SBT_LIGN', $codeEnrDestination, 'SARTICLE', $nouvelleLigneBonTransfert['CODE_ART']);
                $champSupp->copyDefault('SBT_LIGN', $codeEnrDestination, 'SDS_LIGN', ChampSupp::autoCompletCodeEnr($noDs, $ligneDemandeService['NO_LIG_DS'], 'SDS_LIGN'));
            }
        }
    }
}
