<?php

namespace Modules\Evaluation\Repository;

use Helpers\Filter\FilterTable;
use Helpers\Pagination\PaginatorGestion;
use PDO;
use Helpers\QueryBuilder\AbsRepository;

class Category extends AbsRepository
{
    /**
     * @var resource $pdoStorage
     */
    private $pdoStorage;

    /**
     * __construct
     *
     * @param  \PDO $pdo
     * @param  resource $pdoStorage
     */
    public function __construct(PDO $pdo, $pdoStorage)
    {
        parent::__construct($pdo);
        $this->pdoStorage = $pdoStorage;
    }

    /**
     * Fonction qui retourne la liste des catégories de modèles de questionnaires
     * @param array<mixed> $post
     * @return array<mixed>
     */
    public function categoryList(array $post = []) : ?array
    {
        $query = "SELECT ID_GRILLE, LIB_GRILLE 
                FROM GRIL_CATE WITH(NOLOCK)
                WHERE 1 = 1";

        $params = [];
        $filter = FilterTable::splitFilter($post);

        if (count($filter) > 0 && isset($filter[1])) {
            $query .= str_ireplace('where', 'AND', $filter[0]) . $filter['tri'];

            if (count($filter[1]) != 0) {
                $params = array_merge($params, $filter[1]);
            }
        }

        $paginatorManagement = new PaginatorGestion();
        $paginatorManagement->injecterSqlCount($query, $post, $params, $this->pdo);

        return $this->fetchAssocAll($query, $params);
    }

    /*
     * Fonction qui donne le détail d'une catégorie de modèles de questionnaires
     *
     * @param string $categoryId
     * @return array détail d'une catégorie
     */
    public function categoryDetail(string $categoryId)
    {
        $query = "SELECT ID_GRILLE, LIB_GRILLE 
                FROM GRIL_CATE WITH(NOLOCK)
                WHERE ID_GRILLE = :ID_GRILLE";

        $params = [
            ':ID_GRILLE' => $categoryId,
        ];

        $detail = $this->pdo->prepare($query);
        $detail->execute($params);

        return $detail->fetch(\PDO::FETCH_ASSOC);
    }

    /*
     * Fonction qui permet de créer une nouvelle catégorie de modèles de questionnaires
     *
     * @param array $post
     * @return bool true
     */
    public function categoryNew(array $post)
    {
        $query = "INSERT INTO GRIL_CATE (ID_GRILLE, LIB_GRILLE)
                VALUES (:ID_GRILLE, :LIB_GRILLE)";

        $params = [
            ':ID_GRILLE' => $post[':ID_GRILLE'],
            ':LIB_GRILLE' => $post[':LIB_GRILLE'],
        ];

        $insert = $this->pdo->prepare($query);
        $insert->execute($params);

        return true;
    }

    /*
     * Fonction qui permet de modifier une catégorie de modèles de questionnaires
     *
     * @param array $post
     * @return bool true
     */
    public function categoryUpdate(array $post): void
    {
        $query = "UPDATE GRIL_CATE
                SET LIB_GRILLE = :LIB_GRILLE 
                WHERE ID_GRILLE = :ID_GRILLE";

        $update = $this->pdo->prepare($query);
        $update->execute($post);

        // return true;
    }

    /*
     * Fonction qui permet de supprimer une catégorie de modèles de questionnaires
     *
     * @param array $post
     * @return bool true
     */
    public function categoryDelete(array $post)
    {
        $query = "DELETE FROM GRIL_CATE
                WHERE ID_GRILLE = :ID_GRILLE";

        $update = $this->pdo->prepare($query);
        $update->execute($post);

        return true;
    }

    /**
     * @param array<string, string> $categories
     * @return array<string, mixed> $categories
     */
    public function categoryImport(array $categories): array
    {
        // on crée la table temporaire qui nous permettra de faire les contrôles sur l'insert initial
        $query =
            "SELECT ID_GRILLE, LIB_GRILLE, '' AS STATUT
                INTO #TEMP_GRIL_CATE
            FROM GRIL_CATE
            WHERE ID_GRILLE = '';";

        // on réalise un premier insert dans la table temporaire
        $query .= "INSERT INTO #TEMP_GRIL_CATE (ID_GRILLE, LIB_GRILLE, STATUT)
        VALUES ";

        foreach ($categories as $key => $category) {
            $query .=
                "('" .
                $key .
                "', '" .
                str_replace('\'', '\'\'', $category) .
                "', '" .
                "E" .
                "'), ";
        }
        $query = \trim($query, ', ') . '; ';

        // on update la table temporaire avec le champ 'statut' pour organiser les résultats
        $query .= "UPDATE T
                SET T.STATUT = 
                    CASE 
                        WHEN ISNULL (C.ID_GRILLE, '') = ''
                        THEN 'O'
                        ELSE 'E' 
                    END
                FROM #TEMP_GRIL_CATE T
                LEFT OUTER JOIN GRIL_CATE C ON C.ID_GRILLE = T.ID_GRILLE; ";

        // on insère les catégories vérifiées et non-doublons dans la liste des catégories
        $query .= "INSERT INTO GRIL_CATE (ID_GRILLE, LIB_GRILLE)
                SELECT ID_GRILLE, LIB_GRILLE FROM #TEMP_GRIL_CATE T WHERE T.STATUT = 'O' AND T.ID_GRILLE <> '' AND T.LIB_GRILLE <> ''; ";

        // on exécute la requête en connexion persistante
        $stmt = sqlsrv_query($this->pdoStorage, $query);

        // on récupère le compte de catégories importées et insérées
        $query =
            "SELECT COUNT(*) AS count FROM #TEMP_GRIL_CATE T WHERE T.STATUT = 'O' AND T.ID_GRILLE <> '' AND T.LIB_GRILLE <> '';";
        if ($stmt = sqlsrv_query($this->pdoStorage, $query)) {
            while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
                $count = $row['count'];
            }
        }

        // on récupère la liste des catégories qui existaient déjà
        $query = "SELECT T.ID_GRILLE, T.LIB_GRILLE
                FROM #TEMP_GRIL_CATE T 
                LEFT JOIN GRIL_CATE C ON C.ID_GRILLE = T.ID_GRILLE
                WHERE T.STATUT = 'E';";
        if ($stmt = sqlsrv_query($this->pdoStorage, $query)) {
            while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
                $existingCategories[$row['ID_GRILLE']] = $row['LIB_GRILLE'];
            }
        }

        return [
            'count' => $count ?? 0,
            'existingCategories' => $existingCategories ?? [],
        ];
    }
}
