<?php

namespace System;

class User{

    private $_db,
            $_sessionName = 'user_id',
            $_cookieName = 'user_token',
            $_data,
            $_isLoggedIn;

    /**
     * if user id given try to get that otherwise null
     * @param integer user_id
     */
    public function __construct($user = null){
        // get dbo instance
        $this->_db = DB::getInstance();

        if(!$user)
        {
            if(Session::exists($this->_sessionName)){

                $user_id = Session::get($this->_sessionName);

                if($this->find('id', $user_id)){

                    // if inactive delete cookie
                    if($this->data()->status == 'inactive'){
                        Session::delete($this->_sessionName);
                        return;
                    }

                    $this->_isLoggedIn = true;
                }
            } 

        }else{

            $this->find('id', $user);
        }

    }

    /**
     * Create user with provided fields
     * @param  array  $fields
     * @return boolean true or false
     */
    public function create(array $fields){
        return $this->_db->insert('users', $fields);
    }

    /**
     * Special login function
     * @param  string username | email
     * @param  password users password
     * @return boolean
     */
    public function login($email, $password = null, $social = null){

        $data = $this->_db->query('SELECT * FROM users WHERE (`email` = ? OR `username` = ?)', [$email, $email]);
        if(!$data->count())return false;
        $this->_data = $data->first();

        // if social is null
        // else login user
        if($social === null)
                if(!Hash::check($password, $this->data()->password)) return false;

        // remove all previous cookies if everything is okay
        $this->logout();   

        Session::put($this->_sessionName, $this->data()->id);

        return true;
    }

    /**
     * Find user by field and value
     * @param  string field name
     * @param  string value
     * @return boolean
     */
    public function find($field, $value){

        $data = $this->_db->get('users', array($field, '=', $value));
        if(!$data->count())return false;
        $this->_data = $data->first();
        return true;
    }

    /**
     * handles user forget password section
     * @param  string user email
     * @return void(0);
     */
    public function forget($email){

        if(!$this->find('email', $email)) return false;

        // check if already a reset request then limit it
        $checkQuery = $this->_db->query('SELECT id, count FROM user_resets WHERE user_id = ?', [$this->data()->id]);

        $token = base64url_encode(Uid::createUid(33));

        if($checkQuery->count()){

            $checkData = $checkQuery->first();

            if($checkData->count == 3) return;

            // insert new hash
            $this->_db->update('user_resets', $checkData->id, array(
                'hash' => $token,
                'expires' => date('Y-m-d H:i:s', time() + 3600),
                'count' => ($checkData->count + 1)
            ));

        }else{

          $this->_db->insert('user_resets', array(

            'user_id' => $this->data()->id,
            'hash' => $token,
            'expires' => date('Y-m-d H:i:s', time() + 3600),

            ));

        }


         //send mail with token
        $mailer = new Mail();

        $resetLink = Uri::full('reset/'.$token);

        $textmessage = 
"\r\nCopy and paste this URL in your browser, to reset your password: <a href='{$resetLink}''>{$resetLink}</a>\r\n\r\n
- Admin 9xlinks";

        $htmlmessage = 
"<br/>Copy and paste this URL in your browser, to reset your password: <a href='{$resetLink}''>{$resetLink}</a><br/><br/>
- Admin 9xlinks";

       $mailer->send('Password Request on 9xlinks', $htmlmessage, $textmessage, $email);
       return;
    }


    /**
     * Update user data
     * @param  array  $fields
     * @param  string id OPTIONAL
     * @return boolean
     */
    public function update($fields = array(), $id = null){

        if(!$id && $this->isLoggedIn()) $id = $this->data()->id;

        if($this->_db->update('users', $id, $fields)) return true;

        return false;

    }

    /**
     * Getter for user data
     * @return object data
     */
    public function data(){

        return $this->_data;
    }


    /**
     * check whether user is logged in or not
     * @return boolean
     */
    public function isLoggedIn(){

        return $this->_isLoggedIn;
    }

     /**
     * Check whether user is admin or not
     * @return boolean
     */
    public function isAdmin(){

        if(!$this->_isLoggedIn) return false;

        if($this->data()->role == 'user') return false;

        return true;
    }

    /**
     * Logout Current User from everywhere
     * @return void(0)
     */
    public function logout(){
        Session::delete($this->_sessionName);
    }

}