<?php


namespace Modules\ProjetAchat\Service;

use Helpers\Outil\Sql;
use Modules\ProjetAchat\Repository\Action;
use Entity\Model\DoaRecordVal;
use Modules\GlobalApplication\Repository\DocumentsRattaches;
use Modules\ProjetAchat\Repository\Champ;
use Modules\GlobalApplication\Repository\BddObjects;
use Entity\Model\Fourniss;
use Entity\Model\AoFour;
use Entity\Model\DoaRecord;
use Helpers\Outil\Roles;
use Modules\Consultation\Repository\GestionConsultation;
use Entity\Model\Doa;

class ActionService
{

    /**
     * @var Action $actionRepository
     */
    private $actionRepository;

    protected $pdo;
    protected $DoaRecordVal;
    protected $DocumentsRattaches;

    public function __construct(\PDO $pdo)
    {
        $this->pdo = $pdo;
        $this->actionRepository = new Action($pdo);
        $this->DoaRecordVal = new DoaRecordVal($pdo);
        $this->DocumentsRattaches = new DocumentsRattaches($this->pdo);
    }

    /**
     * @return array<mixed>
    */
    public function getData(int $idObjet, ?int $idAction = null, ?int $idCategorie = null) : array
    {
        $resultArray = [];

        if ($idAction) {
            $listDatas = $this->actionRepository->getData($idAction);
        } elseif ($idCategorie) {
            $listDatas = $this->actionRepository->getDataByCategorie($idCategorie);
        }
        
        foreach ($listDatas as $data) {
            $headers = [];
            $datas = [];
            $maxLines = 0;
            $listeRecord = [];
            
            if (Sql::boolSql($data['MULTIPLE'])) {
                $maxLines = $this->actionRepository->getMaxRecord($idObjet, $data['ID_DONNEE'])['maxID_RECORD']??'';
                $listeRecord = $this->actionRepository->getListeRecord($idObjet, $data['ID_DONNEE']);
            }
            
            if ($idAction) {
                $listHeaders = $this->actionRepository->getHeaders($idAction, $data['ID_DONNEE']);
            } elseif ($idCategorie) {
                $listHeaders = $this->actionRepository->getHeadersByData($data['ID_DONNEE']);
            }
            
            foreach ($listHeaders as $header) {
                $headers[] = [
                    'NOM_DATA'  => $header['NOM_DATA'],
                    'TYPE_DATA' => $header['TYPE_DATA']
                ];
                
                if (Sql::boolSql($data['MULTIPLE'])) {
                    foreach ($listeRecord as $headerRecord) {
                        $idRecord = $headerRecord['ID_RECORD'];
                        $record = $this->actionRepository->getRecord($data['ID_DONNEE'], $header['ID_DATA'], $idRecord);
                        if ($header['TYPE_DATA'] == 'F') {
                            $doc = $this->DocumentsRattaches->docAttAvecMemos(str_pad($data['ID_OBJET'], 9, '0', STR_PAD_LEFT), $record['VALEUR']??'', 'DOA');
                            $valeur = $doc['NOM_ORI']??'';
                            $valueCompl = $record['VALEUR']??'';
                        } else {
                            $valeur = $record['VALEUR']??'';
                        }

                        $datas[] = [
                            'TYPE_DATA'   => $header['TYPE_DATA'],
                            'line'        => $idRecord,
                            'value'       => $valeur,
                            'valueCompl'  => $valueCompl??'',
                        ];
                    }
                } else {
                    $idRecord = 0;
                    
                    $record = $this->actionRepository->getRecord($data['ID_DONNEE'], $header['ID_DATA'], $idRecord);
                    
                    if ($header['TYPE_DATA'] == 'F') {
                        $doc = $this->DocumentsRattaches->docAttAvecMemos(str_pad($data['ID_OBJET'], 9, '0', STR_PAD_LEFT), $record['VALEUR']??'', 'DOA');
                        $valeur = $doc['NOM_ORI']??'';
                        $valueCompl = $record['VALEUR']??'';
                    } else {
                        $valeur = $record['VALEUR']??'';
                    }
                    
                    $href = '';
                    if ($header['OBJET'] == 'NO_AO') {
                        $droit = [
                            'HA_AO_ADM' => Roles::droitsUtilisateur($this->pdo, 'HA_AO_ADM', $_SESSION["Session_Login"]),
                            'HA_AO_CMV' => Roles::droitsUtilisateur($this->pdo, 'HA_AO_CMV', $_SESSION["Session_Login"]),
                        ];
                        
                        $gestionConsu = new GestionConsultation($this->pdo);
                        $consult = $gestionConsu->listeConsultation(['filter_egal_NO_AO' => $valeur]);
                        
                        if (($droit['HA_AO_ADM'] || $droit['HA_AO_CMV']) && $consult) {
                            $href = 'urlAO';
                        }
                    }
                    
                    $datas[] = [
                        'line' => $idRecord,
                        'value' => $valeur,
                        'valueCompl' => $valueCompl??'',
                        'href' => $href
                    ];
                }
            }
            
            if ($this->actionRepository->importDataExist($data['ID_STRUCT'])) {
                $importActive = true;
            }
            
            $resultArray[] = [
                'dataName'      => $data['NOM_DONNEE'],
                'ID_DONNEE'     => $data['ID_DONNEE'],
                'importActive'  => $importActive??false,
                'isMultiple'    => Sql::boolSql($data['MULTIPLE']),
                'headers'       => $headers,
                'countLines'    => $maxLines,
                'datas'         => $datas
            ];
        }
        
        return $resultArray;
    }
    /**
     * @param array<mixed> $val
     * @return null
    */
    public function insertData(int $idObjet, int $idDonnee, int $idRecord, array $val, bool $typeFile = false)
    {
        $check = $this->DoaRecordVal->find([
            'ID_DOA' => $idObjet,
            'ID_DONNEE' => $idDonnee,
            'ID_DATA' => $val['ID_DATA'],
            'ID_RECORD' => $idRecord,
        ]);

        if ($check && $typeFile) {
            return null;
        }

        if ($check) {
            $this->DoaRecordVal->update([
                'VALEUR' => $val['value']
            ], [
                'ID_DOA' => $idObjet,
                'ID_DONNEE' => $idDonnee,
                'ID_DATA' => $val['ID_DATA'],
                'ID_RECORD' => $idRecord,
            ]);
        } else {
            $this->DoaRecordVal->insert([
                'ID_DOA' => $idObjet,
                'ID_DONNEE' => $idDonnee,
                'ID_DATA' => $val['ID_DATA'],
                'ID_RECORD' => $idRecord,
                'VALEUR' => $val['value']
            ]);
        }

        return null;
    }
    
    public function deleteData(int $idObjet, int $idDonnee, int $idRecord) : void
    {
        $this->actionRepository->deleteDoaRecord($idObjet, $idDonnee, $idRecord);
        $this->actionRepository->deleteDoaRecordVal($idObjet, $idDonnee, $idRecord);
    }
    
    public function calculedData(string $typeObjet, int $idObjet, int $idDonnee, int $idRecord = 0, string $expression = '') : string
    {
        $champRepo = new Champ($this->pdo);
        $listInput = $champRepo->listInputCalculated($typeObjet, $idObjet, $idDonnee, $idRecord);
        
        foreach ($listInput as $input) {
            $expression = str_replace('['.$input['TYPE_DATA'].'_'.$input['ID'].']', ($input['VALEUR']??''), $expression);
        }
        
        $resultat = '';
        try {
            eval("\$resultat = {$expression};");
        } catch (\ParseError $p) {
            return '0';
        }
        
        return $resultat;
    }
    
    public function insertInfoConsultToProject(string $codeFou, int $idAO, ?int $idRecordUpdate = null) : bool
    {
        if (!$idAO || !$codeFou) {
            return false;
        }
        
        $actionRepo = new Action($this->pdo);
        $bddObjectRepo = new BddObjects($this->pdo);
        $actionService = new ActionService($this->pdo);
        $listeProjet = $actionRepo->checkLienExterneProjetExist($idAO, 'NO_AO');
        
        $fourniss = new Fourniss($this->pdo);
        $arrayFindValue = $fourniss->find($codeFou, [], [], $this->pdo::FETCH_ASSOC);
        
        $aoFour = new AoFour($this->pdo);
        $arrayFindValue2 = $aoFour->find(['CODE_FOU' => $codeFou, 'NO_AO' => $idAO], [], [], $this->pdo::FETCH_ASSOC);
        
        foreach ($arrayFindValue2 as $key2 => $val2) {
            $arrayFindValue['AO_FOUR.'.$key2] = $val2;
        }
        
        $doaEntity = new Doa($this->pdo);
        foreach ($listeProjet as $projet) {
            $infoProjet = $doaEntity->find($projet['ID_OBJET']);
            
            if ($infoProjet && $infoProjet['STATUT'] == 'T') {
                continue;
            }
            
            $listStruct = $actionRepo->getListDataLie($projet['ID_OBJET'], 'AO_FOUR');
            
            foreach ($listStruct as $struct) {
                if ($idRecordUpdate) {
                    $idRecord = $idRecordUpdate;
                } else {
                    $idRecord = null;
                }
                
                $infoStruct = $actionRepo->getInfoStructLie($projet['ID_OBJET'], $struct['ID_DONNEE']);
                
                $listeData = $actionRepo->getInfoData('noId', $struct['ID_DONNEE'], null, true);
                $keyData = 'OBJET';
                
                $codeExist = $actionRepo->getIdObjectExterne($projet['ID_OBJET'], 'AO_FOUR', $struct['ID_DONNEE'], null, $codeFou);
                
                if ($codeExist && !$idRecord) {
                    $idRecord = $codeExist['ID_RECORD'];
                }
                
                foreach ($listeData as $data) {
                    if ($arrayFindValue2 && strpos($data[$keyData], '.')) {
                        $explodeData = explode('.', $data[$keyData]);
                        $bddOject = $bddObjectRepo->getInfoChamp($explodeData[0], $explodeData[1]);
                    } else {
                        $bddOject = $bddObjectRepo->getInfoChamp($infoStruct['OBJET'], $data[$keyData]);
                    }
                    
                    $value = $bddObjectRepo->convertChamp($bddOject, $arrayFindValue[$data[$keyData]]??'');
                    
                    if (!$idRecord) {
                        $lastRecord = $actionRepo->getMaxRecord($projet['ID_OBJET'], $struct['ID_DONNEE']);
                        $idRecord = (int)$lastRecord['maxID_RECORD']+1;
                        
                        $doaRecord = new DoaRecord($this->pdo);
                        $doaRecord->insert([
                            'ID_DOA' => $projet['ID_OBJET'],
                            'ID_DONNEE' => $struct['ID_DONNEE'],
                            'ID_RECORD' => $idRecord,
                        ]);
                    }
                    
                    $actionService->insertData($projet['ID_OBJET'], $struct['ID_DONNEE'], $idRecord, ['value' => $value, 'ID_DATA' => $data['ID_DATA']]);
                }
            }
        }

        return true;
    }
}
