<?php

namespace Modules\ProjetAchat\Service;

use Helpers\Outil\Sql;
use Helpers\Trad\ITrad;
use Helpers\Trad\Trad;
use Helpers\ChampsSupplementaire\ChampSupp;
use Modules\ProjetAchat\Repository\Action;
use Entity\Model\Hastutil;
use Entity\Model\DoaSoc;
use Modules\ProjetAchat\Repository\DoaEvent;
use Entity\Model\Doa;
use Modules\ProjetAchat\Repository\Task;
use Entity\Model\DoaTaches;
use Helpers\Outil\Date;

class ModeleProjetService
{
  
    private $pdo;


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

    /**
     * @return array<mixed>
    */
    public function listeStatut(ITrad $trad): ?array
    {

        $listeStatut[''] = '';

        $modeInitActif = sql::paravrac($this->pdo, 'PARAMGEN', 'DOA_STATUT_INIT_ACTIF')=='O';

        if ($modeInitActif) {
            $listeStatut['I'] = $trad->t('Initialisation');
        }

        $listeStatut['P'] = $trad->t('Préparation');
        $listeStatut['E'] = $trad->t('En cours');
        $listeStatut['T'] = $trad->t('Terminé');
        
        if ($modeInitActif) {
            $listeStatut['IS'] = $trad->t('Suspendu en initialisation');
        }
        
        $listeStatut['PS'] = $trad->t('Suspendu en préparation');
        $listeStatut['ES'] = $trad->t('Suspendu en cours');

        if ($modeInitActif) {
            $listeStatut['IA'] = $trad->t('Ajourné en initialisation');
        }
        $listeStatut['PA'] = $trad->t('Ajourné en préparation');
        $listeStatut['EA'] = $trad->t('Ajourné en cours');
        
        return $listeStatut;
    }
    
    public function getParametrageReference(bool $modele): string
    {
        
        if ($modele) {
            $typeParv = 'NUM_MDOA_P';
        } else {
            $typeParv = 'NUM_DOA_P';
        }
        
        $parametrageSociete = Sql::paravrac($this->pdo, 'PARAMGEN', 'SECTNUMDOA');
        if ($parametrageSociete!='O') {
            $parametrageSaisieCode = Sql::paravrac($this->pdo, $typeParv, 'MODE');
        } else {
            $parametrageSaisieCode = Sql::paravrac($this->pdo, $typeParv, $_SESSION["Session_SocUsr"].'|MODE');
        }
        
        return $parametrageSaisieCode;
    }
    
    public function generateLibelleTypeElement(string $typeElem, string $idElem) : ?string
    {
        $array = ChampSupp::getListeTableStd();
        
        if ($array[$typeElem]??'') {
            $entity = $array[$typeElem];
            $generatorEntity = "\\Entity\\Model\\".$entity[0];
            $entity = new $generatorEntity($this->pdo);
            
            $entityValue = $entity->find($idElem);
            $libelle = $entityValue[$entity->getLibelle()] ?? '';
        } else {
            $cs_valid = new ChampSupp($this->pdo);
            $ts_don = $cs_valid->generateCSSelect($typeElem, ['CODEDICO' => $idElem]);
            if ($ts_don) {
                $libelle = $ts_don[0]['LIB01DICO'];
            } else {
                $libelle = '';
            }
        }
        
        return $libelle;
    }
    
    /**
     * @return array<mixed>
    */
    public function generateListTypeActeur(string $typeElem, ITrad $trad): ?array
    {
        
        switch ($typeElem) {
            case 'FAMILLE':
            case 'SSFAMILL':
                $array['ACHETEUR'] = $trad->t('Acheteur');
                break;
            case 'CENTRE':
            case 'CENTRE_E':
            case 'CENTRE_R':
            case 'CENTRE_F':
                $array['ACHETEUR'] = $trad->t('Acheteur du centre');
                break;
            case 'UO':
                $array['RESPUO'] = $trad->t('Responsable UO');
                break;
            case 'HASTUTIL':
                $array['SUPHIER'] = $trad->t('Supérieur hiérarchique');
                $array['RESPUO'] = $trad->t('Responsable UO');
                break;
            default:
                $array = null; // C'est pas mal d'initialisé la variable de retour surtout en présence de référence
                break;
        }
        
        $actionRepo = new Action($this->pdo);
        $listeCS = $actionRepo->getListeCSTypeActeur($typeElem);
        
        foreach ($listeCS as $cs) {
            $array[$cs['COD_TAB'].'|'.$cs['NUM_FIX']] = $cs['NOM'];
        }
        
        return $array;
    }
    
    public function insertEventCreate(int $idDoa, string $type, string $proprietaire): void
    {
        
        $hastutil = new Hastutil($this->pdo);
        $findProprio = $hastutil->find($proprietaire, ['CODE_STE']);
        
        $doaSoc = new DoaSoc($this->pdo);
        $doaSoc->insert([
            'ID_DOA' => $idDoa,
            'TYPE_GS' => 'S',
            'CODE' => $findProprio['CODE_STE']
        ]);
        
        $doaEventRepo = new DoaEvent($this->pdo);
        $doaEventRepo->rqInsertEventDOA($idDoa, $type=='D'? 'CRE':'CMO', '');
    }
    
    public static function resetDoaSession()
    {
        unset($_SESSION['LAST_DOA_EDIT']);
    }
    
    /**
     * Fonction permettant de créer un evenement dans DOA_EVT lors de la 1ere modification d'un DOA
     * return null si l'objet modifier est de la bibliotheque
     * return true si l'evenement a été créer
     * return false si l'evenement existe déjà
     */
    public static function updateDoaEvent(\pdo $pdo, int $idDoa, string $type, ?string $commentaire = null) : ?bool
    {
        if ($type=='B') {
            return false;
        }
        
        if (empty($_SESSION['LAST_DOA_EDIT']) || $_SESSION['LAST_DOA_EDIT']['ID_DOA'] != $idDoa) {
            $doaEventRepo = new DoaEvent($pdo);
            $doaEventRepo->rqInsertEventDOA($idDoa, $type=='D'? 'MOD':'MOM', $commentaire);
            
            $numOrderCreat = $doaEventRepo->getLastOrder($idDoa, $type);
            
            $_SESSION['LAST_DOA_EDIT'] = [
                'ID_DOA' => $idDoa,
                'date' => date('Ymd'),
                'hour' => date('Hms'),
                'lastOrder' => $numOrderCreat['MAX_NUM_ORDRE']
            ];
            
            return true;
        } else {
            $doaEventRepo = new DoaEvent($pdo);
            $detailEvent = $doaEventRepo->getCommentary((int)$idDoa, $type, (int)$_SESSION['LAST_DOA_EDIT']['lastOrder']);
            if ($detailEvent) {
                $commentaireTMP = $detailEvent['COMMENTAIRE'].'
'.$commentaire;
            } else {
                $commentaireTMP = $commentaire;
            }
            
            if (strlen($commentaireTMP) > 2999) {
                $doaEventRepo->rqInsertEventDOA($idDoa, $type=='D'? 'MOD':'MOM', $commentaire);
                
                $numOrderCreat = $doaEventRepo->getLastOrder($idDoa, $type);
                
                $_SESSION['LAST_DOA_EDIT']['lastOrder'] = $numOrderCreat['MAX_NUM_ORDRE'];
            } else {
                $doaEventRepo->updateCommentaire((int)$idDoa, $type, (int)$_SESSION['LAST_DOA_EDIT']['lastOrder'], $commentaireTMP);
            }
        }
        return false;
    }
    
    public function recalculePlanning(int $idDoa, string $type) : void
    {
        $doaEntity = new Doa($this->pdo);
        $taskRepository = new Task($this->pdo);
        $taskService = new TaskService($this->pdo);
        $doaTacheEntity = new DoaTaches($this->pdo);
        
        $doa = $doaEntity->find($idDoa);

        $newDate = $doa['DATE_DEB'];
        
        $firstTask = $taskRepository->getListTasksForPlanning($type, $idDoa)['0']??'';
        
        if ($firstTask) {
            if ($firstTask['DUREE_PREV'] == '0') {
                $dateFin = $newDate;
            } else {
                $dateFin = $taskService->getNonBusyDate($firstTask['ID_TACHE_H'], $idDoa, Date::dateConverte($newDate, 'aaaa-mm-jj'), $firstTask['DUREE_PREV']);
                Date::dateToSql($dateFin);
                // if ($newDate != '00000000') {
                //     $dateTrans = Date::dateConverte($newDate, 'aaaa-mm-jj');
                //     $dateFin = $taskService->getNonBusyDate($firstTask['ID_TACHE_H'], $idDoa, $dateTrans, $firstTask['DUREE_PREV']);
                //     Date::dateToSql($dateFin);
                // } else {
                //     $dateFin = '00000000';
                // }
            }
        }
        
        $arrayElt[$firstTask['ID_TACHE']] = [
            'DATE_DEB_SQL' => $newDate,
            'DATE_FIN_SQL' => $dateFin
        ];
        
        $listGroupTask = $taskRepository->getGroupTaskPlanning($type, $idDoa, (int)$firstTask['ID_TACHE']);
        foreach ($listGroupTask as $groupTask) {
            /** @phpstan-ignore-next-line */
            if (is_null($arrayElt) || ! array_key_exists($groupTask['ID_TACHE'], $arrayElt)) {
                $dateFin = $taskService->getNonBusyDate($groupTask['ID_TACHE_H'], $idDoa, Date::dateConverte($newDate, 'aaaa-mm-jj'), $groupTask['DUREE_PREV']);
                date::dateToSql($dateFin);
                // if ($newDate != '00000000') {
                //     $dateTrans = Date::dateConverte($newDate, 'aaaa-mm-jj');
                //     $dateFin = $taskService->getNonBusyDate($groupTask['ID_TACHE_H'], $idDoa, $dateTrans, $groupTask['DUREE_PREV']);
                //     date::dateToSql($dateFin);
                // } else {
                //     $dateTrans = '00000000';
                // }
                
                
                $arrayElt[$groupTask['ID_TACHE']] = [
                    'DATE_DEB_SQL' => $newDate,
                    'DATE_FIN_SQL' => $dateFin
                ];
            }
        }
        
        $arrayElt = $taskService->majDatePlanningAuto($type, $idDoa, (int)$firstTask['ID_TACHE'], $dateFin ?? '', $arrayElt);

        
        foreach ($arrayElt as $key => $val) {
            $doaTacheEntity->update(['DATE_DEB' => $val['DATE_DEB_SQL'],'DATE_FIN' => $val['DATE_FIN_SQL']], $key);
        }
    }
}
