<?php
// The Green Spirit's Angry Birds Vuela Tazos service file
// This file handles most of the game's mechanics.
// Because why not?

// start database stuff
$host = "pma.ct8.pl";
$user = "m37488_default";
$pass = "thegreenspiritisc00L";
$db = 'm37488_angrybirds_pepsicomx';

// init PDO
try {
	$pdo = new PDO("mysql:host=$host;dbname=$db", $user, $pass);
	$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e){
	echo "Connection failed: " . $e->getMessage();
}

// users table functions
function addUserToDatabase($pdo, $nickName, $password, $id, $age, $fullName, $zipcode, $gender, $subscribed) {
    $sql = "INSERT INTO users (nickName, password, id, age, fullName, zipcode, gender, subscribed) VALUES (:nickName, :password, :id, :age, :fullName, :zipcode, :gender, :subscribed)";
    try {
        $stmt = $pdo->prepare($sql);
        $stmt->execute([
			'nickName'=>$nickName,
            'password'=>$password,
			'id'=>$id,
			'age'=>$age,
			'fullName'=>$fullName,
			'zipcode'=>$zipcode,
			'gender'=>$gender,
			'subscribed'=>$subscribed,
        ]);
    } catch (Exception $e) {
        echo $e;
    }
}

function getUserFromDatabase($pdo, $id) {
    $sql = "SELECT * FROM users WHERE id=:id";
    try {
        $stmt = $pdo->prepare($sql);
        $stmt->execute([
            'id'=>$id,
        ]);
        $data = $stmt->fetch(PDO::FETCH_ASSOC);
        return $data;
    } catch (Exception $e) {
        echo $e;
    }
}

function checkNickNameHasBeenTaken($pdo, $nickName) {
    $sql = "SELECT * FROM users WHERE nickName=:nickName";
    try {
        $stmt = $pdo->prepare($sql);
        $stmt->execute(['nickName'=>$nickName]);
		$data = $stmt->fetch(PDO::FETCH_ASSOC);
		if ($data) {
			return true;
		}
    } catch (Exception $e) {
        echo $e;
    }
}

// leveldata table functions
function addUserToLevelDatabase($pdo, $id, $level1score, $level2score, $level3score, $level4score, $level5score, $level6score, $level4unlocked, $level5unlocked, $level6unlocked) {
    $sql = "INSERT INTO leveldata (id, level1score, level2score, level3score, level4score, level5score, level6score, level4unlocked, level5unlocked, level6unlocked) VALUES (:id, :level1score, :level2score, :level3score, :level4score, :level5score, :level6score, :level4unlocked, :level5unlocked, :level6unlocked)";
    try {
        $stmt = $pdo->prepare($sql);
        $stmt->execute([
			'id'=>$id,
			'level1score'=>$level1score,
			'level2score'=>$level2score,
			'level3score'=>$level3score,
			'level4score'=>$level4score,
			'level5score'=>$level5score,
			'level6score'=>$level6score,
			'level4unlocked'=>$level4unlocked,
			'level5unlocked'=>$level5unlocked,
			'level6unlocked'=>$level6unlocked,
        ]);
    } catch (Exception $e) {
        echo $e;
    }
}

function unlockLevel($pdo, $id, $levelId) {
	if ($levelId == '1-4') {
		$levelToUnlock = 'level4unlocked';
	}
	else if ($levelId == '1-5') {
		$levelToUnlock = 'level5unlocked';
	}
	else if ($levelId == '1-6') {
		$levelToUnlock = 'level6unlocked';
	}
	
    $sql = "UPDATE leveldata SET {$levelToUnlock}=:{$levelToUnlock} WHERE id=:id";
    try {
        $stmt = $pdo->prepare($sql);
        $stmt->execute([
            'id'=>$id,
            "$levelToUnlock"=>true,
        ]);
        $data = $stmt->fetch(PDO::FETCH_ASSOC);
        return $data;
    } catch (Exception $e) {
        echo $e;
    }
}

function submitScore($pdo, $id, $levelId, $score) {
	if ($levelId == '1-1') {
		$levelToSubmit = 'level1score';
	}
	else if ($levelId == '1-2') {
		$levelToSubmit = 'level2score';
	}
	else if ($levelId == '1-3') {
		$levelToSubmit = 'level3score';
	}
	else if ($levelId == '1-4') {
		$levelToSubmit = 'level4score';
	}
	else if ($levelId == '1-5') {
		$levelToSubmit = 'level5score';
	}
	else if ($levelId == '1-6') {
		$levelToSubmit = 'level6score';
	}
	
    $sql = "UPDATE leveldata SET {$levelToSubmit}=:{$levelToSubmit} WHERE id=:id";
    try {
        $stmt = $pdo->prepare($sql);
        $stmt->execute([
            'id'=>$id,
            "$levelToSubmit"=>$score,
        ]);
        $data = $stmt->fetch(PDO::FETCH_ASSOC);
        return $data;
    } catch (Exception $e) {
        echo $e;
    }
}

function getUserFromLevelDatabase($pdo, $id) {
    $sql = "SELECT * FROM leveldata WHERE id=:id";
    try {
        $stmt = $pdo->prepare($sql);
        $stmt->execute([
            'id'=>$id,
        ]);
        $data = $stmt->fetch(PDO::FETCH_ASSOC);
        return $data;
    } catch (Exception $e) {
        echo $e;
    }
}

function getAllUsersFromLevelDatabase($pdo) {
    $sql = "SELECT * FROM leveldata";
    try {
        $stmt = $pdo->prepare($sql);
        $stmt->execute();
        $data = $stmt->fetchAll(PDO::FETCH_ASSOC);
        return $data;
    } catch (Exception $e) {
        echo $e;
    }
}
// end database stuff

// do not display php errors or else it will cause issues!!
ini_set('display_errors', 0);

// start the actual function of this file (todo: find out if this is needed)
session_start();

// Decode base64-encrypted json data that the game sends
$requestData = $_POST['json'];
$requestData = base64_decode($requestData);
$requestData = json_decode($requestData, true);

// if type is registerPlayer, then add player to database
if ($requestData['type'] == 'registerPlayer') {
	// Add placeholder values if optional information isn't there (except subscribing)
	
	// Define full name
	if ($requestData['player']['name']) {
		$fullName = $requestData['player']['name'];
	}
	else {
		$fullName = "unspecified";
	}
	
	// Define zipcode
	if ($requestData['player']['zipcode']) {
		$zipcode = $requestData['player']['zipcode'];
	}
	else {
		$zipcode = "unspecified";
	}
	
	// Define genders
	if ($requestData['player']['gender'] == 'm') {
		$gender = 'male';
	}
	else if ($requestData['player']['gender'] == 'f') {
		$gender = 'female';
	}
	else {
		$gender = "unspecified";
	}
	
	$checker = checkNickNameHasBeenTaken($pdo, $requestData['player']['nickName']);
	$playerData = getUserFromDatabase($pdo, $requestData['player']['id']);
	
	// if nickname is taken, then send an error telling that the nickname is taken
	if ($checker) {
		echo json_encode(array('error' => 'FIELD_NOT_VALID', 'field' => 'nickName'));
	}
	// if email is taken, then send an error telling that the email is taken
	else if ($playerData) {
		echo json_encode(array('error' => 'PLAYER_ID_USED'));
	}
	else {
		addUserToDatabase($pdo, $requestData['player']['nickName'], $requestData['player']['password'], $requestData['player']['id'], $requestData['player']['age'], $fullName, $zipcode, $gender, $requestData['player']['marketing']);
		addUserToLevelDatabase($pdo, $requestData['player']['id'], 0, 0, 0, 0, 0, 0, false, false, false);
		echo json_encode(array('security' => 'success'));
	}
}
// if type is login, then try to log player in
else if ($requestData['type'] == 'login') {
	$playerData = getUserFromDatabase($pdo, $requestData['player']['id']);
	$playerLevelData = getUserFromLevelDatabase($pdo, $requestData['player']['id']);
	
	if ($playerData['password'] == $requestData['player']['password']) {
		// Update level data after login
		$levelProfile = array();
		
		// since levels 1-1 to 1-3 are already unlocked in base game, we can just set unlocked to true
		$level1 = array('levelId' => '1-1', 'unlocked' => true, 'score' => $playerLevelData['level1score']);
		array_push($levelProfile, $level1);
		$level2 = array('levelId' => '1-2', 'unlocked' => true, 'score' => $playerLevelData['level2score']);
		array_push($levelProfile, $level2);
		$level3 = array('levelId' => '1-3', 'unlocked' => true, 'score' => $playerLevelData['level3score']);
		array_push($levelProfile, $level3);
		$level4 = array('levelId' => '1-4', 'unlocked' => $playerLevelData['level4unlocked'], 'score' => $playerLevelData['level4score']);
		array_push($levelProfile, $level4);
		$level5 = array('levelId' => '1-5', 'unlocked' => $playerLevelData['level5unlocked'], 'score' => $playerLevelData['level5score']);
		array_push($levelProfile, $level5);
		$level6 = array('levelId' => '1-6', 'unlocked' => $playerLevelData['level6unlocked'], 'score' => $playerLevelData['level6score']);
		array_push($levelProfile, $level6);
		
		echo json_encode(array('security' => 'success', 'nickName' => $playerData['nickName'], 'id' => $requestData['player']['id'], 'levelProfile' => $levelProfile));
	}
	else {
		echo json_encode(array('error' => 'PLAYER_INVALID_LOGIN'));
	}
}
// if type is assignCode, then try to unlock the level
else if ($requestData['type'] == 'assignCode') {
	$playerId = $requestData['player']['id'];
	$levelId = $requestData['levelId'];
	
	$playerData = getUserFromDatabase($pdo, $playerId);
	$playerLevelData = getUserFromLevelDatabase($pdo, $playerId);
	
	// Update level data
	$levelProfile = array();
	
	// since levels 1-1 to 1-3 are already unlocked in base game, we can just set unlocked to true
	$level1 = array('levelId' => '1-1', 'unlocked' => true, 'score' => $playerLevelData['level1score']);
	array_push($levelProfile, $level1);
	$level2 = array('levelId' => '1-2', 'unlocked' => true, 'score' => $playerLevelData['level2score']);
	array_push($levelProfile, $level2);
	$level3 = array('levelId' => '1-3', 'unlocked' => true, 'score' => $playerLevelData['level3score']);
	array_push($levelProfile, $level3);
	
	$level4 = array('levelId' => '1-4', 'unlocked' => $playerLevelData['level4unlocked'], 'score' => $playerLevelData['level4score']);
	$level5 = array('levelId' => '1-5', 'unlocked' => $playerLevelData['level5unlocked'], 'score' => $playerLevelData['level5score']);
	$level6 = array('levelId' => '1-6', 'unlocked' => $playerLevelData['level6unlocked'], 'score' => $playerLevelData['level6score']);
	
	
	if ($requestData['code']/* == ''*/ and $levelId == '1-4') {
		// Update level 4 to unlocked state
		$level4 = array('levelId' => $levelId, 'unlocked' => true, 'score' => $playerLevelData['level4score']);
		
		// Push all of the special levels to levelProfile
		array_push($levelProfile, $level4);
		array_push($levelProfile, $level5);
		array_push($levelProfile, $level6);
		
		unlockLevel($pdo, $playerId, $levelId);
		
		// Finalize data
		echo json_encode(array('security' => $requestData['player']['security'], 'nickName' => $playerData['nickName'], 'id' => $playerId, 'levelProfile' => $levelProfile));
	}
	else if ($requestData['code']/* == ''*/ and $levelId == '1-5') {
		// Update level 5 to unlocked state
		$level5 = array('levelId' => $levelId, 'unlocked' => true, 'score' => $playerLevelData['level5score']);
		
		// Push all of the special levels to levelProfile
		array_push($levelProfile, $level4);
		array_push($levelProfile, $level5);
		array_push($levelProfile, $level6);
		
		unlockLevel($pdo, $playerId, $levelId);
		
		// Finalize data
		echo json_encode(array('security' => $requestData['player']['security'], 'nickName' => $playerData['nickName'], 'id' => $playerId, 'levelProfile' => $levelProfile));
	}
	else if ($requestData['code']/* == ''*/ and $levelId == '1-6') {
		// Update level 6 to unlocked state
		$level6 = array('levelId' => $levelId, 'unlocked' => true, 'score' => $playerLevelData['level6score']);
		
		// Push all of the special levels to levelProfile
		array_push($levelProfile, $level4);
		array_push($levelProfile, $level5);
		array_push($levelProfile, $level6);
		
		unlockLevel($pdo, $playerId, $levelId);
		
		// Finalize data
		echo json_encode(array('security' => $requestData['player']['security'], 'nickName' => $playerData['nickName'], 'id' => $playerId, 'levelProfile' => $levelProfile));
	}
	else {
		echo json_encode(array('error' => 'CODE_NOT_EXIST'));
	}
}
// if type is highscore, then load scores
else if ($requestData['type'] == 'highscore') {
	$highscores = array();
	
	$allUsers = getAllUsersFromLevelDatabase($pdo);
	
	// Get scores from level 5, 6 and 7 (because 1, 2, 3 does not show highscores)
	foreach ($allUsers as $key => $userData) {
		if ($requestData['levelId'] == '1-4') {
			$playerData = getUserFromDatabase($pdo, $userData['id']);
			
			$playerScore = array('nickName' => $playerData['nickName'], 'score' => $userData['level4score']);
			array_push($highscores, $playerScore);
		}
		else if ($requestData['levelId'] == '1-5') {
			$playerData = getUserFromDatabase($pdo, $userData['id']);
			
			$playerScore = array('nickName' => $playerData['nickName'], 'score' => $userData['level5score']);
			array_push($highscores, $playerScore);
		}
		else if ($requestData['levelId'] == '1-6') {
			$playerData = getUserFromDatabase($pdo, $userData['id']);
			
			$playerScore = array('nickName' => $playerData['nickName'], 'score' => $userData['level6score']);
			array_push($highscores, $playerScore);
		}
	}
	
	// Sort highscores
	function highscoreSort($a, $b){
		if($a['score'] == $b['score']) return 0;
		return $a['score'] > $b['score'] ? -1 : 1;
	}
	
    usort($highscores, 'highscoreSort');
	echo json_encode($highscores);
}
// if type is updateLevelProfile, then submit score
else if ($requestData['type'] == 'updateLevelProfile') {
	$playerId = $requestData['player']['id'];
	$levelId = $requestData['levelProfile']['levelId'];
	$score = $requestData['levelProfile']['score'];
	
	$playerLevelData = getUserFromLevelDatabase($pdo, $playerId);
	
	if ($levelId == '1-1') {
		$levelToSubmit = 'level1score';
	}
	else if ($levelId == '1-2') {
		$levelToSubmit = 'level2score';
	}
	else if ($levelId == '1-3') {
		$levelToSubmit = 'level3score';
	}
	else if ($levelId == '1-4') {
		$levelToSubmit = 'level4score';
	}
	else if ($levelId == '1-5') {
		$levelToSubmit = 'level5score';
	}
	else if ($levelId == '1-6') {
		$levelToSubmit = 'level6score';
	}
	
	if ($playerLevelData[$levelToSubmit] < $score) {
		submitScore($pdo, $playerId, $levelId, $score);
	}
}
?>