<?php
include 'common.php';

function verifyGoogleToken($id_token, $user_sub)
{
	$client_id = "45867005211-n1t2dmrcn8h6ug5pbljqm72uo3uqr9mg.apps.googleusercontent.com";

	$url = "https://oauth2.googleapis.com/tokeninfo?id_token=" . $id_token;
	$response = file_get_contents($url);
	$data = json_decode($response, true);

	if (isset($data['aud']) && $data['aud'] === $client_id && isset($data['sub']) && $data['sub'] === $user_sub) {
		return true;
	} else {
		return false;
	}
}

function PrintDebug($response, $error)
{
	
	 $isXmlHttpRequest = (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest');
	($isXmlHttpRequest) ? header('Content-type: application/json') : header('Content-type: text/plain');
 
	echo json_encode(array('result'=>$response,'error'=>$error));
	exit; 
}

function IsLocalhost()
{
	$remote_addr = $_SERVER['REMOTE_ADDR'];
	return ($remote_addr === '127.0.0.1' || $remote_addr === '::1' || $remote_addr === 'localhost');
}

function IsBlockAccount($dbhandle, $account_id)
{

	$stmt = $dbhandle->prepare("select count(*) as cnt from block_account_log where user_id=? and is_account_block=1");	
	$stmt->bind_param("s", $account_id);
	$stmt->execute();
	$result = $stmt->get_result();
	$num = $result->fetch_assoc();
	
	mysqli_stmt_free_result($stmt);
	
	if($num["cnt"] > 0)
	{
		return true;
	}
	else
	{
		return false;
	}
}



function GetClientVersion($dbhandle, $account_id)
{
	$stmt = $dbhandle->prepare("select version from account where user_id=?");	
	$stmt->bind_param("s", $account_id);
	$stmt->execute();
	$result = $stmt->get_result();
	$row = $result->fetch_assoc();
	
	mysqli_stmt_free_result($stmt);
	
	return $row["version"] ;
}

function GetWalletId($dbhandle, $account_id)
{
	$stmt = $dbhandle->prepare("select wallet_id from account where user_id=?");	
	$stmt->bind_param("s", $account_id);
	$stmt->execute();
	$result = $stmt->get_result();
	$row = $result->fetch_assoc();
	
	mysqli_stmt_free_result($stmt);
	
	return $row["wallet_id"] ;
}



function CharacterListCheck($dbhandle, $account_id)
{


	$stmt = $dbhandle->prepare("select count(*) as cnt from character_list where user_id=? and deleted=false");	
	$stmt->bind_param("s", $account_id);
	$stmt->execute();
	$result = $stmt->get_result();
	$num = $result->fetch_assoc();
	
	mysqli_stmt_free_result($stmt);
	
	if($num["cnt"] > 0)
	{
		return "LOGIN_OK";
	}
	else
	{
		return "LOGIN_OK_CHAR_NOT_EXIST";
	}
}

function IsExistServerGroup($dbhandle, $server_group_id, $server_version)
{
	$stmt = $dbhandle->prepare("select count(*) as cnt from server_list where server_group_id=? and server_version=?");	
	$stmt->bind_param("ii", $server_group_id,$server_version);
	$stmt->execute();
	$result = $stmt->get_result();
	$num = $result->fetch_assoc();
	
	mysqli_stmt_free_result($stmt);
	
	if($num["cnt"] > 0)
	{
		return true;
	}
	else
	{
		return false;
	}
}

function UpdateLoinKeyOnSameDevice($dbhandle, $new_login_key, $device_unique_id)
{
	if($device_unique_id == "")
	{
		return false;
	} 


	$now = new DateTime();
	$now->setTimezone(new DateTimeZone('UTC'));
	$login_time =  date_format($now, "Y-m-d H:i:s");
	
	
	$stmt = $dbhandle->prepare("update account set login_key=?, login_time=? where device_unique_id=?");
	$stmt->bind_param("sss", $new_login_key, $login_time, $device_unique_id);
	$result = $stmt->execute();
	$stmt->close();
	
	
	if($result)
	{
		return true;
	}
	else
	{
		return false;
	}
}

function CreateRandomLoginKey()
{
	$login_key = rand();
	$login_key = md5($login_key);
	return $login_key;

}

function UpdateLoginKey($dbhandle, $account_id, $ip, $version, $lang, $platform,$server_group_id, $device_unique_id)
{
	
	$login_key = CreateRandomLoginKey();
	
	$now = new DateTime();
	$now->setTimezone(new DateTimeZone('UTC'));
	$login_time =  date_format($now, "Y-m-d H:i:s");
	
	
	$stmt = $dbhandle->prepare("update account set login_key=?, ip=? , login_time=? , version=? , lang=? , server_group_id=?, device_unique_id=? where user_id=?");
	$stmt->bind_param("sssssiss", $login_key, $ip, $login_time,$version, $lang, $server_group_id, $device_unique_id, $account_id);
	$result = $stmt->execute();
	$stmt->close();
	
	
	if($result)
	{
		return $login_key;
	}
	else
	{
		$login_key = "";
		
	}
		
	
	return $login_key;
}



function CreateAccountID($dbhandle, $user_id,$ip, $version, $lang, $platform, $server_group_id, $wallet_id, $device_unique_id)
{

	//Select DB
	$db_selected = mysqli_select_db($dbhandle, DB_NAME)
	or die("Could not select db");

	// check character count limit
	$select_query = "select count(*) from account";
	$result_set = @mysqli_query($dbhandle, $select_query);
	$row = @mysqli_fetch_row($result_set);
	
	
	$login_key = CreateRandomLoginKey();

	
	$now = new DateTime();
	//$now->setTimezone(new DateTimeZone('Asia/Seoul'));
	$login_time =  date_format($now, "Y-m-d H:i:s");

	$stmt = $dbhandle->prepare("insert into account (user_id,user_pwd,platform,login_key, ip, is_guest, login_time, version, lang,server_group_id, wallet_id, device_unique_id) values(?,'null',?,?,?,0,?,?,?,?,?,?)");
	$stmt->bind_param("sssssssiss", $user_id, $platform, $login_key, $ip, $login_time,$version,$lang,$server_group_id, $wallet_id, $device_unique_id);
	$result = $stmt->execute();
	$stmt->close();
	
	if($result)
	{
		$db_success = "yes";
	}
	else
	{
		$db_success = "no";
		
	}
	
    return array($user_id, $login_key, $db_success);
}



function LoginQuery($account_id, $ip, $version,$lang, $platform, $server_group_id, $server_version, $wallet_id, $device_unique_id)
{
	$dbhandle = DB_Connect();
	
	//Select DB
	$db_selected = mysqli_select_db($dbhandle, DB_NAME)
	or die("Could not select db");
	
	
	if(IsBlockAccount($dbhandle,$account_id))
	{
		
		$response = "LOGIN_FAILED";
		$new_login_key = "";
		$error = "Blocked";
	
		$isXmlHttpRequest = (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest');
		($isXmlHttpRequest) ? header('Content-type: application/json') : header('Content-type: text/plain');
		 
		 $notice = "Blocked";
		 
		echo json_encode(array('result'=>$response,'account_id'=>$account_id, 'login_key'=>$new_login_key,'error'=>$error, 'notice'=>$notice,));
		
		mysqli_close($dbhandle);
		exit;
	}
	
	
	///해당 서버 그룹이 존재하는지. 서버통합시에는 존재하지 않을수 있다.
	if(!IsExistServerGroup($dbhandle, $server_group_id, $server_version))
	{
		$response = "NOT_EXIST_SERVER_GROUP";
		$new_login_key = "";
		$error = "NotExistServerGroup";
	
		$isXmlHttpRequest = (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest');
		($isXmlHttpRequest) ? header('Content-type: application/json') : header('Content-type: text/plain');
		 
		
		$notice = "The server is either consolidated or does not exist. Please select another server.";
		
		if($lang == 'kr') 
		{
			$notice = "서버가 통합되었거나, 존재하지 않습니다. 다른 서버를 선택해주세요.";
		}
		 
		echo json_encode(array('result'=>$response,'account_id'=>$account_id, 'login_key'=>$new_login_key,'error'=>$error, 'notice'=>$notice));
		
		mysqli_close($dbhandle);
		exit;
	}
	
	


    $stmt = $dbhandle->prepare("select count(*) as cnt,user_id,login_key from account where user_id=?");	
	$stmt->bind_param("s", $account_id);
	$stmt->execute();
	$result = $stmt->get_result();


	$new_login_key = "";
	$error = "";
	$user_wallet_id = "";
	
	//
	$CRYSTAL_EVENT_ID = 1;
	
	if($row = $result->fetch_assoc())
	{
		if($row["cnt"] > 0)
		{
			$response = CharacterListCheck($dbhandle, $account_id);	
			//임시로 주석 처리 
			if($response != "LOGIN_FAILED")
			{
				$new_login_key = UpdateLoginKey($dbhandle, $account_id, $ip, $version, $lang, $platform,$server_group_id, $device_unique_id);
				if($new_login_key == "")
				{
					$response = "LOGIN_FAILED";
					$error = "ERROR : 042";
				}
				else
				{
					UpdateLoinKeyOnSameDevice($dbhandle, $new_login_key, $device_unique_id);
				}

				$user_wallet_id = GetWalletId($dbhandle, $account_id);
				
			}
		}
		else	// 계정이없다. 생성 필요  /* 구글 토큰 검증 필요 */		
		{
			
			list($account_id,$login_key,$db_success) = CreateAccountID($dbhandle, $account_id,$ip, $version, $lang, $platform,$server_group_id, $wallet_id, $device_unique_id);
			if($db_success == "yes")
			{
				$new_login_key = $login_key;
				$response = "LOGIN_OK";
				$error = "";
				
				$user_wallet_id = $wallet_id;
				
				UpdateLoinKeyOnSameDevice($dbhandle, $new_login_key, $device_unique_id);
				
			}
			else
			{
				$response = "LOGIN_FAILED";
				$error = "ERROR : Failed to create id ";
			}
			
			
		}		
	}
	
	mysqli_stmt_free_result($stmt);
	
	
	$now = new DateTime();
	//$now->setTimezone(new DateTimeZone('Asia/Seoul'));
	$login_log_time =  date_format($now, "Y-m-d H:i:s");

	$stmt = $dbhandle->prepare("insert into login_log (user_id,log_time, lang) values(?,?,?)");
	$stmt->bind_param("sss", $account_id, $login_log_time,$lang);
	$result = $stmt->execute();
	$stmt->close();
	
		
	
	$error=$version;
	

    mysqli_close($dbhandle);
	
	
 
    $isXmlHttpRequest = (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest');
    ($isXmlHttpRequest) ? header('Content-type: application/json') : header('Content-type: text/plain');
 
    echo json_encode(array('result'=>$response,'account_id'=>$account_id,'login_key'=>$new_login_key, 'server_group_id'=>$server_group_id,'wallet_id'=>$user_wallet_id,'error'=>$error));

}

function verifyGoogleToken2($id_token, $user_sub)
{
    $client_id = "45867005211-n1t2dmrcn8h6ug5pbljqm72uo3uqr9mg.apps.googleusercontent.com";
    $url = "https://oauth2.googleapis.com/tokeninfo?id_token=" . $id_token;

    // HTTP 에러가 발생해도 내용을 가져오기 위한 컨텍스트 설정
    $options = [
        'http' => [
            'ignore_errors' => true,
            'method' => 'GET'
        ]
    ];
    $context = stream_context_create($options);
    $response = file_get_contents($url, false, $context);
    
    if ($response === false) {
        return ["success" => false, "message" => "Failed to connect to API"];
    }

    $data = json_decode($response, true);

    // // 1. 구글 API 자체 에러 체크 (만료 포함)
    // if (isset($data['error'])) {
    //     if (strpos($data['error_description'], 'expired') !== false) {
    //         return ["success" => false, "message" => "Token expired", "code" => "EXPIRED"];
    //     }
    //     return ["success" => false, "message" => "Invalid token: " . $data['error_description']];
    // }

	if (isset($data['error'])) {
        // 이 메시지를 유니티 콘솔에서 확인하세요
        return [
            "success" => false, 
            "message" => "Google API Error: " . ($data['error_description'] ?? $data['error']),
            "raw" => $data // 전체 응답 포함
        ];
    }
	
    // 2. Client ID (aud) 검증
    if ($data['aud'] !== $client_id) {
        return ["success" => false, "message" => "Client ID does not match"];
    }

    // 3. 사용자 고유 ID (sub) 검증
    if ($data['sub'] !== $user_sub) {
        return ["success" => false, "message" => "User information does not match"];
    }

    // 4. 모든 검증 통과
    return ["success" => true, "message" => "Authentication successful"];
}


$json = json_decode(file_get_contents('php://input'));
$account_id = getRequestField($json, 'account_id');
$id_token = getRequestField($json, 'id_token');
$version = getRequestField($json, 'version');
$lang = getRequestField($json, 'lang');
$check_sum = getRequestField($json, 'check_sum');
$platform = getRequestField($json, 'platform');
$server_group_id = getRequestField($json, 'server_group_id');
$server_version = getRequestField($json, 'server_version');
$wallet_id = getRequestField($json, 'wallet_id');
$device_unique_id = getRequestField($json, 'device_unique_id');

function getRequestField($json, $field)
{
	if (!isset($json->$field)) return "";
	$val = $json->$field;
	if (is_string($val) && strtolower($val) === 'n/a') return "";
	return $val;
}
	
// account_id is required
if (empty($account_id))
{
	$response = "LOGIN_FAILED";
	$new_login_key = "";
	$server_group_id = 0;
	$error = "login error(110)";
	$isXmlHttpRequest = (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest');
	($isXmlHttpRequest) ? header('Content-type: application/json') : header('Content-type: text/plain');

	echo json_encode(array('result'=>$response,'account_id'=>$account_id, 'login_key'=>$new_login_key,'error'=>$error));
	return;
}
if(!CheckSum($account_id,$version,$check_sum))
{	
	$response = "LOGIN_FAILED";
	$new_login_key = "";
	$server_group_id = 0;
	$error = "login error(108)";
	$isXmlHttpRequest = (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest');
    ($isXmlHttpRequest) ? header('Content-type: application/json') : header('Content-type: text/plain');
     
	 
    echo json_encode(array('result'=>$response,'account_id'=>$account_id, 'login_key'=>$new_login_key,'error'=>$error));
	return;
}

if($account_id === 'test' && !VerifyTestAccountIP())
{
	$response = "LOGIN_FAILED";
	$new_login_key = "";
	$server_group_id = 0;
	$error = "login error(111) => Unauthorized IP for test account.";
	
	$isXmlHttpRequest = (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest');
	($isXmlHttpRequest) ? header('Content-type: application/json') : header('Content-type: text/plain');	

	echo json_encode(array('result'=>$response,'account_id'=>$account_id, 'login_key'=>$new_login_key,'error'=>$error));
	return;
}

if(!IsLocalhost() && $account_id !== 'test')
{
	if(empty($id_token))
	{
		$response = "LOGIN_FAILED";
		$new_login_key = "";
		$server_group_id = 0;
		$error = "login error(109)";
		$isXmlHttpRequest = (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest');
	    ($isXmlHttpRequest) ? header('Content-type: application/json') : header('Content-type: text/plain');
	     
	    echo json_encode(array('result'=>$response,'account_id'=>$account_id, 'login_key'=>$new_login_key,'error'=>$error));
		return;
	}

	// if(!verifyGoogleToken($id_token, $account_id))
	// {
	// 	$response = "LOGIN_FAILED";
	// 	$new_login_key = "";
	// 	$server_group_id = 0;
	// 	$error = "login error(110)";
	// 	$isXmlHttpRequest = (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest');
	//     ($isXmlHttpRequest) ? header('Content-type: application/json') : header('Content-type: text/plain');
	     
	//     echo json_encode(array('result'=>$response,'account_id'=>$account_id, 'login_key'=>$new_login_key,'error'=>$error));
	// 	return;
	// }
	$result = verifyGoogleToken2($id_token, $account_id);	
	if(!$result['success'])
	{
		$error = "login error(110) => Authentication failed.";

		if (isset($result['code']) && $result['code'] === "EXPIRED") {
			$error = "login error(110) => Token expired. Please log in again.";
		} else {
			// result['message']가 한글일 수 있으므로 상황에 따라 직접 영문 메시지를 넣거나 
			// 아래처럼 전달받은 메시지를 결합합니다.
			$error = "login error(110) => Error: " . ($result['message'] ?? "Unknown error occurred.");
		}

		$response = "LOGIN_FAILED";
		$new_login_key = "";
		$server_group_id = 0;
		
		$isXmlHttpRequest = (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest');
		($isXmlHttpRequest) ? header('Content-type: application/json') : header('Content-type: text/plain');	

		echo json_encode(array('result'=>$response,'account_id'=>$account_id, 'login_key'=>$new_login_key,'error'=>$error));
	 	return;
	}
}






//GM Login
if ($account_id == 'a_5288843277264847275' ||
$account_id == 'g17996893341400698406' ||
$account_id == 'a_6361116018492116957' ||
$account_id == 'g17777363609468649255' ||
$account_id == 'g05708447530224277349' ||
$account_id == 'g17286077756811295332')
{	
	LoginQuery($account_id, $_SERVER['REMOTE_ADDR'], $version, $lang, $platform, $server_group_id, $server_version, $wallet_id, $device_unique_id );
}
else
{
	if (CheckServerMaintenance())
	{
		if (CheckServerVersion_v3($version,$platform, $lang))
		{
			LoginQuery($account_id, $_SERVER['REMOTE_ADDR'], $version, $lang, $platform, $server_group_id, $server_version, $wallet_id, $device_unique_id );
		}
	}
}



?>