<?php

namespace Modules\Commande\Service;

use Entity\Model\Centre;
use Entity\Model\CaEntet;
use Entity\Model\Country;
use Entity\Model\Fourniss;
use Helpers\Outil\Sql;
use Helpers\Trad\ITrad;
use Modules\Commande\Repository\CreationCommande;
use Modules\GlobalApplication\Outil\InitAxesImpCde;

class GenerateLigneCdeService
{
    /**
     * @var \PDO $pdo
     */
    public $pdo;

    /**
     * @var \PDO $pdoOxaFT
     */
    public $pdoOxaFT;

    /**
     * @var array<mixed> $entete
     */
    public $entete;

    /**
     * @var array<mixed> $paysEntete
     */
    public $paysEntete;

    /**
     * @var array<mixed> $paysInstall
     */
    public $paysInstall;

    /**
     * @var array<mixed> $centreEntete
     */
    public $centreEntete;

    /**
     * @var array<mixed> $paramTVA
     */
    public $paramTVA;

    /**
     * @var array<mixed> $paysCtrLiv
     */
    public $paysCtrLiv;

    /**
     * @var array<mixed> $fourniss
     */
    public $fourniss;

    /**
     * @var InitAxesImpCde $initAxesIlputation
     */
    public $initAxesIlputation;

    public ITrad $trad;

    public function __construct(\PDO $pdo, \PDO $pdoOxaFT, string $idCde, ITrad $trad, InitAxesImpCde $initAxesIlputation)
    {
        $this->pdo = $pdo;
        $this->pdoOxaFT = $pdoOxaFT;
        $this->trad = $trad;

        $caEntet = new CaEntet($this->pdo);
        $this->entete = $cde = $caEntet->find($idCde);
        $this->fourniss = (new Fourniss($this->pdo))->find($cde['CODE_FOU'], ['RMINCPXN']);
        if (empty($cde)) {
            throw new \Exception('Invalid commande #'.$idCde);
        }

        $centreEntity = new Centre($this->pdo);
        $countryEntity = new Country($this->pdo);

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

        $this->paysEntete = $countryEntity->find($cde['PAYCDEFO'], ['AV_TAXLOC', 'TVA', 'PAYSCEE']);
        $this->paysInstall = $countryEntity->find($paramPaysInstall, ['CODE_PAYS', 'PAYSCEE']);
        $this->centreEntete = $centreEntity->find($cde['CTR_LIV'], ['TX_TAXLOC']);
        $this->paysCtrLiv = $countryEntity->find($cde['PAY_LIV'], ['AV_TAXLOC', 'TVA', 'PAYSCEE']);
        $this->initAxesIlputation = $initAxesIlputation;

        $this->paramTVA = [
            'regle' => Sql::paravrac($this->pdo, 'PARAMGEN', 'REGINIT_TVA'),
            'TVA'   => Sql::parametr($this->pdo, 'TX_TVA'),
        ];
    }

    /**
     * @param array<mixed> $DA
     * @return string
    */
    public function calculAcdDaToCde($DA)
    {
        // Calcul Accord-cadre
        if (($DA['CODE_ACD']??'') != '' && ($DA['DATE_DEB'] <= date('Ymd') && ($DA['DATE_FIN'] >= date('Ymd') || $DA['DATE_FIN'] == '00000000') )) {
            $acd = $DA['CODE_ACD'];
        } else {
            $creationCommandeRepo = new CreationCommande($this->pdo);
            $acd = $creationCommandeRepo->getAccordCadre(($DA['CODE_ART']??''), $this->entete['CTR_EMETT'], $this->entete['CTR_LIV'], $this->entete['CODE_STE'], $this->entete['CODE_FOU']);
            $acd = $acd['CODE_ACD']??'';
        }

        return $acd;
    }

    /**
     * @param mixed $idLigne
     * @param array<mixed> $DA
     * @param array<mixed> $saisie
     * @return array<mixed>
     * TODO NE PAS TOUCHER
    */
    public function calculeChampsCdeParDa(string $context, $idLigne, $DA, $saisie = [], bool $insert = true, string $remiseEntete = '')
    {
        $artFourn = [];
        $acd = '';
        $ref = '';
        $saisieRec = '';
        $prix = '';
        $remise = '';
        $origine = '';
        $ID_CAT_ORI = '';
        $remise = '';

        $tempInit = $DA['TEMPINIT']??'';
        $explodTempInit = explode('|', $tempInit);

        if ($context == 'gareDeTriage') {
            $prix = $saisie[$DA['NO_DA']][$DA['NO_PO']]['PU'];
            $remise = $saisie[$DA['NO_DA']][$DA['NO_PO']]['TX_REMISE'];
            $acd = $saisie[$DA['NO_DA']][$DA['NO_PO']]['ACD'];
            $qte = $saisie[$DA['NO_DA']][$DA['NO_PO']]['QTE'];
            $origine = $saisie[$DA['NO_DA']][$DA['NO_PO']]['PROVENANCE'];
            $ID_CAT_ORI = $saisie[$DA['NO_DA']][$DA['NO_PO']]['ID_CAT_ORI'];
        } elseif (($DA['CODE_ART']??'') != '') {
            $DA['QTE'] = $DA['QTE_DEM'] - $DA['DEJA_COMM'];

            $initPrix = Sql::paravrac($this->pdo, 'PARAMGEN', 'TYPE_INIT_PRIX_DA_CDE');
            if ($initPrix == 2) {
                $prix       = $DA['PU'];
                $remise     = $DA['TX_REMISE'];
                $acd        = $DA['ACD'];
                $origine    = '';
                $qte        = $DA['QTE_DEM'] - $DA['DEJA_COMM'];
                $ID_CAT_ORI = $DA['ID_CAT_ORI'];
                $remiseEntete = 0;
            } else {
                $creationCdeService = new CreationCommandeService($this->pdo, $this->pdoOxaFT, $this->trad);
                $bestPrix = $creationCdeService->getbestPrix($this->entete, $DA, true);
    
                $prix       = $bestPrix['PU'];
                $remise     = $bestPrix['TX_REMISE'];
                $acd        = $bestPrix['ACD'];
                $origine    = $bestPrix['PROVENANCE'];
                $qte        = $DA['QTE_DEM'] - $DA['DEJA_COMM'];
                $ID_CAT_ORI = $bestPrix['ID_CAT'];
    
                if (!$prix && ($DA['PU'] ?? false)) {
                    $prix   = $DA['PU'];
                    $remise = ($DA['TX_REMISE']??'');
                }
            }
        } else {
            $prix   = ($DA['PU']??'');
            $remise = ($DA['TX_REMISE']??'');
            $acd    = $this->calculAcdDaToCde($DA);
            
            $qte    = ($DA['QTE_DEM']??0) - ($DA['DEJA_COMM']??0);

            $initPrix = Sql::paravrac($this->pdo, 'PARAMGEN', 'TYPE_INIT_PRIX_DA_CDE');
            if ($initPrix == 2) {
                $remiseEntete = 0;
            }
        }
        
        // calcul info article
        if (($DA['CODE_ART']??'') != '') {
            if ($DA['INFO_ART'] == 'ARTFOURN') {
                $artFourn = [
                    'POIDS'         => $DA['ARTFOURN_POIDS'],
                    'LONGU'         => $DA['ARTFOURN_LONGU'],
                    'LARG'          => $DA['ARTFOURN_LARG'],
                    'HAUT'          => $DA['ARTFOURN_HAUT'],
                    'VOLUME'        => $DA['ARTFOURN_VOLUME'],
                    'PAY_ORI'       => $DA['ARTFOURN_PAY_ORI'],
                    'PAY_PRO'       => $DA['ARTFOURN_PAY_PROV'],
                    'POIDSNET'      => $DA['ARTFOURN_POIDSNET'],
                ];
            } elseif ($DA['INFO_ART'] == 'ARTGF') {
                $artFourn = [
                    'POIDS'         => $DA['ARTGF_POIDS'],
                    'LONGU'         => $DA['ARTGF_LONGU'],
                    'LARG'          => $DA['ARTGF_LARG'],
                    'HAUT'          => $DA['ARTGF_HAUT'],
                    'VOLUME'        => $DA['ARTGF_VOLUME'],
                    'PAY_ORI'       => $DA['ARTGF_PAY_ORI'],
                    'PAY_PRO'       => $DA['ARTGF_PAY_PROV'],
                    'POIDSNET'      => $DA['ARTGF_POIDSNET'],
                ];
            }
        }

        if (isset($DA['CODE_FOU'])) {
            $fou = $DA['CODE_FOU'];
        } elseif (isset($DA['FOU'])) {
            $fou = $DA['FOU'];
        } else {
            $fou = '';
        }
        
        if ($this->entete['CODE_FOU'] == $fou) {
            if ($DA['ARTGF_REF_FOURN'] != '') {
                $ref = $DA['ARTGF_REF_FOURN'];
            } elseif ($DA['ARTFOURN_REF_FOURN'] != '') {
                $ref = $DA['ARTFOURN_REF_FOURN'];
            } else {
                $ref = $DA['REF_FOUR'];
            }
        } else {
            $ref = '';
        }

        //Calcul SAISIEREC
        if (($DA['SITE_STK']??'') != '' || (($DA['CODE_ART']??'') == '' && !Sql::boolSql(($DA['SSFAMILL_NONRECEPT']??false))) || ($DA['CODE_ART'] != '' && !Sql::boolSql(($DA['ARTICLE_NONRECPT']??false)))) {
            $saisieRec = '0x54';
        } else {
            $saisieRec = '0x46';
        }
        
        //calcul imputation
        $imputations = $this->initAxesIlputation->getInitImputation([
            'CODE_ART' => $DA['CODE_ART'] ?? '',
            'SousFamille' => [
                'CODE_SFA' => $DA['SSFAM'] ?? '',
                'CODE_FAM' => $DA['CODE_FAM'] ?? '',
            ],
        ] + $DA);

        //calcul TVA

        if (sql::boolSql($this->paysEntete['AV_TAXLOC']) && $DA['CODE_ART'] != '' && ( sql::boolSql($DA['ARTICLES_AV_TXLOC']) || sql::boolSql($DA['SSFAMILL_AV_TAXLOC']))) {
            if ($this->entete['CODE_FOU'] == $DA['CODE_FOU'] && $this->entete['CTR_LIV'] == $DA['CTRLIVR']) {
                $tva = $DA['TVA'];
            } else {
                $tva = $this->centreEntete['TX_TAXLOC'];
            }
        } else {
            if ($this->paramTVA['regle'] == 'T') {
                $tva = $this->paysCtrLiv['TVA'];
            } elseif (($this->entete['PAYCDEFO'] == $this->paysInstall['CODE_PAYS']) || (sql::boolSql($this->paysEntete['PAYSCEE']) && sql::boolSql($this->paysInstall['PAYSCEE']))) {
                $tva = ($DA['TVA']??'');
            } else {
                $tva = $this->paramTVA['TVA'];
            }
        }
        
        $explodTempInit = explode('|', ($DA['TEMPINIT']??''));
        $prixTempInit = $explodTempInit[0];
        
        if (!(float)$remise) {
            $remise = $remiseEntete;
        }

        if (sql::boolSql($this->fourniss['RMINCPXN'])) {
            $prix = floatval($prix) * (1-(floatval($remise)/100));
            $remise = 0;
        }

        if (floatval($prixTempInit) != $prix) {
            $TEMPINIT = $prix.'|'.$remise.'|'.date('d/m/Y').'|'.$origine;
        } else {
            $TEMPINIT = ($DA['TEMPINIT']??'');
            $ID_CAT_ORI = $DA['ID_CAT_ORI']??'';
        }

        $commande = [
            'NO_CDE'                    => $this->entete['NO_CDE'],
            'NO_PO'                     => $idLigne,
            'CODE_ART'                  => ($DA['CODE_ART']??''),
            'DES_SOMM'                  => ($DA['DES_SOMM']??''),
            'SSFAM'                     => ($DA['SSFAM']??''),
            'PU'                        => $prix,
            'TVA'                       => $tva,
            'REMISE'                    => $remise,
            'QTE_COMM'                  => $qte??($DA['QTE_DEM']??''),
            'UNITE'                     => ($DA['UNITE']??''),
            'RAL'                       => ($DA['QTE_DEM']??''),
            'DTELIVCON'                 => ($DA['DTELIVSOU']??''),

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

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

            'REF_FOUR'                  => $ref??'',
            'COD_FAB'                   => ($DA['COD_FAB']??''),
            'COD_GAM'                   => ($DA['COD_GAM']??''),
            'REF_FAB'                   => ($DA['REF_FAB']??''),
            
            'numerique_SOLD_PHYS'       => '0x46',
            'numerique_RECEP_AUTO'      => Sql::setBoolSql(sql::boolSql(($DA['RECEP_AUTO']??false))),
            'DATEDEBCONT'               => ($DA['DATEDEBCONT']??''),
            'DATEFINCONT'               => ($DA['DATEFINCONT']??''),
            'CONTRAT_PERIOD'            => ($DA['CONTRAT_PERIOD']??''),
            'FIN_DEB_PER'               => ($DA['FIN_DEB_PER']??''),
            'CALI_RECEPAUTO_JOUR'       => ($DA['DALI_RECEPAUTO_JOUR']??''),
            'ID_EXTERNE'                => ($DA['ID_EXTERNE']??''),
            'ID_CAT_ORI'                => $ID_CAT_ORI,
        ];

        if ($insert) {
            $commande['NM_DCOMP'] = Sql::updateMemo($this->pdo, '', ($DA['DES_COMPL']??''));
        } else {
            $commande['DES_COMPL'] = $DA['DES_COMPL']??'';
        }

        return $commande;
    }
}
