<?php

class Person {

    private $User_Name;
    private $User_Password;
    private $logout_other_device;
    private $db;
    private $info = array();

    public function __construct() {
        $this->db = DBConnectorFactory::loadDriver();
    }

    public function logout($userID = null) {
        if (empty($userID))
            $userID = Session::getUserID();
        if (!empty($userID))
            $this->db->query("UPDATE tbl_common_users SET Is_Logged = 0 WHERE User_ID = '" . $userID . "' ");
        Session::kill($userID);
    }

    public function userNameExists($username = null) {
        if (!is_null($username))
            $this->User_Name = $username;
        $query = $this->db->query('SELECT * FROM tbl_common_users WHERE User_Name = ?', array($this->User_Name));
        if ($this->db->rowsno($query) != 0)
            return true;
        return false;
    }

    public function userNameLogin($username = null) {
        if (!is_null($username))
            $this->User_Name = $username;
        $query = $this->db->query('SELECT * FROM tbl_common_users WHERE User_Name = ? AND Is_Logged = 1', array($this->User_Name));
        if ($this->db->rowsno($query) != 0)
            return true;
        return false;
    }

    public function setLoginInformation(array $login) {
        $this->User_Name = $login['Username'];
        $this->User_Password = $login['Password'];
        $this->logout_other_device = empty($login['logout_other_device']) ? '' : $login['logout_other_device'];
        return $this;
    }

    public function setLoginPOSInformation(array $login) {
        $this->secret_code = $login['secret_code'];
        return $this;
    }

    public static function get_login_row($cond, $cond_param_arr = array()) {
        $query_string = 'SELECT u.User_ID, u.User_Name, u.User_Password, e.Employee_FirstName AS User_FirstName
                    , e.Employee_LastName AS User_LastName, u.Role_ID, u.User_Full_Name, u.control_role_id
                    , u.limited_access, u.login_at, uc.branch_id, u.login_device, u.json_data
                    , u.user_session_path, u.stop_multi_login, u.last_login_time, u.Is_Logged,
                    u.block_ids,u.customer_group_ids,u.notification_type_ids
                FROM tbl_common_users u
                    left JOIN tbl_hrm_employee e ON u.Employee_ID = e.Employee_ID
                    left join tbl_users_accounting_accounts uc on uc.User_ID = u.User_ID
                where u.Status_ID = 1 ' . $cond . ' ';
        $db = DBConnectorFactory::loadDriver();
        $results = $db->prepare_Stmt($query_string, $cond_param_arr);
        //to don't make array_values we send both assoc & numeric
        $tmp_row = $db->assoc($results/* , PDO::FETCH_BOTH */);
        if (!empty($tmp_row)) {
            $tmp_row['Language_Code'] = 'en';
        }
        return $tmp_row;
    }

    public function login($is_secret_code = false) {
        $cond = "  and u.is_app = 0 ";
        $pass = md5(sha1(md5($this->User_Password)));
        $login_page = 'main';
        if ($is_secret_code) {
            $secret_code = md5(sha1(md5($this->secret_code)));
            $login_data = array(&$secret_code);
            $cond .= ' and BINARY secret_code = BINARY ? ';
            $login_page = 'pin';
        } else {
            $login_data = array(&$this->User_Name, &$pass);
            $cond .= ' and u.User_Name = ? AND BINARY u.User_Password = BINARY ? ';
        }
        $data_user = self::get_login_row($cond, $login_data);
        //
        if (!empty($data_user)) {
            $checkIfExpired = $this->UserExpiryDate();
            if ($checkIfExpired === 'expired')
                return 5;   // expired
            elseif ($checkIfExpired === 'notadded')
                return 6;   // error connecting
//            $returnedValuesArray = array_values($data_user);  //convert index from assoc strings to numerical numebrs
            //
            $settings = array();
            $query_st = $this->db->query('SELECT `setting_value`,setting_name FROM `tbl_default_settings` 
                WHERE `setting_name` in ("sync_type","default_branch_id","activate_end_of_day_reminder","default_start_time") ');
            while ($sett_row = $this->db->assoc($query_st))
                $settings[$sett_row['setting_name']] = $sett_row['setting_value'];
            //sync_type 0=>no sync, 1=>server, 2=>branch
            //login_at 0=>nothing, 1=>both, 2=>server, 3=>branch
            if ($settings['sync_type'] == 1 && ($data_user['login_at'] == 3 || $data_user['login_at'] == 0 ))
                return 8; // sync type is branch and the user can login only on branch
            elseif ($settings['sync_type'] == 2 && ($data_user['login_at'] == 0 || $data_user['login_at'] == 2 || ($data_user['login_at'] == 3 && $settings['default_branch_id'] != $data_user['branch_id'])))
                return 8;
            //if limited_access then user can login only on trusted computers
            if ($data_user['limited_access'] == 1) {
                if (empty($_COOKIE[DB_NAME . '_computer']))
                    return 7;
                $trusted_query = $this->db->prepare_Stmt('select * from tbl_computer_trusted where computer_cookies = ?', [&$_COOKIE[DB_NAME . '_computer']]);
                $rows_no = $this->db->rowsno($trusted_query);
                if ($rows_no == 0)
                    return 7;
            }
            //if user not allow to multi login then check that already not login
            if ($data_user['stop_multi_login'] == 1 && $data_user['Is_Logged'] == 1) {
                if (empty($this->logout_other_device))
                    return 9;
                //if logout_other_device then logout from old device by remove the session file
                elseif (!empty($data_user['user_session_path'])) {
                    if (is_file($data_user['user_session_path']) && is_writable($data_user['user_session_path']))
                        unlink($data_user['user_session_path']);
                }
            }
            //
            if ($settings['activate_end_of_day_reminder'] == 1) {
                $user_id = $data_user['User_ID'];
                $yesterday_date_time = date('Y-m-d', strtotime("-1 days")) . ' ' . $settings['default_start_time'];
                $reminder_end_of_day_query = $this->db->query('select * from  tbl_end_of_shift 
                        where (type =1 and close_time > "' . $yesterday_date_time . '") 
                        or (type= 0 and user_id = "' . $user_id . '" and close_time > "' . $yesterday_date_time . '") ');
                $rows_no = $this->db->rowsno($reminder_end_of_day_query);
                if ($rows_no == 0)
                    $data_user['reminder_end_day'] = 1;
            }
            //
            $query2 = $this->db->query('SELECT Language_Code FROM tbl_common_user_preferences WHERE User_ID = "' . $data_user['User_ID'] . '"');
            if ($this->db->rowsno($query2) != 0) {
                $row = $this->db->fetch($query2);
                $data_user['Language_Code'] = $row['Language_Code'];
            }
            //$data_user['ExpiryDateLicense'] = $this->getExpiryDate();
            $serialized_permission = new Permissions($data_user['User_ID'], true);
            $data_user['permissions'] = $serialized_permission->getPermissions();
            $data_user['login_page'] = $login_page;
            //$returnedValuesArray['block_ids'] = $data_user['block_ids'];
            //$returnedValuesArray['customer_group_ids'] = $data_user['customer_group_ids'];
            //
            Session::create($data_user);
            //
            $session_path = session_save_path() . DIRECTORY_SEPARATOR . 'sess_' . session_id();
            $this->db->query("update tbl_common_users set Is_Logged = 1, last_login_time = ?, user_session_path = ? where User_ID = ? "
                    , array(date('Y-m-d H:i:s'), $session_path, smc_session()['user_logged_id']));
            //If login is valid and has permission
            return 1;
        } else  //If username or password is invalid
            return 3;
    }

    public function redirectFromStatusCode($statusCode) {
        switch ($statusCode) {
            case 1:
                header('Location: ' . SITE_LINK . smc_session()['user_details']['landing']);
                break;
            case 3:
                header('Location: ' . SITE_LINK . 'smc?errorcode=1');
                break;
            case 5:
            case 6:
            case 7:
            case 8:
            case 9:
                header('Location: ' . SITE_LINK . 'smc?errorcode=' . $statusCode);
                break;
        }
    }

    public function redirectFromStatusCodePOS($statusCode) {
        switch ($statusCode) {
            case 1:
                header('Location: ' . SITE_LINK . smc_session()['user_details']['landing']);
                break;
            case 3:
                header('Location: ' . SITE_LINK . 'pin?errorcode=1');
                break;
            case 5:
            case 6:
            case 9:
                header('Location: ' . SITE_LINK . 'pin?errorcode=' . $statusCode);
                break;
        }
    }

    public function setdata(array $data) {
        $this->info = $data;
        return $this;
    }

    public function view() {
        $query = $this->db->query('SELECT * FROM tbl_common_users');
        while ($row = $this->db->assoc($query)) {
            $data[] = $row;
        }
        return $data;
    }

    public function getNameByID($table, $field_prefix, $ID) {
        $query = $this->db->query('SELECT * FROM ' . $table . ' WHERE ' . $field_prefix . 'ID = ' . $ID);
        while ($row = $this->db->assoc($query)) {
            return $row[$field_prefix . 'Name'];
        }
    }

    public function getExpiryDate() {
        static $exp_date = null;
        if (is_null($exp_date)) {
            $query = $this->db->query('SELECT * FROM tbl_common_expiry_date order by Expiry_ID desc limit 1');
            $row = $this->db->assoc($query);
            if (!empty($row['Expiry_Date']))
                $exp_date = $row['Expiry_Date'];
        }
        return $exp_date;
    }

    public function UserExpiryDate() {
        $exp_date = $this->getExpiryDate();
        if (empty($exp_date)) {
            $query2 = $this->db->query('INSERT INTO tbl_common_expiry_date (Expiry_Date) VALUES (Date_Add("' . date('Y-m-d') . '",INTERVAL 1 MONTH))');
            if ($query2)
                return 'added';
            return 'notadded';
        }
        if (date('Y-m-d') > $exp_date)
            return 'expired';
        return 'available';
    }

}
