extends Node

# 网络请求管理器 - 统一处理所有HTTP请求

# 信号定义
signal request_completed(request_id: String, success: bool, data: Dictionary)
signal request_failed(request_id: String, error_type: String, message: String)

# API配置
const API_BASE_URL = "https://whaletownend.xinghangee.icu"
const DEFAULT_TIMEOUT = 30.0

# 请求类型枚举
enum RequestType {
	GET,
	POST,
	PUT,
	DELETE,
	PATCH
}

# 错误类型枚举
enum ErrorType {
	NETWORK_ERROR,      # 网络连接错误
	TIMEOUT_ERROR,      # 请求超时
	PARSE_ERROR,        # JSON解析错误
	HTTP_ERROR,         # HTTP状态码错误
	BUSINESS_ERROR      # 业务逻辑错误
}

# 请求状态
class RequestInfo:
	var id: String
	var url: String
	var method: RequestType
	var headers: PackedStringArray
	var body: String
	var timeout: float
	var start_time: float
	var http_request: HTTPRequest
	var callback: Callable
	
	func _init(request_id: String, request_url: String, request_method: RequestType, 
			   request_headers: PackedStringArray = [], request_body: String = "", 
			   request_timeout: float = DEFAULT_TIMEOUT):
		id = request_id
		url = request_url
		method = request_method
		headers = request_headers
		body = request_body
		timeout = request_timeout
		start_time = Time.get_time_dict_from_system().hour * 3600 + Time.get_time_dict_from_system().minute * 60 + Time.get_time_dict_from_system().second

# 活动请求管理
var active_requests: Dictionary = {}
var request_counter: int = 0

func _ready():
	print("NetworkManager 已初始化")

# ============ 公共API接口 ============

# 发送GET请求
func get_request(endpoint: String, callback: Callable = Callable(), timeout: float = DEFAULT_TIMEOUT) -> String:
	return send_request(endpoint, RequestType.GET, [], "", callback, timeout)

# 发送POST请求
func post_request(endpoint: String, data: Dictionary, callback: Callable = Callable(), timeout: float = DEFAULT_TIMEOUT) -> String:
	var body = JSON.stringify(data)
	var headers = ["Content-Type: application/json"]
	return send_request(endpoint, RequestType.POST, headers, body, callback, timeout)

# 发送PUT请求
func put_request(endpoint: String, data: Dictionary, callback: Callable = Callable(), timeout: float = DEFAULT_TIMEOUT) -> String:
	var body = JSON.stringify(data)
	var headers = ["Content-Type: application/json"]
	return send_request(endpoint, RequestType.PUT, headers, body, callback, timeout)

# 发送DELETE请求
func delete_request(endpoint: String, callback: Callable = Callable(), timeout: float = DEFAULT_TIMEOUT) -> String:
	return send_request(endpoint, RequestType.DELETE, [], "", callback, timeout)

# ============ 认证相关API ============

# 用户登录
func login(identifier: String, password: String, callback: Callable = Callable()) -> String:
	var data = {
		"identifier": identifier,
		"password": password
	}
	return post_request("/auth/login", data, callback)

# 验证码登录
func verification_code_login(identifier: String, verification_code: String, callback: Callable = Callable()) -> String:
	var data = {
		"identifier": identifier,
		"verification_code": verification_code
	}
	return post_request("/auth/verification-code-login", data, callback)

# 发送登录验证码
func send_login_verification_code(identifier: String, callback: Callable = Callable()) -> String:
	var data = {"identifier": identifier}
	return post_request("/auth/send-login-verification-code", data, callback)

# 用户注册
func register(username: String, password: String, nickname: String, email: String = "", 
			  email_verification_code: String = "", callback: Callable = Callable()) -> String:
	var data = {
		"username": username,
		"password": password,
		"nickname": nickname
	}
	
	if email != "":
		data["email"] = email
	if email_verification_code != "":
		data["email_verification_code"] = email_verification_code
	
	return post_request("/auth/register", data, callback)

# 发送邮箱验证码
func send_email_verification(email: String, callback: Callable = Callable()) -> String:
	var data = {"email": email}
	return post_request("/auth/send-email-verification", data, callback)

# 验证邮箱
func verify_email(email: String, verification_code: String, callback: Callable = Callable()) -> String:
	var data = {
		"email": email,
		"verification_code": verification_code
	}
	return post_request("/auth/verify-email", data, callback)

# 获取应用状态
func get_app_status(callback: Callable = Callable()) -> String:
	return get_request("/", callback)

# 重新发送邮箱验证码
func resend_email_verification(email: String, callback: Callable = Callable()) -> String:
	var data = {"email": email}
	return post_request("/auth/resend-email-verification", data, callback)

# 忘记密码 - 发送重置验证码
func forgot_password(identifier: String, callback: Callable = Callable()) -> String:
	var data = {"identifier": identifier}
	return post_request("/auth/forgot-password", data, callback)

# 重置密码
func reset_password(identifier: String, verification_code: String, new_password: String, callback: Callable = Callable()) -> String:
	var data = {
		"identifier": identifier,
		"verification_code": verification_code,
		"new_password": new_password
	}
	return post_request("/auth/reset-password", data, callback)

# 修改密码
func change_password(user_id: String, old_password: String, new_password: String, callback: Callable = Callable()) -> String:
	var data = {
		"user_id": user_id,
		"old_password": old_password,
		"new_password": new_password
	}
	return put_request("/auth/change-password", data, callback)

# GitHub OAuth登录
func github_login(github_id: String, username: String, nickname: String, email: String, avatar_url: String = "", callback: Callable = Callable()) -> String:
	var data = {
		"github_id": github_id,
		"username": username,
		"nickname": nickname,
		"email": email
	}
	
	if avatar_url != "":
		data["avatar_url"] = avatar_url
	
	return post_request("/auth/github", data, callback)

# ============ 核心请求处理 ============

# 发送请求的核心方法
func send_request(endpoint: String, method: RequestType, headers: PackedStringArray, 
				  body: String, callback: Callable, timeout: float) -> String:
	# 生成请求ID
	request_counter += 1
	var request_id = "req_" + str(request_counter)
	
	# 构建完整URL
	var full_url = API_BASE_URL + endpoint
	
	# 创建HTTPRequest节点
	var http_request = HTTPRequest.new()
	add_child(http_request)
	
	# 设置超时
	http_request.timeout = timeout
	
	# 创建请求信息
	var request_info = RequestInfo.new(request_id, full_url, method, headers, body, timeout)
	request_info.http_request = http_request
	request_info.callback = callback
	
	# 存储请求信息
	active_requests[request_id] = request_info
	
	# 连接信号
	http_request.request_completed.connect(func(result: int, response_code: int, headers: PackedStringArray, body: PackedByteArray):
		_on_request_completed(request_id, result, response_code, headers, body)
	)
	
	# 发送请求
	var godot_method = _convert_to_godot_method(method)
	var error = http_request.request(full_url, headers, godot_method, body)
	
	print("=== 发送网络请求 ===")
	print("请求ID: ", request_id)
	print("URL: ", full_url)
	print("方法: ", RequestType.keys()[method])
	print("Headers: ", headers)
	print("Body: ", body if body.length() < 200 else body.substr(0, 200) + "...")
	print("发送结果: ", error)
	
	if error != OK:
		print("请求发送失败，错误代码: ", error)
		_handle_request_error(request_id, ErrorType.NETWORK_ERROR, "网络请求发送失败: " + str(error))
		return ""
	
	return request_id

# 请求完成回调
func _on_request_completed(request_id: String, result: int, response_code: int, 
						   headers: PackedStringArray, body: PackedByteArray):
	print("=== 网络请求完成 ===")
	print("请求ID: ", request_id)
	print("结果: ", result)
	print("状态码: ", response_code)
	print("响应头: ", headers)
	
	# 获取请求信息
	if not active_requests.has(request_id):
		print("警告: 未找到请求ID ", request_id)
		return
	
	var request_info = active_requests[request_id]
	var response_text = body.get_string_from_utf8()
	
	print("响应体长度: ", body.size(), " 字节")
	print("响应内容: ", response_text if response_text.length() < 500 else response_text.substr(0, 500) + "...")
	
	# 处理网络连接失败
	if response_code == 0:
		_handle_request_error(request_id, ErrorType.NETWORK_ERROR, "网络连接失败，请检查网络连接")
		return
	
	# 解析JSON响应
	var json = JSON.new()
	var parse_result = json.parse(response_text)
	if parse_result != OK:
		_handle_request_error(request_id, ErrorType.PARSE_ERROR, "服务器响应格式错误")
		return
	
	var response_data = json.data
	
	# 处理响应
	_handle_response(request_id, response_code, response_data)

# 处理响应 - 支持API v1.1.1的状态码
func _handle_response(request_id: String, response_code: int, data: Dictionary):
	var request_info = active_requests[request_id]
	
	# 检查业务成功标志
	var success = data.get("success", true)  # 默认true保持向后兼容
	var error_code = data.get("error_code", "")
	var message = data.get("message", "")
	
	# 判断请求是否成功
	var is_success = false
	
	# HTTP成功状态码且业务成功
	if (response_code >= 200 and response_code < 300) and success:
		is_success = true
	# 特殊情况：206测试模式 - 根据API文档，这是成功的测试模式响应
	elif response_code == 206 and error_code == "TEST_MODE_ONLY":
		is_success = true
		print("🧪 测试模式响应: ", message)
	# 201创建成功
	elif response_code == 201:
		is_success = true
	
	if is_success:
		print("✅ 请求成功: ", request_id)
		# 发送成功信号
		request_completed.emit(request_id, true, data)
		
		# 调用回调函数
		if request_info.callback.is_valid():
			request_info.callback.call(true, data, {})
	else:
		print("❌ 请求失败: ", request_id, " - HTTP:", response_code, " 错误码:", error_code, " 消息:", message)
		
		# 确定错误类型
		var error_type = _determine_error_type(response_code, error_code)
		
		# 发送失败信号
		request_failed.emit(request_id, ErrorType.keys()[error_type], message)
		
		# 调用回调函数
		if request_info.callback.is_valid():
			var error_info = {
				"response_code": response_code,
				"error_code": error_code,
				"message": message,
				"error_type": error_type
			}
			request_info.callback.call(false, data, error_info)
	
	# 清理请求
	_cleanup_request(request_id)

# 处理请求错误
func _handle_request_error(request_id: String, error_type: ErrorType, message: String):
	print("❌ 请求错误: ", request_id, " - ", message)
	
	# 发送错误信号
	request_failed.emit(request_id, ErrorType.keys()[error_type], message)
	
	# 调用回调函数
	if active_requests.has(request_id):
		var request_info = active_requests[request_id]
		if request_info.callback.is_valid():
			var error_info = {
				"error_type": error_type,
				"message": message
			}
			request_info.callback.call(false, {}, error_info)
	
	# 清理请求
	_cleanup_request(request_id)

# 确定错误类型 - 支持更多状态码
func _determine_error_type(response_code: int, error_code: String) -> ErrorType:
	# 根据错误码判断
	match error_code:
		"SERVICE_UNAVAILABLE":
			return ErrorType.BUSINESS_ERROR
		"TOO_MANY_REQUESTS":
			return ErrorType.BUSINESS_ERROR
		"TEST_MODE_ONLY":
			return ErrorType.BUSINESS_ERROR
		"SEND_EMAIL_VERIFICATION_FAILED", "REGISTER_FAILED":
			# 这些可能是409冲突或其他业务错误
			return ErrorType.BUSINESS_ERROR
		_:
			# 根据HTTP状态码判断
			match response_code:
				409:  # 资源冲突
					return ErrorType.BUSINESS_ERROR
				206:  # 测试模式
					return ErrorType.BUSINESS_ERROR
				429:  # 频率限制
					return ErrorType.BUSINESS_ERROR
				_:
					if response_code >= 400 and response_code < 500:
						return ErrorType.HTTP_ERROR
					elif response_code >= 500:
						return ErrorType.HTTP_ERROR
					else:
						return ErrorType.BUSINESS_ERROR

# 清理请求资源
func _cleanup_request(request_id: String):
	if active_requests.has(request_id):
		var request_info = active_requests[request_id]
		
		# 移除HTTPRequest节点
		if is_instance_valid(request_info.http_request):
			request_info.http_request.queue_free()
		
		# 从活动请求中移除
		active_requests.erase(request_id)
		
		print("🧹 清理请求: ", request_id)

# 转换请求方法
func _convert_to_godot_method(method: RequestType) -> HTTPClient.Method:
	match method:
		RequestType.GET:
			return HTTPClient.METHOD_GET
		RequestType.POST:
			return HTTPClient.METHOD_POST
		RequestType.PUT:
			return HTTPClient.METHOD_PUT
		RequestType.DELETE:
			return HTTPClient.METHOD_DELETE
		RequestType.PATCH:
			return HTTPClient.METHOD_PATCH
		_:
			return HTTPClient.METHOD_GET

# ============ 工具方法 ============

# 取消请求
func cancel_request(request_id: String) -> bool:
	if active_requests.has(request_id):
		print("🚫 取消请求: ", request_id)
		_cleanup_request(request_id)
		return true
	return false

# 取消所有请求
func cancel_all_requests():
	print("🚫 取消所有请求")
	var request_ids = active_requests.keys()
	for request_id in request_ids:
		cancel_request(request_id)

# 获取活动请求数量
func get_active_request_count() -> int:
	return active_requests.size()

# 检查请求是否活动
func is_request_active(request_id: String) -> bool:
	return active_requests.has(request_id)

# 获取请求信息
func get_request_info(request_id: String) -> Dictionary:
	if active_requests.has(request_id):
		var info = active_requests[request_id]
		return {
			"id": info.id,
			"url": info.url,
			"method": RequestType.keys()[info.method],
			"start_time": info.start_time,
			"timeout": info.timeout
		}
	return {}

func _notification(what):
	if what == NOTIFICATION_WM_CLOSE_REQUEST:
		# 应用关闭时取消所有请求
		cancel_all_requests()