<?php

namespace Modules\Panier\Service;

use Entity\Model\DGeoCtre;
use Entity\Model\Fourniss;
use Entity\Model\OxaUserPanierFour;
use Entity\Model\OxaUserPanierFourClause;
use Entity\Model\OxaUserPanierFourPj;
use Entity\Model\TacClaus;
use Entity\Model\TacPijo;
use Helpers\CaracCompl\CaracCompl;
use Helpers\Fichier\Fichier;
use Helpers\Outil\Sql;
use Modules\Ajax\Repository\Listes;
use Modules\GlobalApplication\Repository\Centre;
use Modules\Panier\Repository\PanierEntete;
use Modules\Panier\Repository\PanierFrs;
use Helpers\Session\ParseBase1;

class PanierFrsService
{
    private \PDO $pdo;

    public function __construct(\PDO $pdo)
    {
        $this->pdo = $pdo;
    }

    /**
     * @param \pdo $pdoOxaFT
     * @param string $idLig
     * @param array<mixed> $ligne
     * @return void
     */
    public function updateFrs(\pdo $pdoOxaFT, string $idLig, $ligne)
    {
        
        (new ReceptionAutoService($this->pdo, $pdoOxaFT))->receptionAutomatique($ligne);
        
        CritereRegroupService::recalculCritereRegroup($this->pdo, $_SESSION['id_panier'], $idLig);

        $cc = new CaracCompl($this->pdo, $ligne['COD_ART'], $ligne['COD_SFAM']);
        $cc->updateCalculatedCc(
            ['PU', 'MNT_LIG_HT', 'MNT_LIG_TTC'],
            'PAN',
            $_SESSION['id_panier'],
            $idLig,
            $_SESSION['id_user'],
            '',
            false,
            ''
        );


        /*
            $listeCs = SqlCs::rqGetValeurEtNumFixDesti('DA_LIGNE', 'ARTFOURN', $codEnr)->TrouveTous();
            foreach($listeCs as $ligneCS){
                $reqCS = SqlCs::rqMajCsFixe($ligneCS['CHP_DESTI'], $id_lig, 'DA_LIGNE', $ligneCS['VALEUR'])->ExecuteSql();
            }
        */
    }

    /**
     * @param array<mixed> $infoBloc
     * @param string|null $codeSte
     * @param string|null $centreLivr
     * @param string|null $centreEmetteur
     * @param string|null $frs
     * @param string $messageErreur
     * @return void
     */
    public function initDoc(
        $infoBloc,
        ?string $codeSte = null,
        ?string $centreLivr = null,
        ?string $centreEmetteur = null,
        ?string $frs = null,
        string &$messageErreur = ''
    ) {
        $listeDoc = (new PanierFrs($this->pdo))->listeDocInit($codeSte, $centreLivr, $centreEmetteur, $frs);
        
        foreach ($listeDoc as $pj) {
            $this->createDoc($pj, true, $frs, $infoBloc['CRITERE_REGROUP'], $messageErreur);
        }
    }

    /**
     * @param array<mixed> $infoBloc
     * @param string $codeSte
     * @param string|null $typeAchat
     * @return void
     */
    public function initPjTypeAchat($infoBloc, string $codeSte, ?string $typeAchat = null, string &$messageErreur = ''):void
    {
        if (sql::paravrac($this->pdo, 'PARAMOXA', 'MULTILNGACTIF') == 'O') {
            $fourniss = (new Fourniss($this->pdo))->find($infoBloc['COD_FOURN'], ['COD_LNG']);
            $langue = $fourniss['COD_LNG']==''? $_SESSION['Session_Langue']:$fourniss['COD_LNG'];
        } else {
            $langue = '';
        }

        if (!$typeAchat) {
            $typeAchat = (new PanierEntete($this->pdo))->getListeTypeAchatByFrs($infoBloc['COD_FOURN']);
            $typeAchat = $typeAchat['TACFOTAC'];
        }

        $listePijo = (new TacPijo($this->pdo))->findAll([
            'TYP_ACH' => $typeAchat,
            'COD_SOC' => $codeSte,
            'COD_LNG' => $langue
        ]);

        foreach ($listePijo as $pj) {
            $this->createDoc($pj, false, $infoBloc['COD_FOURN'], $infoBloc['CRITERE_REGROUP'], $messageErreur);
        }

        (new OxaUserPanierFour($this->pdo))->update([
            'numerique_flg_add_pj' => sql::TRUE
        ], [
            'id_user' => $_SESSION['id_user'],
            'id_panier' => $_SESSION['id_panier'],
            'CRITERE_REGROUP' => $infoBloc['CRITERE_REGROUP']
        ]);
    }

    /**
     * @param array<mixed> $infoBloc
     * @param string $codeSte
     * @param string|null $typeAchat
     * @return void
     */
    public function initClause($infoBloc, string $codeSte, ?string $typeAchat = null):void
    {
        if (sql::paravrac($this->pdo, 'PARAMOXA', 'MULTILNGACTIF') == 'O') {
            $fourniss = (new Fourniss($this->pdo))->find($infoBloc['COD_FOURN'], ['COD_LNG']);
            $langue = $fourniss['COD_LNG']==''? $_SESSION['Session_Langue']:$fourniss['COD_LNG'];
        } else {
            $langue = '';
        }


        if (!$typeAchat) {
            $typeAchat = (new PanierEntete($this->pdo))->getListeTypeAchatByFrs($infoBloc['COD_FOURN']);
            $typeAchat = $typeAchat['TACFOTAC'];
        }
        
        $listeClause = (new TacClaus($this->pdo))->findClause($typeAchat, $codeSte, $langue);

        foreach ($listeClause as $clause) {
            (new OxaUserPanierFourClause($this->pdo))->insert([
                'id_user'           => $_SESSION['id_user'],
                'id_panier'         => $_SESSION['id_panier'],
                'CRITERE_REGROUP'   => $infoBloc['CRITERE_REGROUP'],

                'COD_FOURN'             => $infoBloc['COD_FOURN'],
                'CONTENU'               => $clause['CONTENU'],
                'TYP_ACH'               => $typeAchat,
                'numerique_VERROU'      => sql::setBoolSql(Sql::boolSql($clause['VERROU'])),
                'numerique_CLAU_FIX'    => sql::setBoolSql(Sql::boolSql($clause['CLAU_FIX'])),
            ]);
        }

        (new OxaUserPanierFour($this->pdo))->update([
            'numerique_flg_add_clause' => sql::TRUE
        ], [
            'id_user' => $_SESSION['id_user'],
            'id_panier' => $_SESSION['id_panier'],
            'CRITERE_REGROUP' => $infoBloc['CRITERE_REGROUP']
        ]);
    }

    /**
     * @param array<mixed> $pj
     * @param bool $issuDoc
     * @param string|null $codeFrs
     * @param string|null $critereRegroup
     * @return bool
     */
    public function createDoc($pj, $issuDoc, $codeFrs, $critereRegroup, string &$messageErreur = '')
    {
        
        if (Sql::boolSql($pj['USE_CGA']??false)) {
            $file_dir = $pj['NOM_FIC'];
            $fileConvert = $pj['FIC_PDF'];
        } else {
            $pj['NOM_FIC_system'] = str_replace("\\", '/', $pj['NOM_FIC']);
            
            $cheminSource = (new ParseBase1())->getRep()->pj . $pj['NOM_FIC'];
            $pathInfo = pathinfo($pj['NOM_ORI']);

            $saveFile       = fichier::moveDocPanier($this->pdo, $cheminSource, $pathInfo['basename']);
            $file_dir       = $saveFile['file_dir'];
            $fileConvert    = $saveFile['file_convert'];
            $pj['NOM_ORI']  = $pathInfo['basename'];

            if ($saveFile['error']) {
                $messageErreur .= '- ' . $pj['TITRE'] . "\n";
                return false;
            }
        }

        $arrayInsert = [
            'id_user'           => $_SESSION['id_user'],
            'id_panier'         => $_SESSION['id_panier'],
            'COD_FOURN'         => $codeFrs,
            'CRITERE_REGROUP'   => $critereRegroup ?? '',
            'TITRE'             => $pj['TITRE'],
            'PJ_TYPES'          => $pj['TYPE_PJ'],
            'nom_piece_user'    => $pj['NOM_ORI'],
            'nom_piece_sys'     => $file_dir,
            'FIC_PDF'           => $fileConvert,
        ];

        if ($issuDoc) {
            $arrayInsert += [
                'numerique_PHYSIQUE'        => '0x54',
                'numerique_OUVRABLE'        => '0x54',
                'numerique_IMPRIMABL'       => '0x54',
                'numerique_VERROU'          => '0x46',
                'numerique_USE_CGA'         => '0x46',
                'TYP_ACH'                   => '',
                'numerique_ISSU_DOCATT'     => '0x54',
                'TABLE_DOCATT'              => $pj['NO_DA'],
                'numerique_LIEN_FICHIER'    => '0x46',
            ];
        } else {
            $arrayInsert += [
                'numerique_PHYSIQUE'    => sql::setBoolSql(Sql::boolSql($pj['LECTURE'])),
                'numerique_OUVRABLE'    => sql::setBoolSql(Sql::boolSql($pj['IMP_PJ'])),
                'numerique_IMPRIMABL'   => sql::setBoolSql(Sql::boolSql($pj['IMP_TITRE'])),
                'numerique_VERROU'      => sql::setBoolSql(Sql::boolSql($pj['VERROU'])),
                'numerique_USE_CGA'     => sql::setBoolSql(Sql::boolSql($pj['USE_CGA'])),
                'TYP_ACH'               => $pj['TYP_ACH']??'',
                'numerique_ISSU_DOCATT' => '0x46',
                'TABLE_DOCATT'          => '',
                'numerique_LIEN_FICHIER'=> sql::setBoolSql(Sql::boolSql($pj['USE_CGA'])),
            ];
        }

        (new OxaUserPanierFourPj($this->pdo))->insert($arrayInsert);
        return true;
    }

    public function updateAdresseCommandeByCentre(string $centre, bool $update = false):void
    {
        if ($update) {
            $decoupageExist = (new DGeoCtre($this->pdo))->find(['CODE_CTR' => $centre], ['COUNT(*) countZoneGeo'])['countZoneGeo']??'0';
            if (!$decoupageExist) {
                return;
            }
        }
        
        $liste = new Listes($this->pdo);
        $zoneCentre = $liste->calculZoneGeoCentre($centre);

        $listeBlocFrs = (new PanierFrs($this->pdo))->getAdresseFrsByBloc();

        $paramAdrFouInit = Sql::paravrac($this->pdo, 'OXAPROC', 'ADRCDEFOUR_INITDEFAUT') != 'N';
        $paramCtc = Sql::paravrac($this->pdo, 'PARAMGEN', 'CHOIX_INIT_FAXMAILFOUR_SUR_CDE') == 'O';

        foreach ($listeBlocFrs as $frs) {
            $post = [
                'filter_egal_CODE' => $frs['COD_FOURN'],
                'ADR_COMMANDE'   => '0x54',
            ];

            $liste = new Listes($this->pdo);
            $zoneGeoCentre = $liste->listeZoneGeoCentre($centre);
            $listeAdresse = $liste->adresseFournisseur($post, $zoneGeoCentre, false, $frs);
            if ($listeAdresse) {
                // si l'adresse existe, on ne va pas re-update la date déjà présente
                return;
            }

            $adresseFrsinit = CritereRegroupService::getAdresseFrs($this->pdo, $zoneCentre, $post, $frs, $paramAdrFouInit);

            $arrayAdresse = [
                'CODE_PAYS'                 => $adresseFrsinit['CODE_PAYS']??'',
                'CPOSTAL'                   => $adresseFrsinit['CPOSTAL']??'',
                'VILLE1'                    => $adresseFrsinit['VILLE1']??'',
                'ADR'                       => $adresseFrsinit['ADR']??'',
            ];

            // TODO : oxa_users_panier_four.CTC_FAX does not exist, maybe another talbe need to be updated
            // if ($paramCtc) {
            //     $arrayAdresse['CTC_FAX']    = $adresseFrsinit['FAX']??'';
            //     $arrayAdresse['CTC_MAIL']   = $adresseFrsinit['EMAIL']??'';
            // }

            (new OxaUserPanierFour($this->pdo))->update($arrayAdresse, [
                'id_panier' => $_SESSION['id_panier'],
                'id_user' => $_SESSION['id_user'],
                'CRITERE_REGROUP' => $frs['CRITERE_REGROUP']
            ]);
        }
    }

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

    /**
     * @param string $centreZoneGeo
     * @param string $codeFournisseur
     * @param array<mixed> $adresseSearch
     * @return array<mixed>
     */
    public function adresseCommande(string $centreZoneGeo, string $codeFournisseur, $adresseSearch = [])
    {
        $listes = new Listes($this->pdo);
        $centre = new Centre($this->pdo);

        if ($this->bufferZoneGeoCentre[$centreZoneGeo]??[]) {
            $zoneGeoCentre = $this->bufferZoneGeoCentre[$centreZoneGeo];
        } else {
            $zoneGeoCentre = $centre->ListeZoneGeoCentre((string)$centreZoneGeo);
            $this->bufferZoneGeoCentre[$centreZoneGeo] = $zoneGeoCentre;
        }
        $adresseFound = $listes->adresseFournisseur([
            'ADR_COMMANDE' => '0x54',
            'filter_egal_CODE' => $codeFournisseur,
            'tri_CPOSTAL' => 'asc',
        ], $zoneGeoCentre, false, $adresseSearch);

        return $adresseFound;
    }
}
