<?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\Paravrac;
use Helpers\CaracCompl\CaracCompl;
use Helpers\ChampsSupplementaire\ChampSupp;
use Helpers\Outil\Sql;
use Helpers\Parametres\Constante;
use Modules\Commande\Repository\CreationCommande;
use Modules\Commande\Service\CalculPlanningService;
use Modules\GlobalApplication\Outil\InitAxesImpCde;
use Modules\Panier\Service\CalculTauxTvaService;
use Modules\Panier\Service\OutilPanierService;
use PDO;

class AjoutLigneCdeService
{
    /**
     * @var array<mixed> $enteteCde
     */
    private $enteteCde;

    public function __construct(
        private PDO $pdo
    ) {
    }

    public function setNoCde(string $noCde):void
    {
        $this->enteteCde = (new CaEntet($this->pdo))->find($noCde);
    }

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

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

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

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

        //calcule max ligne cde
        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 InitAxesImpCde(
            $this->pdo,
            (new CaEntet($this->pdo))->find($this->enteteCde['NO_CDE'])
        ))->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($this->enteteCde['SAISIEREC'])) {
            $saisieRec = true;
            $recepAuto = Sql::toBool($this->enteteCde['RECEP_AUTO']);
        } elseif (!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 CaLigne($this->pdo))->getMaxNoPo($this->enteteCde['NO_CDE'])+1;

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

        $commande = [
            'NO_CDE'                    => $this->enteteCde['NO_CDE'],
            'NO_PO'                     => $idLigne,
            'CODE_ART'                  => $article['COD_ART'],
            'DES_SOMM'                  => $article['DES_ART'],
            'NM_DCOMP'                  => sql::updateMemo($this->pdo, '', $article['DES_COMP']),
            'SSFAM'                     => $article['COD_SFAM'],
            'PU'                        => $article['PX_ART'],
            'TVA'                       => $tva,
            'REMISE'                    => '0',
            'QTE_COMM'                  => 1,
            'UNITE'                     => $article['COD_UNIT'],
            'RAL'                       => 1,
            'DTELIVCON'                 => $dteLivr,

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

            'NO_DA'                     => '0',
            'NO_PO_DA'                  => '0',
            'QTE_FACTU'                 => '0',
            'QTEFACVAL'                 => '0',
            'SOM_FACTU'                 => '0',
            'ET_CDELIG'                 => 'A',
            'SOMFACVAL'                 => '0',
            'SITE_STK'                  => '',
            'CTRL_BR'                   => '0',
            'numerique_SAISIEREC'       => Sql::setBoolSql($saisieRec),
            'TOLLIVAVA'                 => Sql::parametr($this->pdo, 'NBJOAVLIV'),
            'CODE_STE'                  => $this->enteteCde['CODE_STE'],
            'ACCORCA'                   => $article['COD_ACD'],
            'POIDS'                     => '',
            'LONGU'                     => '',
            'LARG'                      => '',
            'HAUT'                      => '',
            'VOLUME'                    => '',
            'PAY_ORI'                   => '',
            'PAY_PRO'                   => '',
            'DOUANE'                    => '',
            'POIDSNET'                  => '',
            'TYPNMP'                    => '',
            'TEMPINIT'                  => $tempinit,
            'TYPDATE'                   => 'D',

            'REF_FOUR'                  => $article['REF_FOURN'],
            'COD_FAB'                   => $article['COD_FAB']??'',
            'COD_GAM'                   => $article['COD_GAM']??'',
            'REF_FAB'                   => $article['REF_FAB']??'',
            
            'numerique_SOLD_PHYS'       => '0x46',
            '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??'':'',
            'CALI_RECEPAUTO_JOUR'       => $recepAuto? $RECEPAUTO_JOUR??'':'',
            'ID_EXTERNE'                => $article['ID_EXTERNE']??'', // pour les punchout
            'ID_CAT_ORI'                => $article['ID_CAT'],
        ];

        (new CaLigne($this->pdo))->insert($commande);

        $caracCompl = new CaracCompl($this->pdo, $article['COD_ART'], ($article['COD_SFAM']??''), ($article['CODE_FAM']??''));
        $caracCompl->insertCC('CA', $this->enteteCde['NO_CDE'], (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->enteteCde['NO_CDE'], $idLigne, 'CA_LIGNE');
            $champSupp->insertChampSupp('CA_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
            ];
        }

        $caPlCtEntity = new CaPlCt($this->pdo);

        foreach ($planning as $plann) {
            $caPlCtEntity->insert([
                'NO_CA'     => $this->enteteCde['NO_CDE'],
                'NO_PO_CA'  => $idLigne,
                'DTE_LIV'   => $plann['DTE_LIV'],
                'QTE_COMM'  => $plann['QTE_COMM'],
                'CODE_STE'  => $this->enteteCde['CODE_STE']
            ]);
        }


        /* mettre a jours le montant de la cde avec les valeurs des lignes */
        $totalCde = (new CreationCommande($this->pdo))->getCalculMontantCde($this->enteteCde['NO_CDE']);
        (new CaEntet($this->pdo))->update([
            'TOT_CDE'   => $totalCde['TOT_CDE'],
            'TOT_CDEHT' => $totalCde['TOT_CDEHT'],
            'TOT_TTC'   => $totalCde['TOT_TTC'],
        ], $this->enteteCde['NO_CDE']);
    }
}
