<?php
class ResoudreGateway
{
    private Connection $con;

    /**
     * @param Connection $con
     */
    public function __construct()
    {
        global $dsn, $rep, $vues, $error;
        try {
            $con = new Connection($dsn);
            $this->con = $con;
        } catch (Exception $e) {
            $error = $e->getMessage();
            require($rep . $vues['erreur']);
        }
    }

    /**
     * @param Connection $con
     */
    public function setCon(Connection $con): void
    {
        $this->con = $con;
    }
    public function deleteByEnigme(int $idEnigme){
        $query="DELETE FROM Resoudre WHERE enigme=:idEnigme";
        $this->con->executeQuery($query, array(
            "idEnigme" => array($idEnigme, SQLITE3_INTEGER)));
    }

    public function resoudreEnigmeSolo(Utilisateur $utilisateur, int $enigmeId, int $partieId){
        $query="SELECT * FROM Resoudre
        WHERE utilisateur=:utilisateur
        AND enigme=:enigme";
        $this->con->executeQuery($query, array(
            "utilisateur" => array($utilisateur->getEmail(), SQLITE3_TEXT),
            "enigme" => array($enigmeId, SQLITE3_INTEGER)));
        $results=$this->con->getResults();
        if(empty($results))
        {
            $temps = 1;
            $code = "";
            $ended = false;
            $query="INSERT INTO Resoudre VALUES (:utilisateur, :enigme,:partie,:classement,:index,:temps,:code,:ended,:enMulti)";
            $this->con->executeQuery($query, array(
                "utilisateur" => array($utilisateur->getEmail(), SQLITE3_TEXT),
                "enigme" => array($enigmeId, SQLITE3_INTEGER),
                "partie" => array($partieId, SQLITE3_INTEGER),
                "classement" => array(NULL, SQLITE3_NULL),
                "index" => array(NULL, SQLITE3_NULL),
                "temps" => array($temps, SQLITE3_FLOAT),
                "code" => array($code, SQLITE3_TEXT),
                "ended" => array($ended, SQLITE3_INTEGER),
                "enMulti" => array(0, SQLITE3_INTEGER)));
        }
        else
        {
            $query = "SELECT * FROM Resoudre WHERE utilisateur=:utilisateur AND enigme=:enigme";
            $this->con->executeQuery($query, array(
                "utilisateur" => array($utilisateur->getEmail(), SQLITE3_TEXT),
                "enigme" => array($enigmeId, SQLITE3_INTEGER)));
            $results = $this->con->getResults();
            $temps = $results[0]['temps'];
            $code = $results[0]['code'];
            $ended = $results[0]['ended'];
            $query="UPDATE Resoudre
            SET temps=:temps, code=:code, ended=:ended
            WHERE utilisateur=:utilisateur
            AND enigme=:enigme";
            $this->con->executeQuery($query, array(
                "utilisateur" => array($utilisateur->getEmail(), SQLITE3_TEXT),
                "enigme" => array($enigmeId, SQLITE3_INTEGER),
                "temps" => array($temps, SQLITE3_FLOAT),
                "code" => array($code, SQLITE3_TEXT),
                "ended" => array($ended, SQLITE3_INTEGER)));
        }
    }
    public function resoudreEnigmeMulti(Utilisateur $utilisateur, int $enigmeId, int $partieId, int $index){
        $query="SELECT * FROM Resoudre
        WHERE utilisateur=:utilisateur
        AND enigme=:enigme
        AND partie=:partie";
        $this->con->executeQuery($query, array(
            "utilisateur" => array($utilisateur->getEmail(), SQLITE3_TEXT),
            "enigme" => array($enigmeId, SQLITE3_INTEGER),
            "partie" => array($partieId, SQLITE3_INTEGER)));
        $results=$this->con->getResults();
        if(empty($results) || $results == null)
        {
            $temps = 1;
            $code = "";
            $ended = false;
            $query="INSERT INTO Resoudre VALUES (:utilisateur, :enigme,:partie,:classement,:index,:temps,:code,:ended,:enMulti)";
            $this->con->executeQuery($query, array(
                "utilisateur" => array($utilisateur->getEmail(), SQLITE3_TEXT),
                "enigme" => array($enigmeId, SQLITE3_INTEGER),
                "partie" => array($partieId, SQLITE3_INTEGER),
                "classement" => array(NULL, SQLITE3_NULL),
                "index" => array($index, SQLITE3_INTEGER),
                "temps" => array($temps, SQLITE3_FLOAT),
                "code" => array($code, SQLITE3_TEXT),
                "ended" => array($ended, SQLITE3_INTEGER),
                "enMulti" => array(1, SQLITE3_INTEGER)));
        }
        else
        {
            $query = "SELECT * FROM Resoudre WHERE utilisateur=:utilisateur AND enigme=:enigme";
            $this->con->executeQuery($query, array(
                "utilisateur" => array($utilisateur->getEmail(), SQLITE3_TEXT),
                "enigme" => array($enigmeId, SQLITE3_INTEGER)));
            $results = $this->con->getResults();
            $temps = $results[0]['temps'];
            $code = $results[0]['code'];
            $ended = $results[0]['ended'];
            $query="UPDATE Resoudre
            SET temps=:temps, code=:code, ended=:ended
            WHERE utilisateur=:utilisateur
            AND enigme=:enigme";
            $this->con->executeQuery($query, array(
                "utilisateur" => array($utilisateur->getEmail(), SQLITE3_TEXT),
                "enigme" => array($enigmeId, SQLITE3_INTEGER),
                "temps" => array($temps, SQLITE3_FLOAT),
                "code" => array($code, SQLITE3_TEXT),
                "ended" => array($ended, SQLITE3_INTEGER)));
        }
    }
    public function checkEnigmeIsEnded(string $mailUtilisateur, int $enigmeId){
        $query="SELECT * FROM Resoudre
        WHERE utilisateur=:utilisateur
        AND enigme=:enigme";
        $this->con->executeQuery($query, array(
            "utilisateur" => array($mailUtilisateur, SQLITE3_TEXT),
            "enigme" => array($enigmeId, SQLITE3_INTEGER)));
        $results=$this->con->getResults();
        if(empty($results))
        {
            return false;
        }
        else
        {
            return $results[0]['ended'];
        }
    }
    public function checkEnigmeIsEndedInPartie(string $mailUtilisateur, int $enigmeId, int $idPartie){
        $query="SELECT * FROM Resoudre
        WHERE utilisateur=:utilisateur
        AND enigme=:enigme
        AND partie=:partie";
        $this->con->executeQuery($query, array(
            "utilisateur" => array($mailUtilisateur, SQLITE3_TEXT),
            "enigme" => array($enigmeId, SQLITE3_INTEGER),
            "partie" => array($idPartie, SQLITE3_INTEGER)));
        $results=$this->con->getResults();
        if(empty($results))
        {
            return false;
        }
        else
        {
            return $results[0]['ended'];
        }
    }

    public function checkPartieIsAlreadyCreate(int $enigmeId) : bool{
        $query="SELECT * FROM Resoudre
        WHERE enigme=:enigme";
        $this->con->executeQuery($query, array(
            "enigme" => array($enigmeId, SQLITE3_INTEGER)));
        $results=$this->con->getResults();
        if(empty($results))
        {
            return false;
        }
        else
        {
            return true;
        }
    }
    public function enigmeEnded(string $mailUtilisateur, int $enigmeId){
        $query="UPDATE Resoudre
        SET ended=:ended
        WHERE utilisateur=:utilisateur
        AND enigme=:enigme";
        $this->con->executeQuery($query, array(
            "utilisateur" => array($mailUtilisateur, SQLITE3_TEXT),
            "enigme" => array($enigmeId, SQLITE3_INTEGER),
            "ended" => array(1, SQLITE3_INTEGER)));
    }
     public function enigmeMultiEnded(string $mailUtilisateur, int $enigmeId, int $idPartie ,int $tempDeResolution, $classement){
        $query="UPDATE Resoudre
        SET ended=:ended
        WHERE utilisateur=:utilisateur
        AND enigme=:enigme
        AND partie=:partie";
        $this->con->executeQuery($query, array(
            "utilisateur" => array($mailUtilisateur, SQLITE3_TEXT),
            "enigme" => array($enigmeId, SQLITE3_INTEGER),
            "partie" => array($idPartie, SQLITE3_INTEGER),
            "ended" => array(1, SQLITE3_INTEGER)));

        $query="UPDATE Resoudre
        SET temps=:temps
        WHERE utilisateur=:utilisateur
        AND enigme=:enigme
        AND partie=:partie";
        $this->con->executeQuery($query, array(
            "utilisateur" => array($mailUtilisateur, SQLITE3_TEXT),
            "enigme" => array($enigmeId, SQLITE3_INTEGER),
            "partie" => array($idPartie, SQLITE3_INTEGER),
            "temps" => array($tempDeResolution, SQLITE3_INTEGER)));
        
        $query="UPDATE Resoudre
        SET classement=:classement
        WHERE utilisateur=:utilisateur
        AND enigme=:enigme
        AND partie=:partie";
        $this->con->executeQuery($query, array(
            "utilisateur" => array($mailUtilisateur, SQLITE3_TEXT),
            "enigme" => array($enigmeId, SQLITE3_INTEGER),
            "partie" => array($idPartie, SQLITE3_INTEGER),
            "classement" => array($classement, SQLITE3_INTEGER)));
    }

    public function saveCode(string $mailUtilisateur, int $enigmeId, string $code){
        $query="UPDATE Resoudre
        SET code=:code
        WHERE utilisateur=:utilisateur
        AND enigme=:enigme";
        $this->con->executeQuery($query, array(
            "utilisateur" => array($mailUtilisateur, SQLITE3_TEXT),
            "enigme" => array($enigmeId, SQLITE3_INTEGER),
            "code" => array($code, SQLITE3_TEXT)));
    }
    public function saveCodeMulti(string $mailUtilisateur, int $enigmeId, int $idPartie, int $index,string $code){
        $query="UPDATE Resoudre
        SET code=:code
        WHERE utilisateur=:utilisateur
        AND enigme=:enigme
        AND partie=:partie
        AND indexEnigme=:index";
        $this->con->executeQuery($query, array(
            "utilisateur" => array($mailUtilisateur, SQLITE3_TEXT),
            "enigme" => array($enigmeId, SQLITE3_INTEGER),
            "partie" => array($idPartie, SQLITE3_INTEGER),
            "index" => array($index, SQLITE3_INTEGER),
            "code" => array($code, SQLITE3_TEXT)));
    }
    public function getCode(string $mailUtilisateur, int $enigmeId) : string{
        $query="SELECT * FROM Resoudre
        WHERE utilisateur=:utilisateur
        AND enigme=:enigme";
        $this->con->executeQuery($query, array(
            "utilisateur" => array($mailUtilisateur, SQLITE3_TEXT),
            "enigme" => array($enigmeId, SQLITE3_INTEGER)));
        $results=$this->con->getResults();
        if(empty($results))
        {
            return "";
        }
        else
        {
            return $results[0]['code'];
        }
    }

    public function getLastEnigmeEnded(string $mailUtilisateur) : int{
        $query="SELECT * FROM Resoudre
        WHERE utilisateur=:utilisateur
        AND enMulti=:enMulti
        AND ended=:ended
        ORDER BY ended DESC LIMIT 1";
        $this->con->executeQuery($query, array(
            "utilisateur" => array($mailUtilisateur, SQLITE3_TEXT),
            "ended" => array(1, SQLITE3_INTEGER),
            "enMulti" => array(0, SQLITE3_INTEGER)));
        $results=$this->con->getResults();
        if(empty($results))
        {
            return 0;
        }
        else
        {
            return $results[0]['enigme'];
        }
    }
    public function getLastIndex(int $idPartie) : int{
        $query="SELECT max(indexEnigme) FROM Contenir
        WHERE partie=:partie";
        $this->con->executeQuery($query, array(
            "partie" => array($idPartie, SQLITE3_INTEGER)));
        $results=$this->con->getResults();
        if (empty($results) || $results[0]['max(indexEnigme)'] == null) {
            return 0;
        }
        return $results[0]['max(indexEnigme)'];
    }
    public function getMaxClassement($enigmeId, $idPartie) : int{
        $query="SELECT classement FROM Resoudre
        WHERE enigme=:enigme
        AND partie=:partie
        ORDER BY classement DESC LIMIT 1";
        $this->con->executeQuery($query, array(
            "enigme" => array($enigmeId, SQLITE3_INTEGER),
            "partie" => array($idPartie, SQLITE3_INTEGER)));
        $results=$this->con->getResults();
        if (empty($results) || $results[0]['classement'] == null) {
            return 0;
        }
        return $results[0]['classement'];
    }
    public function getClassement($enigmeId, $idPartie) : array{
        $query="SELECT classement FROM Resoudre
        WHERE enigme=:enigme
        AND partie=:partie
        ORDER BY classement";
        $this->con->executeQuery($query, array(
            "enigme" => array($enigmeId, SQLITE3_INTEGER),
            "partie" => array($idPartie, SQLITE3_INTEGER)));
        $results=$this->con->getResults();
        foreach ($results as $row) {
            $classement[] = $row['classement'];
        };
        return $classement;
    }

    public function getAllByPartieAndUtilisateur(string $mailUtilisateur, int $idPartie) : array{
        $query = "SELECT * FROM Resoudre
        WHERE utilisateur=:utilisateur
        AND partie=:partie";
        $this->con->executeQuery($query, array(
            "utilisateur" => array($mailUtilisateur, SQLITE3_TEXT),
            "partie" => array($idPartie, SQLITE3_INTEGER)));
        $results=$this->con->getResults();
        return $results;
    }

    public function skipEnigme(string $mailUtilisateur, int $idPartie, int $idEnigme) {
        global $playerNumberPerGame;
        $query = "UPDATE Resoudre
        SET ended=:ended
        WHERE utilisateur=:utilisateur
        AND partie=:partie";
        $this->con->executeQuery($query, array(
            "utilisateur" => array($mailUtilisateur, SQLITE3_TEXT),
            "partie" => array($idPartie, SQLITE3_INTEGER),
            "ended" => array(1, SQLITE3_INTEGER)));

        $query = "UPDATE Resoudre
        SET temps=:temps
        WHERE utilisateur=:utilisateur
        AND partie=:partie";
        $this->con->executeQuery($query, array(
            "utilisateur" => array($mailUtilisateur, SQLITE3_TEXT),
            "partie" => array($idPartie, SQLITE3_INTEGER),
            "temps" => array(null, SQLITE3_NULL)));
        
        $query = "UPDATE Resoudre
        SET classement=:classement
        WHERE utilisateur=:utilisateur
        AND partie=:partie";
        $this->con->executeQuery($query, array(
            "utilisateur" => array($mailUtilisateur, SQLITE3_TEXT),
            "partie" => array($idPartie, SQLITE3_INTEGER),
            "classement" => array($playerNumberPerGame, SQLITE3_INTEGER)));

    }
}