<?php
include_once '../objects/db_table_object.php';

class User extends DBTableObject
{
    // database connection and table name
    //private $conn;
    protected $table_name = USERS_TABLE_NAME;
    protected $array_key = "user";
    
    // object properties
    public int $id = -1;
    public string $username = "";
    public string $password = "";
	public string $firstName = "";
	public string $lastName = "";
    public $created = "";
	public int $leftHanded = 0;
	public int $maleGender = 1;
	public string $charSkinAssetName = "";
	public string $weaponAssetName = "";
	public $lastConnection = "";
	public float $avgPrecision = 0.0;
	public float $avgReaction = 0.0;
	public float $avgFault = 0.0;
	public float $avgRapidity = 0.0;
	public int $size = 0;	
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	public static function withRow ($db, array $row)
	{
        $instance = new self($db);
        $instance->readRow($row);
        return $instance;
    }

    
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	function readRow (array $row)
	{
        $this->id = (int)$row['id'];
        $this->username = $row['username'];
        $this->firstName = $row['firstName'];
        $this->lastName = $row['lastName'];
        $this->leftHanded = $row['leftHanded'];
        $this->maleGender = $row['maleGender'];
        $this->charSkinAssetName = $row['charSkinAssetName'];
        $this->weaponAssetName = $row['weaponAssetName'];
        $this->lastConnection = date('Y-m-d H:i:s');
        $this->avgPrecision = (float)$row['avgPrecision'] ?? 0.0;
        $this->avgReaction = (float)$row['avgReaction'] ?? 0.0;
        $this->avgFault = (float)$row['avgFault'] ?? 0.0;
        $this->avgRapidity = (float)$row['avgRapidity'] ?? 0.0;
        $this->size = (int)$row['size'];
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	public function toArray () : array
	{
		return array (
			"id" => (int)$this->id,
			"username" => $this->username ?? "",
			"firstName" => $this->firstName ?? "",
			"lastName" => $this->lastName ?? "",
			"leftHanded" => ($this->leftHanded ?? 0) == 1 ? true : false,
			"maleGender" => ($this->maleGender ?? 1) == 1 ? true : false,
			"charSkinAssetName" => $this->charSkinAssetName ?? "",
			"weaponAssetName" => $this->weaponAssetName ?? "",
			"lastConnection" => $this->lastConnection,
			"avgPrecision" => (float)$this->avgPrecision ?? 0.0,
			"avgReaction" => (float)$this->avgReaction ?? 0.0,
			"avgFault" => (float)$this->avgFault ?? 0.0,
			"avgRapidity" => (float)$this->avgRapidity ?? 0.0,
			"size" => (int)$this->size
		);
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	function sanitize ()
	{
		$this->username=htmlspecialchars(strip_tags($this->username));
        $this->password=htmlspecialchars(strip_tags($this->password));
        $this->created=htmlspecialchars(strip_tags($this->created));
        $this->lastConnection=htmlspecialchars(strip_tags($this->lastConnection));
        //$this->firstName=htmlspecialchars(strip_tags($this->firstName));
        //$this->lastName=htmlspecialchars(strip_tags($this->lastName));
        //$this->leftHanded=htmlspecialchars(strip_tags($this->leftHanded));
        //$this->maleGender=htmlspecialchars(strip_tags($this->maleGender));
        //$this->charSkinAssetName=htmlspecialchars(strip_tags($this->charSkinAssetName));
        //$this->weaponAssetName=htmlspecialchars(strip_tags($this->weaponAssetName));
        //$this->avgPrecision=htmlspecialchars(strip_tags($this->avgPrecision));
        //$this->avgReaction=htmlspecialchars(strip_tags($this->avgReaction));
        //$this->avgFault=htmlspecialchars(strip_tags($this->avgFault));
        //$this->avgRapidity=htmlspecialchars(strip_tags($this->avgRapidity));
	}

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	function sanitize_update ()
	{
        //$this->username=htmlspecialchars(strip_tags($this->username));
        //$this->password=htmlspecialchars(strip_tags($this->password));
        //$this->avgPrecision=htmlspecialchars(strip_tags($this->avgPrecision));
        //$this->avgReaction=htmlspecialchars(strip_tags($this->avgReaction));
        //$this->avgFault=htmlspecialchars(strip_tags($this->avgFault));
        //$this->avgRapidity=htmlspecialchars(strip_tags($this->avgRapidity));
		$this->firstName=htmlspecialchars(strip_tags($this->firstName));
        $this->lastName=htmlspecialchars(strip_tags($this->lastName));
        $this->leftHanded=htmlspecialchars(strip_tags($this->leftHanded));
        $this->maleGender=htmlspecialchars(strip_tags($this->maleGender));
        $this->charSkinAssetName=htmlspecialchars(strip_tags($this->charSkinAssetName));
        $this->weaponAssetName=htmlspecialchars(strip_tags($this->weaponAssetName));
        $this->lastConnection=htmlspecialchars(strip_tags($this->lastConnection));
		$this->size=htmlspecialchars(strip_tags($this->size));
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	function load ()
	{
		// select all query with user inputed username and password
        $query = "SELECT * FROM " . $this->table_name . " WHERE id='" . $this->id . "'";
		
        // prepare query statement
        $stmt = $this->conn->prepare($query);
        // execute query
        $stmt->execute();
		
		if($stmt->rowCount() > 0)
		{
			// get retrieved row
			$row = $stmt->fetch(PDO::FETCH_ASSOC);
			// retrieve user values
            $this->readRow($row);
			return true;
		}
		
		return false;
	}
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //user signup method
    function signup ()
	{
        if ($this->isAlreadyExist()) return false;
        
        // query to insert record of new user signup
		$query = "INSERT INTO " . $this->table_name . " SET username=:username, password=:password, created=:created, lastConnection=:lastConnection";
		
        // prepare query
        $stmt = $this->conn->prepare($query);
    
        // sanitize
        $this->sanitize();
		
        // bind values
        $stmt->bindParam(":username", $this->username);
        $stmt->bindParam(":password", $this->password);
        $stmt->bindParam(":created", $this->created);
        $stmt->bindParam(":lastConnection", $this->lastConnection);
        //$stmt->bindParam(":firstName", $this->firstName);
        //$stmt->bindParam(":lastName", $this->lastName);
        //$stmt->bindParam(":leftHanded", $this->leftHanded);
        //$stmt->bindParam(":maleGender", $this->maleGender);
        //$stmt->bindParam(":charSkinAssetName", $this->charSkinAssetName);
        //$stmt->bindParam(":weaponAssetName", $this->weaponAssetName);
        //$stmt->bindParam(":avgPrecision", $this->avgPrecision);
        //$stmt->bindParam(":avgReaction", $this->avgReaction);
        //$stmt->bindParam(":avgFault", $this->avgFault);
        //$stmt->bindParam(":avgRapidity", $this->avgRapidity);
   
   
        // execute query
        if ($stmt->execute())
		{
            $this->id = $this->conn->lastInsertId();
            return $this->load();
        }
    
        return false;
    }

	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // login user method
    function login ()
	{
        // select all query with user inputed username and password
        $query = "SELECT * FROM " . $this->table_name . " WHERE BINARY username='".$this->username."' AND BINARY password='".$this->password."'";
		
        // prepare query statement
        $stmt = $this->conn->prepare($query);
        // execute query
        $stmt->execute();
        return $stmt;
    }
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //Update user infos
	function refreshConnectionDate ()
	{
        // select all query with user inputed username and password
        $query = "UPDATE " . $this->table_name . " SET lastConnection = '" . date('Y-m-d H:i:s') . "' WHERE id='" . $this->id . "'";
		
        // prepare query statement
        $stmt = $this->conn->prepare($query);
        // execute query
        return $stmt->execute();
    }
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //Notify if User with given username Already exists during SignUp
    function isAlreadyExist ()
	{
        $query = "SELECT * FROM " . $this->table_name . " WHERE BINARY username='".$this->username."'";
        // prepare query statement
        $stmt = $this->conn->prepare($query);
        // execute query
        $stmt->execute();
        return ($stmt->rowCount() > 0);
    }
	
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //Update user infos
    function update ()
	{
        $query = "UPDATE " . $this->table_name . " 
			SET firstName=:firstName, lastName=:lastName, leftHanded=:leftHanded, size=:size, maleGender=:maleGender, charSkinAssetName=:charSkinAssetName, " . "
			weaponAssetName=:weaponAssetName, lastConnection=:lastConnection " . "
			WHERE id=".$this->id;
		
        // prepare query
        $stmt = $this->conn->prepare($query);
		
        // sanitize
        $this->sanitize_update();
		
        // bind values
        //$stmt->bindParam(":username", $this->username);
        //$stmt->bindParam(":password", $this->password);
        //$stmt->bindParam(":avgPrecision", $this->avgPrecision);
        //$stmt->bindParam(":avgReaction", $this->avgReaction);
        //$stmt->bindParam(":avgFault", $this->avgFault);
        //$stmt->bindParam(":avgRapidity", $this->avgRapidity);
        $stmt->bindParam(":firstName", $this->firstName);
        $stmt->bindParam(":lastName", $this->lastName);
        $stmt->bindParam(":leftHanded", $this->leftHanded);
        $stmt->bindParam(":maleGender", $this->maleGender);
        $stmt->bindParam(":charSkinAssetName", $this->charSkinAssetName);
        $stmt->bindParam(":weaponAssetName", $this->weaponAssetName);
        $stmt->bindParam(":lastConnection", $this->lastConnection);
        $stmt->bindParam(":size", $this->size);
        // execute query
        return $stmt->execute();
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //user reset password methods
    function resetPassword ()
	{
        if ($this->id < 1)
        {
            // find userId for this username
            $query = "SELECT id FROM " . $this->table_name . " WHERE BINARY username='".$this->username."'";

            // prepare query
            $stmt = $this->conn->prepare($query);
            // execute query
            $stmt->execute();

            if ($stmt->rowCount() != 1)
            {
                // no user found for this username (or multiple users, but this should not happen)
                return false;
            }
            else
            {
                // get retrieved row
                $row = $stmt->fetch(PDO::FETCH_ASSOC);
                // retrieve user values
                $this->id = (int)$row['id'];
            }
        }

        // now that we have an id, run the update method
        $query = "UPDATE " . $this->table_name . " SET password=:password WHERE id=".$this->id;
        
        // prepare query
        $stmt = $this->conn->prepare($query);
        
        // sanitize
        $this->password=htmlspecialchars(strip_tags($this->password));
        
        // bind values
        $stmt->bindParam(":password", $this->password);

        // execute query
        $stmt->execute();
        
        // load user after password update
        return $this->load();
    }
}