<?php

/*
 *  The SQL Injection Prevention are handled by BINDING
 *  $db->bind(something)
 * 
 */

global $app;
global $csrf;
global $twilio;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Twilio\Rest\Client;

$sid = 'ACf33c135ae826f004d380c8ef3e437eae'; 
$token = '3b0fcbf497d12ce4a13c99020046a880'; 
$twilio = new Client($sid, $token);

function get_client_ip() {
    $ipaddress = '';
    if (isset($_SERVER['HTTP_CLIENT_IP']))
        $ipaddress = $_SERVER['HTTP_CLIENT_IP'];
    else if (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
        $ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
    else if (isset($_SERVER['HTTP_X_FORWARDED']))
        $ipaddress = $_SERVER['HTTP_X_FORWARDED'];
    else if (isset($_SERVER['HTTP_FORWARDED_FOR']))
        $ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
    else if (isset($_SERVER['HTTP_FORWARDED']))
        $ipaddress = $_SERVER['HTTP_FORWARDED'];
    else if (isset($_SERVER['REMOTE_ADDR']))
        $ipaddress = $_SERVER['REMOTE_ADDR'];
    else
        $ipaddress = 'UNKNOWN';
    return $ipaddress;
}

function loginLog($user_id, $status) {
    global $db;
    $ip = get_client_ip();
    // Prevent SQL Injection
    $db->bind("user_id", $user_id);
    $db->bind("ip", $ip);
    $db->bind("status", $status);
    // Execute
    $db->query("INSERT INTO login_log(user_id,date,ip_address,status) VALUES(:user_id,CURRENT_TIMESTAMP,:ip,:status)");
}

$app->post('/login/auth', function (Request $request)  {
    global $db;
    $username = $request->get('username');
    $password = $request->get('password');

    // Prevent SQL Injection
    $db->bind("username", $username);

    // Execute
    $users = $db->query("SELECT * FROM users WHERE username= :username && status = 1");
    if (count($users) > 0) {
        if (password_verify($password, $users[0]["password"])) {
            $_SESSION["username"] = $username;
            $_SESSION["user_id"] = $users[0]["user_id"];
            $_SESSION["role"] = $users[0]["role"];
            $_SESSION["group_id"] = $users[0]["group_id"];
            if($users[0]["role"] > 0){
                $_SESSION["company_id"] = getCompany($users[0]["user_id"]);
                $_SESSION["branch_id"] = getBranch($users[0]["user_id"]);
            }else{
                $_SESSION["company_id"] = 0;
                $_SESSION["branch_id"] = 0;
            }
            //loginLog($_SESSION["user_id"], "SUCCESS");
            return new Response('Success', 200);
        }
        else{
            loginLog($username, "FAILED");
            return new Response('Failed', 401);
        }
    } else {
        loginLog($username, "FAILED");
        return new Response('Failed. User not Found.', 401);
    }
});
$app->post('/forgot-password/reset', function (Request $request)  {
    global $db;
    global $global_env;
    global $twilio;

    $username = $request->get('username');

    $db->bind("username", $username);
    $users = $db->query("SELECT * FROM users WHERE username= :username  && status = 1");
    
    if (count($users) > 0) {
        # generate unique reset token 
        $reset_token = md5(uniqid($users[0]["user_id"], true));

        # update user with reset token 
        $db->bind('reset_token', $reset_token);
        $db->bind('username', $username);
        $update = $db->query("UPDATE users SET reset_token = :reset_token WHERE username = :username");
        if ($update) {
            # password recovery link
            $recovery_link = "https://app.izyim.com/reset-password?reset-token=".$reset_token;
            # send link to SMS
           	$twilio->messages->create(
				$username,
				array(
					'from' => '+601130115722',
					'body' => 'Your IZIM password recovery link ' .$recovery_link. ' '
				)
			);
            // end todo 
            return new Response('Success', 200);
        } else {
            return new Response('Failed', 201);
        }
    } else {

        return new Response('Failed', 201);
    }
});

$app->post('/reset-password/reset', function (Request $request)  {
    global $db;
	global $global_env;
    $password = $request->get('password');
    $confirm_password = $request->get('confirm_password');
    $reset_token = $request->get('reset_token');

    # check if token exist 
    $db->bind("reset_token", $reset_token);
    $users = $db->query("SELECT * FROM users WHERE status = 1 && reset_token= :reset_token");
    
    if (count($users) > 0) {
        # check confirm password
        if ($password != $confirm_password){
            return new Response('Failed, password and confirm is not the same', 201);
        }
        # update user password
        $e_password = password_hash($password, PASSWORD_DEFAULT); 
        $db->bind('password', $e_password);
        $db->bind('reset_token', $reset_token);
        $update = $db->query("UPDATE users SET password = :password WHERE reset_token = :reset_token");

        if ($update) {
            return new Response('Success', 200);
        } else {
            return new Response('Failed', 201);
        }
    } else {
        return new Response('Invalid token.', 201);
    }
});

$app->post('/register/check', function(Request $request) {
        global $db;
        $username = $request->get('username');
        $db->bind('username', $username);
        $row = $db->query("SELECT user_id FROM users WHERE username = :username");
        if (count($row) > 0) {
            $status = 'false';
        } else {
            $status = 'true';
        }
        echo $status;
        return '';
    });
$app->post('/register/check-verification', function(Request $request) {
        global $db;
        $verification_no = $request->get('verification_no');
        $username = $request->get('username');
        if (preg_match("/^[0-9]{10}$/", $username)){
            $db->bind('username', $username);
            $db->bind('verification_no', (string)$verification_no);
            $row = $db->query("SELECT * FROM mobile_verifications WHERE mobile = :username AND verification_code = :verification_no");
            if (count($row) > 0) {
                $status = 'true';
            } else {
                $status = 'false';
            }
            echo $status;
            return '';
        }
        else{
            $status = 'incorrect phone number';
            return '';
        }
    });

$app->post('/register/send-verification', function(Request $request) {
        global $db;
        global $twilio;
        
		$username = $request->get('username');
		$verification_code = mt_rand(100000,999999);
		
        $db->bind('mobile', $username);
        $db->bind('verification_code', $verification_code);
		$userReg = $db->query("INSERT INTO mobile_verifications(mobile,verification_code) VALUES(:mobile,:verification_code)");
		
        if ($userReg) {
			$twilio->messages->create(
				$username,
				array(
					'from' => '+601130115722',
					'body' => 'Your IZIM verification code is ' .$verification_code . ' '
				)
			);
			return new Response("SUCCESS", 200);
        } else {
			return new Response("FAILED", 400);
        }
    });
$app->post('/register/submit', function(Request $request) {
        global $db;
        global $global_env;
        global $app;
        
        // Catch the GET
        $username = $request->get('username');
        $raw_password = $request->get('password');    
        $group_id = $request->get('role');    
		$created_on = date("Y-m-d H:i:s");
        
        // Password encoding
        $password = password_hash($raw_password, PASSWORD_DEFAULT);

        // END
        // Check if the request match the conditional
        if (!userExist($username) && groupExist($group_id) && is_numeric($group_id)) {
            // PREPARE
			
			$db->bind("username", $username);
            $db->bind("password", $password);
            $db->bind("group_id", $group_id);
            $db->bind("created_on", $created_on);
			
			
            // Record to users to get the user id
            $userReg = $db->query("INSERT INTO users(username,password,created_on,role,group_id) VALUES(:username,:password,:created_on,'1',:group_id)");
            $user_id = $db->lastInsertId();
            if ($userReg && $user_id) {
                // Record User Detail
                // PREPARE
                $db->bind("user_id", $user_id);
				
                // EXECUTE
                $userDetRec = $db->query("INSERT INTO user_detail(user_id) VALUES(:user_id)");
                                
                if ($userDetRec) {
					// action_log($_SESSION['user_id'], "User Registration " . $first_name . " " . $last_name ." (" .$username . ")", "SUCCESS");
                    return new Response("SUCCESS", 200);
                } else {
					// action_log($_SESSION['user_id'], "User Registration " . $first_name . " " . $last_name ." (" .$username . ")", "FAILED");
                    return new Response('FAILED', 400);
                }
            }
        }
        else{
            return new Response('FAILED', 400);
        }
    });
$app->get('/login', function() {
    global $app;
    $title = "IZYIM - Login";
    if (is_login()) {
		return $app->redirect('/dashboard');
    } else {
        require_once __DIR__ . '/../tpl/login.php';
        return "";
    }
});

$app->get('/forgot-password', function()  {
    global $app;
    $title = "IZYIM - Reset Password";
    if (is_login()) {
        return $app->redirect('/dashboard');
    } else {
        require_once __DIR__ . '/../tpl/forgot.php';
        return "";
    }
});

$app->get('/reset-password', function()  {
    global $app;
    $title = "IZYIM - Reset Password";
    if (is_login()) {
        return $app->redirect('/dashboard');
    } else {
        require_once __DIR__ . '/../tpl/resetpwd.php';
        return "";
    }
});

$app->get('/register', function()  {
    global $app;
    $title = "IZYIM - Registration";
    if (is_login()) {
        return $app->redirect('/dashboard');
    } else {
        require_once __DIR__ . '/../tpl/register.php';
        return "";
    }
});
$app->get('/logout', function() {
    global $app;
    echo "Successfully logged out. </br>";
    session_destroy();
    return $app->redirect('/login');
});

