extends Node2D

@onready var _http_request = $HTTPRequest
@onready var timer = $Timer

const Response = preload("res://scenes/util/Response.gd")

var user_name : String = "FooBar"

var _user_ulid : String = ""
var _dojo_ulid : String = ""

var _dojos: Dictionary = {}
var _users: Dictionary = {}

var _own_characters: Dictionary = {}
var _own_characters_array : Array = []
var _all_characters: Dictionary = {}

var _techniques: Dictionary = {}
var _techniques_array : Array = []

func initialize_api():
	_http_request.base_address = "http://localhost:8000"
	_http_request.auth_token = "_sGFrChRV6ML0eWZC2qSUZzEGNLPbAhP4dwmnWhQ5bQ9xIi2pwHWQ1CzybFPDLeK8dTNx6GgWdR-Jcz-Z9_aC0hlY2h0fDIwMjQtMDYtMTNUMTk6MTU6MzkrMDA6MDA="

	for argument in OS.get_cmdline_user_args():
		print_debug("argument: %s" % argument)
		var key_value = argument.split("=", true, 1)
		if "--token" == key_value[0]:
			_http_request.auth_token = key_value[1]
		elif "--env" == key_value[0]:
			if key_value[1] == "dev":
				_http_request.base_address = "http://localhost:8000"
			else:
				_http_request.base_address = "https://dojo.animegame.eu"
				
	var tmp = _http_request.auth_token.replace("-", "/").replace("_", "+")
	
	# replace \-_ with /\+
	var chunks = Marshalls.base64_to_raw(tmp)
	user_name = chunks.slice(64).get_string_from_utf8().split('|')[0]
	

# Called when the node enters the scene tree for the first time.
func _ready():
	initialize_api()

# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta):
	pass

func get_uri(type: String, entity: Variant) -> String:
	return "api/%s/%s" % [type, entity if entity is String else entity["id"]]

func create_dojo(dojo_name : String) -> Response:
	var body = JSON.stringify({"name": dojo_name})
	return await _http_request.post_http_request("api/dojos", body)

func create_character(name: String, strength: int, constitution: int, agility: int, chi: int, techniques: Array) -> bool:
	var technique_uris : Array[String] = []
	
	for technique in techniques:
		technique_uris.append(get_uri("techniques", technique))
	
	var body = JSON.stringify({
		"dojo": "/api/dojos/%s" % _dojo_ulid, # meh!
		"name": name,
		"strength": strength,
		"constitution": constitution,
		"agility": agility,
		"chi": chi,
		"techniques": technique_uris
		})
	var response: Response =  await _http_request.post_http_request("api/characters", body)
	return response.status == OK

func update_user_preferences(values: Dictionary) -> Response:
	var body = JSON.stringify({"properties": values})
	var user = await get_user()
	return await _http_request.patch_http_request(get_uri("users", user), body)

func get_dojo() -> Dictionary:
	if _dojo_ulid  == "":
		var user = await get_user();
		if user.is_empty():
			print_debug("...")
			return {}

		var result: Response = await _http_request.get_http_request_sync(user["dojo"])
		print_debug("%s - %s - %s" % [result.status, result.code, result.data])
		if result.status != OK:
			return {}

		_dojo_ulid = result.data["id"]
		_dojos[_dojo_ulid] = result.data

	return _dojos[_dojo_ulid]

func get_dojo_by_id(id: String) -> Dictionary:
	return await __get_entity_by_id(_dojos, "dojos", id)

func get_user() -> Dictionary:
	if _user_ulid  == "":
		var result = await _http_request.get_http_request_sync("/api/users/authName/%s" % user_name)
		
		print_debug("get_user() %s - %s -> data %s" % [result.status, result.code, result.data])

		if result.status != OK:
			return {}


		_user_ulid = result.data["id"]
		_users[_user_ulid] = result.data

	return _users[_user_ulid]

func get_user_by_id(id: String) -> Dictionary:
	return await __get_entity_by_id(_users, "users", id)

func get_own_characters() -> Array:
	return await __get_entity_list(_own_characters, _own_characters_array, "api/dojo/characters")

func get_techniques() -> Array:
	return await __get_entity_list(_techniques, _techniques_array, "api/techniques")

func get_tournaments() -> Array:
	return await _http_request.get_http_request_sync("api/tournaments")

func get_character_by_id(id: String) -> Dictionary:
	if _own_characters.has(id):
		return _own_characters[id]

	return await __get_entity_by_id(_all_characters, "api/characters", id)

func __get_entity_by_id(entities: Dictionary, type: String, id: String) -> Dictionary:
	if not entities.has(id):
		var result: Response = await _http_request.get_http_request_sync("api/%s/%s" % [type, id])
		if result.status == OK:
			entities[id] = result.data
		else:
			return {}
	return entities[id];

func __get_entity_list(entities: Dictionary, _entities_array: Array, type: String) -> Array:
	if entities.is_empty():
		var result: Response = await _http_request.get_http_request_sync("api/%s" % type)
		if result.status == OK:
			for entity in result.data:
				entities[entity["id"]] = entity
				_entities_array.append(entity)
		else:
			return []

	return _entities_array
