<?php

namespace Modules\Stock\Service\Form;

use Entity\Model\Devise;
use Entity\Model\SbsEnte;
use Entity\Model\SbsLign;
use Entity\Model\SdsLign;
use Entity\Model\Snoreser;
use Exception;
use Helpers\ChampsSupplementaire\ChampSupp;
use Modules\Stock\Enum\LigneOperationEnum;
use Modules\Stock\Enum\Operation;
use Modules\Stock\Enum\TypeNumerotationEnum;
use Modules\Stock\Interface\FormServiceInterface;
use Modules\Stock\Repository\BonSortieRepo;
use Modules\Stock\Trait\FormTrait;
use PDO;

readonly class BonSortieFormService implements FormServiceInterface
{
    use FormTrait;

    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
    {
        $post['ORIGINE'] = '';
        $post['TOT_BS'] = 0;
        $post['CODE_STE'] = $data['SITE_STOCK']['CODE_STE'];
        $post['DEVISE'] = $data['SITE_STOCK']['DEVISE'];
        $post['VAL_DEVIS'] = (new Devise($this->pdo))->find($post['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
    {
        if ($post['operation'] === Operation::CREATE) {
            $champSupp = new ChampSupp($this->pdo);
            $champSupp->copyDefault('SBS_ENTE', [$entity['NO_BS'], null], 'SOCIETE', $entity['CODE_STE']);
            $champSupp->copyDefault('SBS_ENTE', [$entity['NO_BS'], null], 'SSITESTO', $entity['SITE']);
            $champSupp->copyDefault('SBS_ENTE', [$entity['NO_BS'], null], 'HASTUTIL', $entity['MAG']);

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

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

    /**
     * @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_BS'] === '')
        ) {
            $entity['NO_BS'] = (new BonSortieRepo($this->pdo))->getAutomatiqueNo($parametreNumerotation);
        }
    }

    /**
     * Création de lignes de bon de sortie à partir des inputs contenus dans SBS_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 createLignesBonSortie(array $entity, array $post): void
    {
        if (!empty($post['SBS_LIGNS'])) {
            $noDs = $post['NO_DS'];
            $sbsLign = new SbsLign($this->pdo);
            $sdsLign = new SdsLign($this->pdo);
            $champSupp = new ChampSupp($this->pdo);
            $ligneBonSortieFormService = new LigneBonSortieFormService($this->pdo);

            foreach ($post['SBS_LIGNS'] as $key => $ligneBonSortie) {
                $ligneDemandeService = $sdsLign->find(['NO_DS' => $noDs, 'NO_LIG_DS' => $ligneBonSortie['NO_LIG_DS']]);
                $nouvelleLigneBonSortie = [
                    'NO_BS' => $entity['NO_BS'],
                    'NO_LIG' => $key + 1,
                    'NO_DS' => $noDs,
                    'PRIX_SORT' => $ligneBonSortieFormService->getStockLocalValLocal($entity['NO_BS'], $ligneDemandeService['ART']) ?? '',
                    'NO_LIG_DS' => $ligneDemandeService['NO_LIG_DS'],
                    'ART' => $ligneDemandeService['ART'],
                    'QTE_SORTI' => $ligneBonSortie['QTE'],
                    'SECTIMP' => $ligneDemandeService['SECTIMP'],
                    'CODE_COMP' => $ligneDemandeService['CODE_COMP'],
                    'SSCPTEANA' => $ligneDemandeService['SSCPTEANA'],
                    'CODGES' => $ligneDemandeService['CODGES'],
                    'LIBGES' => $ligneDemandeService['LIBGES'],
                    'ID_CG' => $ligneDemandeService['ID_CG']
                ];

                $ligneBonSortieFormService->updateTotalEntete($entity, $nouvelleLigneBonSortie, LigneOperationEnum::ADD, 0);

                $ligneDemandeService['RESTE'] -= $ligneBonSortie['QTE'];

                $sbsLign->merge($nouvelleLigneBonSortie);
                $sdsLign->processAndMerge($ligneDemandeService);

                $codeEnrDestination = [$entity['NO_BS'], $nouvelleLigneBonSortie['NO_LIG']];
                $codeEnrSectimp = ChampSupp::autoCompletCodeEnrImputations($this->pdo, 'SECTIMPU', $nouvelleLigneBonSortie['SECTIMP'], $entity['CODE_STE']);
                $codeEnrCodecomp = ChampSupp::autoCompletCodeEnrImputations($this->pdo, 'CODECOMP', $nouvelleLigneBonSortie['CODE_COMP'], $entity['CODE_STE']);
                $codeEnrSscpteana = ChampSupp::autoCompletCodeEnrImputations($this->pdo, 'SSCPTANA', $nouvelleLigneBonSortie['SSCPTEANA'], $entity['CODE_STE']);

                $champSupp->copyDefault('SBS_LIGN', $codeEnrDestination, 'SBS_ENTE', $entity['NO_BS']);
                $champSupp->copyDefault('SBS_LIGN', $codeEnrDestination, 'SSTOCKLO', $entity['SITE'] . $nouvelleLigneBonSortie['ART']);
                $champSupp->copyDefault('SBS_LIGN', $codeEnrDestination, 'SARTICLE', $nouvelleLigneBonSortie['ART']);
                $champSupp->copyDefault('SBS_LIGN', $codeEnrDestination, 'SECTIMPU', $codeEnrSectimp);
                $champSupp->copyDefault('SBS_LIGN', $codeEnrDestination, 'CODECOMP', $codeEnrCodecomp);
                $champSupp->copyDefault('SBS_LIGN', $codeEnrDestination, 'SSCPTANA', $codeEnrSscpteana);
                $champSupp->copyDefault('SBS_LIGN', $codeEnrDestination, 'SDS_LIGN', ChampSupp::autoCompletCodeEnr($noDs, $ligneDemandeService['NO_LIG_DS'], 'SDS_LIGN'));
            }
        }
    }
}
