<?php

namespace Modules\ProjetAchat\Service;

use Entity\Model\DoaStruct;
use Helpers\Outil\Sql;
use Modules\ProjetAchat\Repository\BibliothequeDonnee;
use Entity\Model\DoaData;
use Modules\ProjetAchat\Repository\Donnee;

class ChampService
{
  
    private $pdo;
    private $ChampRepository;
    private $heritageService;


    public function __construct(\PDO $pdo)
    {
        $this->pdo = $pdo;
        $this->ChampRepository = new \Modules\ProjetAchat\Repository\Champ($this->pdo);
        $this->heritageService = new \Modules\ProjetAchat\Service\HeritageService($this->pdo);
    }


    public function supprimerData(int $idData, string $typeObjet, int $idObjet, int $postHeritage = 2) : void
    {

        if ($data = $this->ChampRepository->getInfoData($idData, $typeObjet, $idObjet)) {
            $typeObjet  = $data['TYPE_OBJET'];
            $idObjet    = $data['ID_OBJET'];
            $idDonnee   = $data['ID_DONNEE'];

            if (\Helpers\Outil\Sql::boolSql($data['ID_OBJET_DATA']) && $data['ID_DATA_LIEE'] == 0) {
                if ($listeData = $this->ChampRepository->getDataLink($data['TYPE_OBJET'], $data['ID_OBJET'], $data['ID_DONNEE'], $idData)) {
                    foreach ($listeData as & $ligne) {
                        $this->heritageService->supprimeHeritage($ligne['TYPE_OBJET'], $ligne['ID_OBJET'], $ligne['ID_DONNEE'], $ligne['ID_DATA'], $postHeritage);
                    }
                }
            }
            
            $this->heritageService->supprimeHeritage($typeObjet, $idObjet, $idDonnee, $idData, $postHeritage);
        }
    }

    public function insertStructureHeritage(string $oldTypeObject, int $oldIdObject, string $typeObjet, int $idObjet, int $idCatCible, int $idDonnee, string $dataName, string $descr, string $multiple, string $LIE_A_OBJET, string $objet) :void
    {
        $this->rqInsertDoaStruct($typeObjet, $idObjet, $idCatCible, $idDonnee, $dataName, $descr, $multiple, $LIE_A_OBJET, $objet);
        $retourCreat = $this->getRightId($typeObjet, $idObjet);
        
        $doaDataEntity = new DoaData($this->pdo);
        
        if ($retourCreat) {
            $bibliothequeRepo = new BibliothequeDonnee($this->pdo);
            $listeChamps = $bibliothequeRepo->getListeDonneOrderById($oldTypeObject, $oldIdObject, $idDonnee);
            
            foreach ($listeChamps as $champs) {
                $this->ajoutDataVersObjet($champs, $typeObjet, $idObjet, $retourCreat);
            }
            
            $listFieldsCalculated = $this->ChampRepository->getFieldsCalculated($typeObjet, $idObjet, $retourCreat);
            foreach ($listFieldsCalculated as $fields) {
                $this->heritageService->convertCalculatedFields($typeObjet, $idObjet, $retourCreat, $fields);
                
                $doaDataEntity->update([
                    'EXP_CALCUL' => $fields['EXP_CALCUL'],
                    'numerique_ERREUR_CALCUL' => $fields['ERREUR_CALCUL'],
                ], $fields['ID_DATA']);
            }
        }
    }
    
    public function rqInsertDoaStruct(string $typeObjet, int $idObjet, int $idCatCible, int $idStruct, string $dataName, string $descr, string $multiple, string $LIE_A_OBJET, string $objet) : void
    {
        $donneeRepo = new Donnee($this->pdo);
        $doaStruct = new DoaStruct($this->pdo);
        if ($idStruct != 0) {
            $reqDonnee = $doaStruct->find($idStruct);
            if ($reqDonnee['TYPE_OBJET'] != 'B') {
                $idStruct = $reqDonnee['ID_STRUCT'];
            }
        }

        $doaStruct->insert([
            'TYPE_OBJET' => $typeObjet,
            'ID_OBJET' => $idObjet,
            'ID_CAT' => $idCatCible,
            'ID_STRUCT' => $idStruct,
            'NOM_DONNEE' => $dataName,
            'DESCR' => $descr,
            'numerique_MULTIPLE' => Sql::toBool($multiple)? '0x54':'0x46',
            'numerique_LIE_A_OBJET' => Sql::toBool($LIE_A_OBJET)? '0x54':'0x46',
            'OBJET' => $objet,
            'NUM_ORDRE' => ( (int)$donneeRepo->getRightOrder($idCatCible)) +1,
        ]);
    }
    
    public function getRightId(string $typeObjet, int $idObjet) : int
    {
        return (int) $this->ChampRepository->rqGetLastIdFromDonne($typeObjet, $idObjet);
    }
    
    /**
     * @param array<string> $data
     */
    public function ajoutDataVersObjet(array $data, string $typeObjet, int $idObjet, int $idDonnee) : void
    {
        if ($data['ID_DATA_LIEE'] > 0) {
            if ($data['TYPE_OBJET'] == 'B') {
                $dataLieeCible = $this->ChampRepository->getDataOriginLink($typeObjet, $idObjet, $idDonnee, $data['ID_DATA_LIEE']);
                if ($dataLieeCible) {
                    $newIdDataLiee = $dataLieeCible['ID_DATA'];
                } else {
                    $newIdDataLiee = null;
                }
            } else {
                $dataLieeCible = $this->ChampRepository->getInfoData($data['ID_STRUCT'], 'B', '0');
                if ($dataLieeCible) {
                    $idDataLiee = $dataLieeCible['ID_DATA_LIEE'];
                    
                    $dataLieeCible = $this->ChampRepository->getDataOriginLink($typeObjet, $idObjet, $idDonnee, $idDataLiee);
                    if ($dataLieeCible) {
                        $newIdDataLiee = $dataLieeCible['ID_DATA'];
                    } else {
                        $newIdDataLiee = null;
                    }
                } else {
                    $newIdDataLiee = null;
                }
            }
        } else {
            $newIdDataLiee = 0;
        }
        
        if (! is_null($newIdDataLiee)) {
            $majDb = false;
            if ($data['DATA_LIE_A_OBJ'] && $newIdDataLiee != 0) {
                $dataRecherche = $this->ChampRepository->searshDataLinkObjet($typeObjet, $idObjet, $idDonnee, $newIdDataLiee, $data['CHAMP_OBJET_DATA']);
                if ($dataRecherche) {
                    $dataRecherche = $this->ChampRepository->updateDataLinkObjet($typeObjet, $idObjet, $idDonnee, $newIdDataLiee, $data['CHAMP_OBJET_DATA'], ($data['TYPE_OBJET'] == 'B' ? $data['ID_DATA'] : $data['ID_STRUCT']), $data['TAG_MERGE']);
                    $majDb = true;
                }
            }
            
            if (!$majDb) {
                $doaDataEntity = new DoaData($this->pdo);
                $doaDataEntity->insert([
                    'TYPE_OBJET'                => $typeObjet,
                    'ID_OBJET'                  => $idObjet,
                    'ID_DONNEE'                 => $idDonnee,
                    'NUM_ORDRE'                 => $data['NUM_ORDRE'],
                    'NOM_DATA'                  => $data['NOM_DATA'],
                    'numerique_LIE_A_OBJET'     => Sql::toBool($data['LIE_A_OBJET'])? '0x54':'0x46',
                    'OBJET'                     => $data['OBJET'],
                    'numerique_FLAG_ID_OBJET'   => Sql::toBool($data['FLAG_ID_OBJET'])? '0x54':'0x46',
                    'numerique_DATA_LIE_A_OBJ'  => Sql::toBool($data['DATA_LIE_A_OBJ'])? '0x54':'0x46',
                    'OBJET_DATA'                => $data['OBJET_DATA'],
                    'numerique_ID_OBJET_DATA'   => Sql::toBool($data['ID_OBJET_DATA'])? '0x54':'0x46',
                    'ID_DATA_LIEE'              => $newIdDataLiee,
                    'CHAMP_OBJET_DATA'          => $data['CHAMP_OBJET_DATA'],
                    'numerique_CLE_UNIQUE'      => Sql::toBool($data['CLE_UNIQUE'])? '0x54':'0x46',
                    'TYPE_DATA'                 => $data['TYPE_DATA'],
                    'A_LONG'                    => $data['A_LONG'],
                    'numerique_N_NEGATIF_AUTO'  => Sql::toBool($data['N_NEGATIF_AUTO'])? '0x54':'0x46',
                    'N_PARTIE_ENT'              => $data['N_PARTIE_ENT'],
                    'N_PARTIE_DEC'              => $data['N_PARTIE_DEC'],
                    'MNT_DEVISE'                => $data['MNT_DEVISE'],
                    'numerique_FIC_GENERE'      => Sql::toBool($data['FIC_GENERE'])? '0x54':'0x46',
                    'ID_FORMAT'                 => $data['ID_FORMAT'],
                    'TAG_MERGE'                 => $data['TAG_MERGE'],
                    'ID_STRUCT'                 => ($data['TYPE_OBJET'] == 'B' ? $data['ID_DATA'] : $data['ID_STRUCT']),
                    'numerique_ERREUR_CALCUL'   => Sql::toBool($data['ERREUR_CALCUL'])? '0x54':'0x46',
                    'EXP_CALCUL'                => $data['EXP_CALCUL'],
                ]);
            }
        }
    }

    public function setErreurExpCalcul(string $typeObjet, int $idObjet, int $idDonnee, int $idChamps) : void
    {
        $listDataCalculated = $this->ChampRepository->getDataUseCalculedData($typeObjet, $idObjet, $idDonnee, $idChamps);
        $doaDataEntity = new DoaData($this->pdo);
        
        foreach ($listDataCalculated as $dataCalculated) {
            $exp_calcul = str_replace('[CHP_'.$idChamps.']', '', $dataCalculated['EXP_CALCUL']);
            
            $doaDataEntity->update([
                'EXP_CALCUL' => $exp_calcul,
                'numerique_ERREUR_CALCUL' => '0x54',
            ], $dataCalculated['ID_DATA']);
        }
    }
}
