<?php

namespace Modules\RechercheArticles\Service;

use Entity\Model\CaEntet;
use Entity\Model\CaLigne;
use Entity\Model\CaPlCt;
use Entity\Model\Centre;
use Entity\Model\Country;
use Entity\Model\DaEntet;
use Entity\Model\DaLigne;
use Entity\Model\DaPlann;
use Entity\Model\Paravrac;
use Helpers\CaracCompl\CaracCompl;
use Helpers\ChampsSupplementaire\ChampSupp;
use Helpers\Outil\Sql;
use Helpers\Parametres\Constante;
use Modules\Commande\Service\CalculPlanningService;
use Modules\DemandeAchat\Repository\ModificationDemandeAchat;
use Modules\GlobalApplication\Outil\InitAxesImpCde;
use Modules\GlobalApplication\Outil\InitAxesImpDa;
use Modules\Panier\Service\CalculTauxTvaService;
use Modules\Panier\Service\OutilPanierService;
use PDO;

class AjoutLigneDAService
{
    /**
     * @var array<mixed> $enteteDA
     */
    private $enteteDA;

    public function __construct(
        private PDO $pdo
    ) {
    }

    public function setNoDA(string $noDA):void
    {
        $this->enteteDA = (new DaEntet($this->pdo))->find($noDA);
    }

    /**
     * @param array<mixed> $article
     * @return void
     */
    public function generateLigne($article):void
    {
        $centreEntete = (new Centre($this->pdo))->find($this->enteteDA['CTR_LIV']);
        $pays = new Country($this->pdo);
        $paysCtrLiv = $pays->find($this->enteteDA['PAYSLIV']);

        $paramPaysInstall = sql::paravrac($this->pdo, 'PARAMGEN', 'PAYSINSTAL');
        $paysInstall = $pays->find($paramPaysInstall);

        if (!$this->enteteDA['PAYSFOU']) {
            $codePays =  $paysInstall['CODE_PAYS'];
        } else {
            $codePays = $this->enteteDA['PAYSFOU'];
        }
        $paysEntete = $pays->find($codePays);

        $centre = new Centre($this->pdo);
        $centreEntete = $centre->find($this->enteteDA['CTR_LIV']);

        $paramTVA = [
            'regle' => (new Paravrac($this->pdo))->getGeneric('REGINIT_TVA'),
            'TVA'   => Sql::parametr($this->pdo, 'TX_TVA'),
        ];

        if (Sql::toBool($paysEntete['AV_TAXLOC']) && sql::toBool($article['ARTICLE_AV_TAXLOC'])) {
            $tva = $centreEntete['TX_TAXLOC'];
        } else {
            if ($paramTVA['regle'] == 'T') {
                $tva = $paysCtrLiv['TVA'];
            } elseif (($paysEntete['CODE_PAYS'] == $paysInstall['CODE_PAYS']) || (sql::boolSql($paysEntete['PAYSCEE']) && sql::boolSql($paysInstall['PAYSCEE']))) {
                $tva = $article['TXTVA']??$article['TAUX_TVA'];
            } else {
                $tva = $paramTVA['TVA'];
            }
        }

        $imputations = (new InitAxesImpDa(
            $this->pdo,
            (new DaEntet($this->pdo))->find($this->enteteDA['NO_DA'])
        ))->getInitImputation([
            'CODE_ART' => $article['CODE_ART'],
            'SousFamille' => [
                'CODE_SFA' => $article['COD_SFAM'],
                'CODE_FAM' => $article['CODE_FAM'],
            ],
        ]);

        $tempinit = number_format($article['PX_ART'], Constante::PUDECIMAL, '.', '').'|'.number_format(0, 2, '.', '').'||'.'CAT';

        $saisieRec = false;
        $recepAuto = false;
        if (!Sql::toBool($article['NONRECEPT']??'N')) {
            $saisieRec = true;
            $recepAuto = Sql::toBool($article['RECEP_AUTO']);
        }

        if ($saisieRec) {
            $FIN_DEB_PER = 'F';
            $RECEPAUTO_JOUR = '31';
            $DATEDEBCONT = $this->enteteCde['DATEDEBCONT'] ?? '00000000';
            $DATEFINCONT = $this->enteteCde['DATEFINCONT'] ?? '00000000';
            $periodicite = $this->enteteCde['CONTRAT_PERIOD']?? $article['PER_REC_AUTO']?:'M';
        }

        $idLigne = (new DaLigne($this->pdo))->getMaxNoPo($this->enteteDA['NO_DA'])+1;

        $traitementDA = (int) (new Paravrac($this->pdo))->getValue('PARAMGEN', 'DUREETTDA');
        $dteLivr = OutilPanierService::getDateLivraisonMin($article['DELAI'], $traitementDA);

        $values = [
            'NO_DA'         => $this->enteteDA['NO_DA'],
            'NO_PO'         => $idLigne,
            'CODE_ART'      => $article['COD_ART'],
            'DES_SOMM'      => $article['DES_ART'],
            'SSFAM'         => $article['COD_SFAM'],
            'PU'            => $article['PX_ART'],
            'QTE_DEM'       => 1,
            'DEJA_COMM'     => 0,

            'SECTIMP'       => $imputations['SI'],
            'CODE_COMP'     => $imputations['CDC'],
            'SSCPTEANA'     => $imputations['SCA'],
            'ID_CG'         => $imputations['ID_CG'],
            'CODGES'        => $imputations['CODGES'],
            'LIBGES'        => $imputations['LIBGES'],

            'DTELIVSOU'     => $dteLivr,
            'UNITE'         => $article['COD_UNIT'],
            'MNT_LIG'       => $article['PX_ART'],
            'TX_REMISE'     => '0',
            'SITE_STK'      => '',
            'CTRL_BR'       => '0',
            'NM_DCOMP'      => sql::updateMemo($this->pdo, '', $article['DES_COMP']),
            'BUDGET'        => '',
            'CHIF_EXEC'     => $this->enteteDA['CHIF_EXEC'],
            'TRAITEE'       => false,
            'VALIDEE'       => false,
            'CODE_FOU'      => $article['COD_FOURN'],
            'ACHETEUR'      => $_SESSION["Session_Login"],
            'TYP_DOC'       => $this->enteteDA['TYP_DOC'],
            'CODE_STE'      => $this->enteteDA['CODE_STE'],
            'ACD'           => $article['COD_ACD'],
            'NOLI_FRM'      => 0, // lié aux formulaires de création de DA donc laisse à 0
            'MOD_TRS'       => '',
            'TYPNMP'        => 'U',
            'FM_MET'        => '', // TODO quelle valeur ? obsolète, à retirer
            'FM_SPE'        => '', // TODO quelle valeur ? obsolète, à retirer
            'ACHATDIR'      => false, // ignorer, vient des autres modes de création
            'CTRLIVR'       => $this->enteteDA['CTR_LIV'],
            'TVA'           => $tva??'',
            'TEMPINIT'      => $tempinit,
            'FRAISANN'      => false, // TODO quelle valeur ? ignorer, vient des paniers

            'REF_FOUR'                  => $article['REF_FOURN'],
            'COD_FAB'                   => $article['COD_FAB']??'',
            'COD_GAM'                   => $article['COD_GAM']??'',
            'REF_FAB'                   => $article['REF_FAB']??'',

            'CDEAUTO'       => false, // ignorer, vient des paniers
            'numerique_RECEP_AUTO'  => Sql::setBoolSql($recepAuto),
            'DATEDEBCONT'               => $recepAuto? $DATEDEBCONT??'':'00000000',
            'DATEFINCONT'               => $recepAuto? $DATEFINCONT??'':'00000000',
            'CONTRAT_PERIOD'            => $recepAuto? $periodicite??'':'',
            'FIN_DEB_PER'               => $recepAuto? $FIN_DEB_PER??'':'',
            'DALI_RECEPAUTO_JOUR'       => $recepAuto? $RECEPAUTO_JOUR??'':'',
            'ID_EXTERNE'                => $article['ID_EXTERNE']??'', // pour les punchout
            'ID_CAT_ORI'                => $article['ID_CAT'],
        ];

        (new DaLigne($this->pdo))->insert($values);

        $caracCompl = new CaracCompl($this->pdo, $article['COD_ART'], ($article['COD_SFAM']??''), ($article['CODE_FAM']??''));
        $caracCompl->insertCC('DA', $this->enteteDA['NO_DA'], (string)$idLigne, '0');


        $champSupp = new ChampSupp($this->pdo);
        $listeCS = $champSupp->getInfoCS('CA_LIGNE');

        foreach ($listeCS as $cs) {
            $valueCS = '';
            if ($cs['TAB_SOUR'] == 'ARTICLES' && $article['COD_ART'] != '') {
                $idCS = $article['COD_ART'];
                $valueCS = ChampSupp::getValueCS($cs['TAB_SOUR'], $idCS, $cs['CHP_SOUR'], $this->pdo);
            }

            $idCSLigne = $champSupp::autoCompletCodeEnr($this->enteteDA['NO_DA'], $idLigne, 'DA_LIGNE');
            $champSupp->insertChampSupp('DA_LIGNE', $idCSLigne, $cs['NUM_FIX'], $valueCS, $this->pdo);
        }

        if ($recepAuto) {
            $calculPlanningService = new CalculPlanningService('1', $periodicite??'', $DATEDEBCONT??'', $DATEFINCONT??'', $FIN_DEB_PER??'', $RECEPAUTO_JOUR??'');
            $calculPlanningService->calculPlanning();
            $planning = $calculPlanningService->getTableauEcheance();
        } else {
            $planning = [[
                'DTE_LIV'   => '00000000',
                'QTE_COMM'  => 1
            ]];
        }

        $daPlan = new DaPlann($this->pdo);

        foreach ($planning as $plann) {
            $daPlan->insert([
                'NO_DA'     => $this->enteteDA['NO_DA'],
                'NO_PO'     => $idLigne,
                'DTE_LIV'   => $plann['DTE_LIV'],
                'QTE_DEMAN' => $plann['QTE_COMM'],
                'CODE_STE'  => $this->enteteDA['CODE_STE'],
                'DATEMODI'  => '00000000',
            ]);
        }

        $montantsLignes = (new ModificationDemandeAchat($this->pdo))->montantsLignes($this->enteteDA['NO_DA']);
        $ht = 0;
        $ttc = 0;
        foreach ($montantsLignes as $values) {
            $ht += $values['MNT_LIG'];
            $ttc += $values['MNT_LIG'] * (1 + $values['TVA'] / 100);
        }

        $ht = number_format($ht, 2, '.', '');
        $ttc = number_format($ttc, 2, '.', '');
        (new DaEntet($this->pdo))->update(['TOTAL_DA' => $ht, 'TOTAL_DA_TTC' => $ttc], $this->enteteDA['NO_DA']);
    }
}
