<?php

namespace EmotionHero\Models;

use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as JMS;
use Doctrine\Common\Collections\ArrayCollection;
use Gedmo\Mapping\Annotation as Gedmo;

use Symfony\Component\Security\Core\User\UserInterface;
use Silex\Component\Security\Core\Encoder\JWTEncoder;
use EmotionHero\Application;

/**
 * Users
 *
 * @ORM\Table(name="users")
 * @ORM\Entity(repositoryClass="EmotionHero\Models\UserRepository")
 */
class User implements UserInterface
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="UUID")
     */
    private $id;

    /**
     * @ORM\OneToMany(targetEntity="Game", mappedBy="user")
     * @JMS\Exclude
     */
    private $games;

    /**
     * @ORM\Column(type="float")
     * @JMS\Exclude
     * @var float
     */
    private $totalScore;

    /**
     * @var \DateTime
     * @Gedmo\Timestampable(on="create")
     * @ORM\Column(type="datetime")
     */
    protected $createdAt;
    
    /**
     * @param float $score
     * @return \EmotionHero\Models\User
     */
    public function setTotalScore(float $score){
        $this->totalScore = $score;
        return $this;
    }
    
    /**
     * @return float
     */
    public function getTotalScore(){
        return $this->totalScore;
    }

    /**
     * Sets createdAt.
     *
     * @param  \DateTime $createdAt
     * @return $this
     */
    public function setCreatedAt(\DateTime $createdAt)
    {
        $this->createdAt = $createdAt;

        return $this;
    }

    /**
     * Returns createdAt.
     *
     * @return \DateTime
     */
    public function getCreatedAt()
    {
        return $this->createdAt;
    }

    public function __construct()
    {
        $this->games = new ArrayCollection();
    }



    /**
     * Returns the roles granted to the user.
     *
     * <code>
     * public function getRoles()
     * {
     *     return array('ROLE_USER');
     * }
     * </code>
     *
     * Alternatively, the roles might be stored on a ``roles`` property,
     * and populated in any number of different ways when the user object
     * is created.
     *
     * @return (Role|string)[] The user roles
     */
    public function getRoles() {
        return ['ROLE_USER'];
    }

    /**
     * Returns the password used to authenticate the user.
     *
     * This should be the encoded password. On authentication, a plain-text
     * password will be salted, encoded, and then compared to this value.
     *
     * @return string The password
     */
    public function getPassword() {
        return null;
    }

    /**
     * Returns the salt that was originally used to encode the password.
     *
     * This can return null if the password was not encoded using a salt.
     *
     * @return string|null The salt
     */
    public function getSalt() {
        return null;
    }

    /**
     * Returns the username used to authenticate the user.
     *
     * @return string The username
     */
    public function getUsername() {
        return $this->getId();
    }

    /**
     * Removes sensitive data from the user.
     *
     * This is important if, at any given point, sensitive information like
     * the plain-text password is stored on this object.
     */
    public function eraseCredentials() {

    }

    /**
     * Gets the value of id.
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * @JMS\VirtualProperty
     * @return String
     */
    public function getJwt() {
        $c =Application::getInstance()->getConfig();
        $encoder = new JWTEncoder($c['secret_key'], $c['jwt_lifetime'], null);
        return $encoder->encode(['id' => $this->getUsername()]);
    }
    
    /**
     * @JMS\VirtualProperty
     * @return integer
     */
    public function getRank() {
        $em =Application::getInstance()->getEm();
        /* @var $userRepo UserRepository */
        $userRepo = $em->getRepository(static::class);
        return $userRepo->getRankForUser($this);
    }
}