<?php

namespace Modules\ProjetAchat\Service;

use Entity\Model\DoaTacheH;
use Helpers\Validator\Validator;
use Modules\ProjetAchat\Repository\Hierarchy;
use Modules\ProjetAchat\Repository\Task;
use Entity\Model\DoaTaches;

class HierarchyService
{
   
    private $pdo;

    /**
     * @var DoaTacheH $doaTacheH
     */
    private $doaTacheH;

    /**
     * @var Hierarchy $hierarchyRepository
     */
    private $hierarchyRepository;

    /**
     * @var Task $taskRepository
     */
    private $taskRepository;

    /**
     * HierarchyService constructor.
     */
    public function __construct($pdo)
    {
        $this->pdo = $pdo;
        $this->doaTacheH = new DoaTacheH($this->pdo);
        $this->hierarchyRepository = new Hierarchy($this->pdo);
        $this->taskRepository = new Task($this->pdo);
    }
    
    /**
     * @return array<mixed>
    */
    public function findHierarchy(Int $id) : ?array
    {
        return $this->doaTacheH->find($id);
    }

    public function updateHierarchy(array $payload, Int $id) : void
    {
        $this->doaTacheH->update($payload, $id);
    }

    public function deleteHierarchy(Int $id) : void
    {
        $taskService = new TaskService($this->pdo);
        $this->doaTacheH->delete($id);
        $listTask = $this->taskRepository->getTasksLinkedToHierarchy($id);
        foreach ($listTask as $task) {
            $taskService->deleteTask($task['ID_TACHE']);
        }
        
        $listChilds = $this->hierarchyRepository->getAllChilds($id);
        foreach ($listChilds as $chields) {
            $this->deleteHierarchy($chields['ID_TACHE_H']);
        }
    }

    /**
     * @param array<mixed> $payload
    */
    public function createHierarchy(array $payload) : void
    {
        $this->doaTacheH->insert($payload);
    }

    /**
     * @return array<mixed>
    */
    public function getTaskCurrentHierarchy(Int $idHierarchy) : array
    {
        return $this->taskRepository->getTasksLinkedToHierarchy($idHierarchy);
    }

    /**
     * @return array<mixed>
    */
    public function hasChilds(string $typeObject, int $idObject, int $idHierarchy): ?array
    {
        return $this->hierarchyRepository->hasChilds($typeObject, $idObject, $idHierarchy);
    }

    public function getParentHierarchy(Int $id) : int
    {
        return (int)$this->findHierarchy($id)['ID_PARENT'];
    }

    public function getRightOrder(Int $idParent, string $typeObject, $idProjet) : int
    {
        return (int) $this->hierarchyRepository->getRightOrder($idParent, $typeObject, $idProjet) + 1;
    }

    /**
     * OLD_treeBibliotheque
     * @param int $parent
     * @param array<mixed> $array
     * @param array<mixed> $post
     * @return array<mixed>
     */
    // phpcs:ignore
    public function OLD_treeHierarchy(int $parent, array $array, array $post) : ?array
    {
        
        $result = array();
        foreach ($array as $noeud) {
            if ($parent == trim($noeud['ID_PARENT'])) {
                $result[] = array(
                    'id' => $noeud['ID_TACHE_H'],
                    'text' => (strlen($noeud['LIB'])>50? '<span title="'.$noeud['LIB'].'">'.substr($noeud['LIB'], 0, 50).'</span>':$noeud['LIB']),
                    'nodes' => $this->treeHierarchy($noeud['ID_TACHE_H'], $array, $post),
                    'href' => '#'.$noeud['ID_TACHE_H'],
                );
            }
        }
        return $result;
    }
    

    /** @phpstan-ignore-next-line */
    public function treeHierarchy(?int $parent = null, array $array, array $post, ?string $urlImage = null) : ?array
    {
        $result = array();
        foreach ($array as $noeud) {
            if ($parent == trim($noeud['ID_PARENT'])) {
                $result[] = array(
                    'id' => $noeud['ID_TACHE_H'],
                    'text' => (strlen($noeud['LIB'])>50? '<span title="'.$noeud['LIB'].'">'.substr($noeud['LIB'], 0, 50).'</span>':$noeud['LIB']) .($urlImage? '<div class="divMenuContextuel" onClick="AfficheMenuH(this);roueDenteActive(this);"><img class="imagePoint" style="float: right;" src="'.$urlImage.'" width="5px" style=""/></div><ul class="ss_parametres"></ul>':''),
                    'children' => $this->treeHierarchy($noeud['ID_TACHE_H'], $array, $post, $urlImage),
                );
            }
        }
        return $result;
    }

    public function updateHierarchie(int $id, int $idParent) : void
    {
        $this->hierarchyRepository->updateHierarchiefunction($id, $idParent);
    }
    
    /**
     * @param array<string|int> $tasks
    */
    public function errorOrderHierarchy(string $typeObjet, int $idObjet, int $idHierarchy, array &$tasks) : void
    {
        $doaTache = new DoaTaches($this->pdo);
        if ($this->hierarchyRepository->getErrorOrderHierarchie($typeObjet, $idObjet, $idHierarchy)) {
            $i = 1;
            foreach ($tasks as &$task) {
                $task['NUM_ORDRE'] = $i;
                
                $doaTache->update(['NUM_ORDRE' => $i], $task['ID_TACHE']);
                $i++;
            }
        }
    }
    
    public function reOrderAnomalie(string $typeObjet, int $idObjet, int $parent): void
    {
        $doaTacheH = new DoaTacheH($this->pdo);
        $erreur = $this->hierarchyRepository->orderIsError($typeObjet, $idObjet, $parent);
        if ($erreur) {
            $listCat = $doaTacheH->fetchAll([], ['filter_egal_TYPE_OBJET' => $typeObjet,'filter_egal_ID_OBJET' => $idObjet,'filter_egal_ID_PARENT' => $parent, 'tri_NUM_ORDRE' => 'asc']);
            $i = 1;
            
            foreach ($listCat as $cat) {
                $doaTacheH->update(['NUM_ORDRE' => $i], $cat['ID_TACHE_H']);
                $i++;
            }
        }
    }
    
    public function reOrder(string $typeObjet, int $idObjet, int $idHierarchy, int $oldParent, int $parent, int $oldPosition, int $position): void
    {
        //Le treeview calcule les position lui même, il faut ajouter 1 pour avoir la cohérence avec la BDD
        $oldPosition = $oldPosition+1;
        $position = $position+1;
        $this->reOrderAnomalie($typeObjet, $idObjet, $oldParent);
        
        if ($oldParent != $parent) {
            $this->reOrderAnomalie($typeObjet, $idObjet, $parent);
            $this->hierarchyRepository->reOrderOtherParent($typeObjet, $idObjet, $idHierarchy, $oldParent, $parent, $oldPosition, $position);
            
            $this->hierarchyRepository->reorderTasks($typeObjet, $idObjet, $oldParent, $oldPosition);
        } else {
            $this->hierarchyRepository->reOrderSameParent($typeObjet, $idObjet, $idHierarchy, $parent, $oldPosition, $position);
        }
    }
}
