<?php

namespace Modules\RechercheArticles\Service;

use Entity\Model\Articles;
use Entity\Model\Cataproc;
use Entity\Model\DaLibre;
use Entity\Model\Famille;
use Entity\Model\HistoCde;
use Helpers\ChampsSupplementaire\ChampSupp;
use Helpers\Outil\Sql;
use Modules\Panier\Service\PanierLigneService;
use Modules\Panier\Service\RequeteArticle;
use Modules\RechercheArticles\Repository\Article;
use Helpers\Parametres\Constante;
use Helpers\Trad\ITrad;
use Helpers\Trad\Trad;

class ArticleService
{

    /**
     * @var \PDO $pdo
     */
    private $pdo;

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

    /**
     * @var string $table
     */
    private $table;

    /**
     * @var string $rowCompteur
     */
    private $rowCompteur;

    /**
     * @var Cataproc|HistoCde|DaLibre $repo
     */
    private $repo;

    /**
     * @var array<mixed> $article
     */
    private $article;

    /**
     * @param string $table
     */
    public function __construct(\PDO $pdo, \PDO $pdoOxaFT, $table)
    {
        $this->pdo = $pdo;
        $this->pdoOxaFT = $pdoOxaFT;
        
        if ($table == 'CAT') {
            $this->repo = new Cataproc($this->pdoOxaFT);
            $this->table = 'CATAPROC';
        } elseif ($table == 'HISTO') {
            $this->repo = new HistoCde($this->pdoOxaFT);
            $this->table = 'HISTOCDE';
        } elseif ($table == 'ART' || $table == 'SSF') {
            $this->repo = new DaLibre($this->pdoOxaFT);
            $this->table = 'DALIBRE';
        }
    }

    /**
     * @param string $rowCompteur
     */
    public function setRowCompteur($rowCompteur): void
    {
        $this->rowCompteur = $rowCompteur;
    }

    /**
     * @param array<mixed>|null $listeChamps
     * @return array<mixed>
     */
    public function getArticle(ITrad $trad, &$listeChamps = [], bool $ficheArt = false)
    {
        $outilRechercheService = new OutilRechercheService($this->pdo);
        $outilRechercheService->initRequeteArticle($this->pdoOxaFT);
        
        if ($_SESSION['STATUT_RECH_ART'] == -1) {
            return [];
        }
        $this->article = $this->repo->find($this->rowCompteur);

        if ($this->table == 'DALIBRE') {
            $outilRechercheService->majRecordGen($this->article);

            $famille = new Famille($this->pdo);
            $this->article['DESIGNFAM'] = $famille->find($this->article['CODE_FAM'], ['DESIGNAT'])['DESIGNAT'];
        }

        $outilRechercheService->majRecord($this->article, $this->pdoOxaFT);

        $qteCond = 1;
        if ((float)$this->article['CONDITNT'] && $this->article['TXTCOND']) {
            $qteCond = (float)$this->article['CONDITNT'];
        }

        if ($qteCond) {
            $this->article['PX_ART'] = (float)$this->article['PX_ART']*$qteCond;
        }
        
        $repoCs = new ChampSupp($this->pdo);
        foreach ($listeChamps as $key => &$champs) {
            if ($champs['CODE_CHP'] == 'TXTVA') {
                $champs['CODE_CHP'] = 'TAUX_TVA';
            } elseif ($champs['CODE_CHP'] == 'ZONEALPHA') {
                unset($listeChamps[$key]);
            } elseif ($champs['CODE_CHP'] == 'PX_ART_TTC') {
                if (Sql::paravrac($this->pdo, 'OXAPROC', 'AFFTTC') == 'O') {
                    $this->article['PX_ART_TTC'] = number_format($this->article['PX_ART'] * (1 + $this->article['TAUX_TVA'] / 100), Constante::PUDECIMAL, '.', '');
                } else {
                    $this->article['PX_ART_TTC'] = $this->article['PX_ART'];
                }
            } elseif (strpos($champs['CODE_CHP'], 'CS|') === 0) {
                $infoCS = explode('|', $champs['CODE_CHP']);
                $this->article[$champs['CODE_CHP']] = $repoCs->getInfoValueCs('ARTICLE', $this->article['COD_ART'], $infoCS[1])['VALEUR'] ?? '';
            }
        }

        /*if ($this->article['TXTCOND']) {
            if ($this->article['CONDITNT'] != 0 && $this->article['CONDITNT'] != 1) {
                $text = Trad::strBuild($trad->t('@1@ de @2@ à (@3@)'), $this->article['TXTCOND'], (number_format($this->article['CONDITNT'], 2, '.', ' ').' '.$this->article['COD_UNIT']), number_format($this->article['PX_ART']/$qteCond, Constante::PUDECIMAL, '.', ' ').' '.$this->article['DEVISE'].' / '.$this->article['COD_UNIT']);
                $this->article['libprix'] = $text;
            } else {
                $this->article['libprix'] = $this->article['TXTCOND'];
            }
        }*/
        $result     = PanierLigneService::calculePrixUnite($this->article, $this->article['PX_ART'], $this->article['TAUX_TVA'], Sql::paravrac($this->pdo, 'OXAPROC', 'AFFTTC') == 'O', Constante::PUDECIMAL);
        $this->article['libprix'] = $result['unite'];

        $articleRepo        = new RequeteArticle($this->pdo, $this->pdoOxaFT, '');
        /* Gestion des prix degressif */
        if ($this->article['PRIXDEGRESSIF']) {
            $this->article['PRIXDEGRESSIF_VAL'] = $articleRepo->getListePrixDegressif($this->article, Sql::paravrac($this->pdo, 'OXAPROC', 'AFFTTC') == 'O', (float)$this->article['TAUX_TVA']);
        }

        return $this->article;
    }

    /**
     * @param array<mixed> $arrayUpdate
     * @param string|int $id
     */
    public function updateArticle($arrayUpdate, $id): void
    {
        $this->repo->update($arrayUpdate, $id);
    }

    /**
     * @return array<mixed>
     */
    public function getDocArticle()
    {
        $article = new Article($this->pdo);
        $listeDoc = $article->getListeDocArticle($this->article['COD_ART']);

        return $listeDoc;
    }
    
    /**
     * RechercheArtFrs V1
     * @param  array<mixed> $article
     * @return array<mixed>
     */
    public function rechercheArtFrs($article, string $clause = '', ?string $forceFrs = null, bool $ignoreGenerique = false)
    {
        $req = "select 
                    *
                from $this->table with (nolock) 
                where 1=1";

        $arrayReq = [];
        $reqArt = [];
        if (($article['COD_FAB']??'') != '' && $article['REF_FAB'] != '') {
            $reqArt[] = " (COD_FAB = :codeFab and REF_FAB = :refFab) ";

            $arrayReq[':codeFab'] = $article['COD_FAB'];
            $arrayReq[':refFab'] = $article['REF_FAB'];
        }
        
        if (($article['REF_FOURN']??'') != '' && ($article['COD_GRP']??'') != '') {
            $reqArt[]  = " (REF_FOURN=:refFourn and REGRFOUR = :codGrp) ";
            $arrayReq[':refFourn'] = $article['REF_FOURN'];
            $arrayReq[':codGrp'] = $article['COD_GRP'];
        } elseif (($article['REF_FOURN']??'') != '') {
            $reqArt[]  = " (REF_FOURN=:refFourn and COD_FOURN = :codeFourn) ";
            $arrayReq[':refFourn'] = $article['REF_FOURN'];
            $arrayReq[':codeFourn'] = $article['COD_FOURN'];
        }

        if ($article['COD_ART'] != '') {
            $articleEntity = new Articles($this->pdo);
            $infoArt = $articleEntity->find($article['COD_ART']);
            
            if (($infoArt != '' && !Sql::boolSql($infoArt['GENRERIQUE'])) || $ignoreGenerique) {
                $reqArt[]  = " COD_ART = :codeArt ";
                $arrayReq[':codeArt'] = $article['COD_ART'];
            }
        }

        if ($reqArt) {
            $implodeReq = implode(' or', $reqArt);
            $whereArt = " and ( ".$implodeReq." )";

            $req .= $whereArt;
        } else {
            $req .= " and 1=0 ";
        }
        
        $req .= $clause;

        if (($article['ID_CAT']??'') != '') {
            $req .= " and ID_CAT = :idCat ";
            $arrayReq[':idCat'] = $article['ID_CAT'];
        }

        
        if ($forceFrs) {
            $req .= " and (COD_FOURN =:codFournForcer or TYPECATA = 'M')";
            $arrayReq[':codFournForcer'] = $forceFrs;
        }

        $req .= "
            AND (DATEPUB   <= '".date('Ymd')."' OR DATEPUB = '00000000')    
            AND (VALIDCATA >= '".date('Ymd')."' OR VALIDCATA = '00000000')   
        ";
        
        $req .= " order by RS_FOURN";

        $requete = $this->pdoOxaFT->prepare($req);
        $requete->execute($arrayReq);

         //! requete no_fetchAssocOne
        $return = $requete->fetchAll($this->pdoOxaFT::FETCH_ASSOC);

        if ($return) {
            return $return;
        } else {
            return [];
        }
    }
}
