<?php
class PartieGateway
{
    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 array $listeUtilisateur
     */
    public function partieInQueueExists() : bool{
        $query = "SELECT count(*) FROM PARTICIPER WHERE etat = 0";
        $this->con->executeQuery($query);
        $results = $this->con->getResults();
        if ($results[0]['count(*)'] == 0)
            return false;
        else
            return true;
    }

    public function findPartieMaxId() : int{
        $query = "SELECT max(id) FROM Partie";
        $this->con->executeQuery($query);
        $results=$this->con->getResults();
        if ($results[0]['max(id)']==NULL)
            return 0;
        else
            return $results[0]['max(id)'];
    }
    public function creerPartieMulti(int $max, array $tabEnigme) : Partie{
        $partie=PartieFactory::createPartieMulti($max+1,$tabEnigme);
        $query= "INSERT INTO Partie VALUES (:idPartie,CURRENT_DATE)";
        $this->con->executeQuery($query, array(':idPartie' => array($partie->getIdPartie(), SQLITE3_INTEGER)));
        if (count($partie->getListeEnigme()) != 0) {
            foreach ($partie->getListeEnigme() as $Enigme) {
                $query = "INSERT INTO Contenir VALUES (:idPartie, :idEnigme)";
                $this->con->executeQuery($query, array(
                    ':idPartie' => array($partie->getIdPartie(), SQLITE3_INTEGER),
                    ':idEnigme' => array($Enigme->getIdEnigme(), SQLITE3_INTEGER)
                )
                );
            }
        }
        return $partie;
    }

    public function rejoindrePartieMulti(int $idPartieInQueue,array $tabEnigme) : Partie{
        $partie = PartieFactory::createPartieMulti($idPartieInQueue,$tabEnigme);
        return $partie;
    }

    public function findPartieInQueue(){
        $query = "SELECT p.id
        FROM Partie p, Participer pa
        WHERE pa.etat=0
        AND pa.partie=p.id";
        $this->con->executeQuery($query);
        $results = $this->con->getResults();
        return $results[0]['id'];
    }

    public function creerPartieSolo(Utilisateur $utilisateur){
        $query = "SELECT * FROM Enigme
        WHERE points IS NULL OR points = 0";
        $this->con->executeQuery($query);
        $results = $this->con->getResults();
        $query= "SELECT max(p.id)
        FROM PARTIE p;";
        $this->con->executeQuery($query);
        $max=$this->con->getResults()[0]["max"];
        $partie=PartieFactory::createPartieSolo($max,$results);
        $query= "INSERT INTO Partie VALUES (:idPartie,:idEnigme)";
        $this->con->executeQuery($query, array(':idPartie' => array($partie->getIdPartie(), SQLITE3_INTEGER)));
        foreach($partie->getListeEnigme() as $Enigme){
            $query= "INSERT INTO Contenir VALUES (:idPartie, :idEnigme)";
            $this->con->executeQuery($query, array(
            ':idPartie' => array($partie->getIdPartie(), SQLITE3_INTEGER),
            ':idEnigme' => array($Enigme->getIdEnigme(), SQLITE3_INTEGER)));
        }
        foreach($partie->getListeEnigme() as $Enigme){
            $query= "INSERT INTO Contenir VALUES (:idPartie, :idEnigme)";
            $this->con->executeQuery($query, array(
            ':idPartie' => array($partie->getIdPartie(), SQLITE3_INTEGER),
            ':idEnigme' => array($Enigme->getIdEnigme(), SQLITE3_INTEGER)));
        }
        $query= "INSERT INTO Participer VALUES (:idPartie, :idUtilisateur, TRUE)";
        $this->con->executeQuery($query, array(
        'idPartie' => array($partie->getIdPartie(), SQLITE3_INTEGER),
        'idUtilisateur' => array($utilisateur->getEmail(), SQLITE3_INTEGER)));
    }

    public function delete(string $idPartie){
        $query= "DELETE FROM Partie WHERE id = :idPartie";
        $this->con->executeQuery($query, array(':idPartie' => array($idPartie, SQLITE3_INTEGER)));
    }

    public function findPartieHistory() : array{
        $query="SELECT * FROM Partie";
        $this->con->executeQuery($query);
        $results = $this->con->getResults();
        $query= "SELECT max(p.id)
        FROM PARTIE p;";
        $this->con->executeQuery($query);
        $max=$this->con->getResults()[0]["max"];
        $listePartieHistory=array();
        foreach($results as $row)
        {
            $query = "SELECT e.* FROM Enigme e,Contenir c,Partie p
            WHERE p.id = c.partie
            AND c.enigme = e.id
            AND c.enCours = false;
            AND p.partie = :idPartie";
            $this->con->executeQuery($query,array(
                "idPartie" => array($row["idPartie"],SQLITE3_INTEGER)
            ));
            $historiquePartie=$this->con->getResults();
            $listePartieHistory[]=PartieFactory::createPartieHistory($row["idPartie"],$historiquePartie);
        }
        return $listePartieHistory;
    }

    public function showAll() : void{
        $query= "SELECT * FROM Partie";
        $this->con->executeQuery($query);
        $results=$this->con->getResults();
        foreach ($results as $row) {
            echo $row['idPartie'] . '</br>';
        }
    }
}