<?php
namespace Gateway;
use PDO;
use PDOException;

Class QuoteGateway extends Gateway{

    public function searchQuote(string $quote,int $numpage,string $language):array{
        $query="SELECT q.id_quote, q.content, q.id_caracter, c.img_char, s.title, s.date, q.likes, q.langue 
            FROM Quote q 
            JOIN Source s ON s.id_source = q.id_source 
            WHERE content LIKE '%:quote%' AND is_valid = true AND langue = :langue 
            LIMIT 20 OFFSET :page*20;";
        $this->co->executeQuery($query,array(':quote' => array($quote,PDO::PARAM_STR),':page' => array($numpage,PDO::PARAM_INT),':langue' => array($language,PDO::PARAM_STR)));
        return $this->co->getResults();
    }

    public function searchSource(string $source,int $numpage,string $language):array{

        //recherche par source
        $query="SELECT q.id_quote, q.content, c.character, c.img_path, s.title, s.date, q.likes, q.langue 
            FROM Quote q 
            JOIN Caracter c ON c.id_caracter = q.character 
            JOIN Source s ON s.id_source = q.id_source  
            WHERE s.title LIKE '%:source%' AND q.is_valid = true AND langue = :langue 
            LIMIT 20 OFFSET :page*20;";
        $this->co->executeQuery($query,array(':source' => array($source,PDO::PARAM_STR),':page' => array($numpage,PDO::PARAM_INT),':langue' => array($language,PDO::PARAM_STR)));
        $result=$this->co->getResults();
        return $result;
    }

    public function searchPers(string $Carac,int $numpage,string $language):array{

        //recherche par personnage
        $query="SELECT q.id_quote, q.content, c.character, c.img_path, s.title, s.date, q.likes, q.langue
            FROM Quote q 
            JOIN Caracter c ON c.id_caracter = q.character
            JOIN Source s ON s.id_source = q.id_source 
            WHERE c.character LIKE '%:pers%' AND q.is_valid = true AND langue = :langue 
            LIMIT 20 OFFSET :page*20;";
        $this->co->executeQuery($query,array(':pers' => array($Pers,PDO::PARAM_STR),':page' => array($numpage,PDO::PARAM_INT),':langue' => array($language,PDO::PARAM_STR)));
        $result=$this->co->getResults();
        return $result;
    }

    public function searchId(string $id):array{

        //recherche par id
        $query="SELECT q.id_quote, q.content, c.caracter, i.imgPath, s.title, s.dates, q.likes, q.langue 
            FROM Quote q 
            JOIN Caracter c ON c.id_caracter = q.id_caracter 
            JOIN Source s ON s.id_source = q.id_source 
            JOIN Image i ON c.id_img = i.id_img 
            WHERE q.id_quote = :id AND q.isvalide = true;";
        $this->co->executeQuery($query,array(':id' => array($id,PDO::PARAM_STR)));
        $result=$this->co->getResults();
        return $result;
    }

    public function search(?string $type,?string $search,array $filtre):array{
        $query="SELECT q.id_quote, q.content, c.caracter, i.imgPath, s.title, s.dates, q.likes, q.langue 
                FROM Quote q 
                JOIN Caracter c ON c.id_caracter = q.id_caracter 
                JOIN Source s ON s.id_source = q.id_source 
                JOIN Image i ON c.id_img = i.id_img 
                WHERE lower(";

        if($type=='personnage'){
            $query = $query . "c.caracter) LIKE lower('%" . $search . "%')";
        }
        elseif($type=='titre'){
            $query = $query . "s.title) LIKE lower('%" . $search . "%')";
        }
        else{
            $query = $query . "q.content) LIKE lower('%" . $search . "%')";
        }
        /* Categorie a rajouter
        foreach($filtre as $fil){
            $query = $query . " AND " . $fil
        }*/

        $this->co->executeQuery($query,array());

        $result=$this->co->getResults();
        return $result;
    }

    public function getQuoteOfTheDay(string $language): array {
        $query = "SELECT q.id_quote, q.content, c.caracter, i.imgPath, s.title, s.dateS, q.likes, q.langue
            FROM DailyQuote dq
            JOIN Quote q ON dq.citation_id = q.id_quote
            JOIN Caracter c ON c.id_caracter = q.id_caracter
            JOIN Source s ON s.id_source = q.id_source
            JOIN Image i ON c.id_img = i.id_img
            WHERE q.isValide = true AND q.langue = :language
            ORDER BY q.id_quote DESC
            LIMIT 1;";
        try {
            $this->co->executeQuery($query, [':language' => [$language, PDO::PARAM_STR]]);
            $result = $this->co->getResults();
            return $result[0] ?? [];
        } catch (PDOException $e) {
            echo "Erreur dans getQuoteOfTheDay: " . $e->getMessage();
            return [];
        }
    }



    public function getSuggestions(int $numpage, string $language): array {
        $query = "SELECT q.id_quote, q.content, c.caracter, i.imgPath, s.title, s.dateS, q.likes, q.langue
                  FROM Quote q
                  JOIN Caracter c ON c.id_caracter = q.id_caracter
                  JOIN Source s ON s.id_source = q.id_source
                  JOIN Image i ON c.id_img = i.id_img
                  WHERE q.isValide = true AND q.langue = :language
                  ORDER BY RANDOM()
                  LIMIT 20 OFFSET :offset;";

        $this->co->executeQuery($query, [
            ':language' => [$language, PDO::PARAM_STR],
            ':offset' => [$numpage * 20, PDO::PARAM_INT]
        ]);
        return $this->co->getResults();
    }

    public function getFavorites(string $userId): array {
        $query = "SELECT q.id_quote, q.content, c.caracter, i.imgPath, s.title, s.dateS, q.likes, q.langue
                  FROM Favorite f
                  JOIN Quote q ON f.quote = q.id_quote
                  JOIN Caracter c ON c.id_caracter = q.id_caracter
                  JOIN Source s ON s.id_source = q.id_source
                  JOIN Image i ON c.id_img = i.id_img
                  WHERE f.users = :userId";
    
        try {
            $this->co->executeQuery($query, [
                ':userId' => [$userId, PDO::PARAM_STR]
            ]);
            return $this->co->getResults();
        } catch (PDOException $e) {
            echo "Erreur dans getFavorites: " . $e->getMessage();
            return [];
        }
    }

    public function autoincrement() : int
    {
        $query = "SELECT Max(id_quote) + 1 as id FROM Quote;";
        $this->co->executeQuery($query);
        return ($this -> co ->getResults())[0]['id'];
    }

    public function addQuote(string $content, string $lang, int $idChar, int $idSrc, int $idUsr){
        $id = $this->getLastId();
        $query = "INSERT INTO Quote Values (:id,:content,0,:lang,false,'',:charac,:src,:user);";
        try {
            $this->co->executeQuery($query,[
                ':id' => [$id,PDO::PARAM_INT],
                ':content' => [$content,PDO::PARAM_STR],
                ':lang' => [$lang,PDO::PARAM_STR],
                ':charac' => [$idChar,PDO::PARAM_INT],
                ':src' => [$idSrc,PDO::PARAM_INT],
                ':user' => [$idUsr,PDO::PARAM_INT],
            ]);
        }
        catch (PDOException $e){
            $error['501'] = 'Erreur lors de la création de la citation';
            return error;
        }
    }

    public function getLastId():int{
        $query = "SELECT id_quote FROM Quote;";
        $this -> co -> executeQuery($query);
        $res = $this -> co -> getResults();
        foreach($res as $r){
            $tab[] = $r["id_quote"];
        }
        $id = 1;
        while(in_array($id,$tab))
        {
            $id=$id+1;
        }
        return $id;
    }

    //======================== PARTI ADMIN ========================
    //Probablement à déplacer dans un autre fichier

    public function getQuoteIsValide():array{
        //obtenir les quotes en attentes de validation par l'admin
        $query = 'SELECT *  FROM Quote WHERE isValid=:bool';
        $this->co->executeQuery($query,array(':bool' => array(false, PDO::PARAM_BOOL)));
        return $this->co->getResults();
    }

    public function validQuote(int $id){
        //Valider la quote par l'admin
        $query ='UPDATE Quote SET isValid=:newValide WHERE id_Quote=:id';
        $this->co->executeQuery($query,array(':id' => array($id,PDO::PARAM_INT)));
    }

    public function invalidQuote(int $id){
        //Invalide la quote par l'admin (suppression)
        $query ='DELETE FROM Quote WHERE id_Quote=:id';
        $this->co->executeQuery($query,array(':id' => array($id,PDO::PARAM_INT)));
    }

    public function updateContent(int $id, string $newContent):array{
        //Update le contexte de quote passé en paramètre
        $queryUpdate = 'UPDATE Quote SET content=:newContent WHERE id_quote=:idQuote';
        $this->co->executeQuery($queryUpdate, array(':idQuote'=>array($id, PDO::PARAM_STR), ':newContent'=> array($newContent, PDO::PARAM_STR)));

        //Renvoie le nouveau contexte de quote
        $queryReponse = 'SELECT content FROM Quote WHERE id_quote=:idQuote';
        $this->co->executeQuery($queryReponse, array(':idQuote'=>array($id, PDO::PARAM_STR)));
        return $this->co->getResults();
    }

    public function updateTimeCode(int $id, string $newTimeCode):array{
        //Update le time code de quote passé en paramètre
        $queryUpdate = 'UPDATE Quote SET timecode=:newTimeCode WHERE id_quote=:idQuote';
        $this->co->executeQuery($queryUpdate, array(':idQuote'=>array($id, PDO::PARAM_STR), ':newTimeCode'=> array($newTimeCode, PDO::PARAM_STR)));

        //Renvoie le nouveau contexte de quote
        $queryReponse = 'SELECT timecode FROM Quote WHERE id_quote=:idQuote';
        $this->co->executeQuery($queryReponse, array(':idQuote'=>array($id, PDO::PARAM_STR)));
        return $this->co->getResults();
    }

    public function updateDate(int $id, int $newDate):array{
        //Update la date de quote passé en paramètre
        $queryUpdate = 'UPDATE Source SET dateSource =:newdate WHERE idSource = (SELECT idSource FROM Quote WHERE idQuote =:idQuote)';
        $this->co->executeQuery($queryUpdate, array(':idQuote'=>array($id, PDO::PARAM_STR), ':newDate'=> array($newDate, PDO::PARAM_INT)));

        //Renvoie la nouvelle date de quote
        $queryReponse = 'SELECT s.dateSource FROM Source s, Quote q WHERE id_quote=:idQuote AND s.idSource = q.idSource';
        $this->co->executeQuery($queryReponse, array(':idQuote'=>array($id, PDO::PARAM_STR)));
        return $this->co->getResults();
    }

    public function updateTitle(int $id, string $newTitle):array{
        //Update le titre de l'oeuvre de quote passé en paramètre
        $queryUpdate = 'UPDATE Source SET title =:newTitle WHERE idSource = (SELECT idSource FROM Quote WHERE idQuote =:idQuote)';
        $this->co->executeQuery($queryUpdate, array(':idQuote'=>array($id, PDO::PARAM_STR), ':newTitle'=> array($newTitle, PDO::PARAM_STR)));

        //Renvoie le nouveau titre de quote
        $queryReponse = 'SELECT s.title FROM Source s, Quote q WHERE id_quote=:idQuote AND s.idSource = q.idSource';
        $this->co->executeQuery($queryReponse, array(':idQuote'=>array($id, PDO::PARAM_STR)));
        return $this->co->getResults();
    }

    public function updateNameCharacter(int $id, string $newNameCharacter):array{
        //Update le personnage de l'oeuvre de quote passé en paramètre
        $queryUpdate = 'UPDATE Character SET name =:newNameCharacter WHERE idCharacter = (SELECT idCharacter FROM Quote WHERE idQuote =:idQuote)';
        $this->co->executeQuery($queryUpdate, array(':idQuote'=>array($id, PDO::PARAM_STR), ':newNameCharacter'=> array($newNameCharacter, PDO::PARAM_STR)));

        //Renvoie le nouveau personnage de quote
        $queryReponse = 'SELECT c.title FROM Character c, Quote q WHERE id_quote=:idQuote AND c.idCharacter = q.idCharacter';
        $this->co->executeQuery($queryReponse, array(':idQuote'=>array($id, PDO::PARAM_STR)));
        return $this->co->getResults();
    }
}

?>