local socket = require("socket")
local json = require("dkjson")
local welding_common = require("welding_common")

local M = {}
local HTTP_TIMEOUT_SECONDS = 2

local function isTimeoutError(err)
	if not err then
		return false
	end

	return string.find(string.lower(tostring(err)), "timeout", 1, true) ~= nil
end

local function handleTimeoutAndAbort(err)
	log_error(welding_common.log_prefix .. "HTTP request timed out: " .. tostring(err))
	welding_common.showErrorMessage(welding_common.ERROR_ENUM.HTTP_REQUEST_TIMEOUT)
	abort()
end

local function encodeJson(value)
	local encoded, err = json.encode(value)
	if not encoded then
		return nil, err
	end
	return encoded
end

-- 通用的JSON-RPC调用函数（优化版）
function callJsonRpcMethod(methodName, params, url)
	local http = require("socket.http")
	local ltn12 = require("ltn12")

	-- LuaSocket 的 http.TIMEOUT 控制整个 HTTP 请求的超时时间。
	http.TIMEOUT = HTTP_TIMEOUT_SECONDS

	-- 设置默认URL
	url = url or "http://localhost:30302/jsonrpc"

	if params == nil then
		params = {}
	elseif type(params) ~= "table" then
		params = { params }
	end

	local request_obj = {
		jsonrpc = "2.0",
		method = methodName,
		params = params,
		id = 1,
	}

	local json_request, encode_err = encodeJson(request_obj)
	if not json_request then
		return nil, "JSON encode error: " .. tostring(encode_err)
	end
	json_request = string.gsub(json_request, "%s+", " ")

	local headers = {
		["Content-Type"] = "application/json",
		["Content-Length"] = tostring(#json_request),
	}

	local response_body = {}

	local _, status, response_headers = http.request({
		url = url,
		method = "POST",
		headers = headers,
		source = ltn12.source.string(json_request),
		sink = ltn12.sink.table(response_body),
	})

	if status == 200 then
		local response = table.concat(response_body)
		return response
	elseif isTimeoutError(status) then
		return nil, "HTTP timeout after " .. tostring(HTTP_TIMEOUT_SECONDS) .. "s"
	else
		return nil, "HTTP error: " .. tostring(status)
	end
end

-- 增强的JSON响应解析器（使用模式匹配改进）
function extractResultFromResponse(response)
	if not response or response == "" then
		return nil
	end
	response = response:match("^%s*(.-)%s*$")
	local success, decoded = pcall(json.decode, response)
	if not success or not decoded then
		return nil, "invalid json response"
	end

	if decoded.error then
		local message = decoded.error.message or "unknown rpc error"
		return nil, message
	end

	return decoded.result, nil
end

-- 封装的函数：传入函数名称，返回具体参数
M.getFunctionResult = function(functionName, params, url)
	local response, err = callJsonRpcMethod(functionName, params, url)
	if not response then
		if isTimeoutError(err) then
			handleTimeoutAndAbort(err)
		end
		return nil, err
	end

	return extractResultFromResponse(response)
end

-- 获取当前时间的完整时间戳
function getCurrentTimestamp()
	if socket.gettime then
		local time = socket.gettime() -- 返回秒，有小数
		local milliseconds = math.floor((time - math.floor(time)) * 1000)
		local date_str = os.date("%Y-%m-%d %H:%M:%S", math.floor(time))
		return date_str .. "." .. string.format("%03d", milliseconds)
	else
		return os.date("%Y-%m-%d %H:%M:%S")
	end
end

-- 调试辅助函数：打印参数信息
function debugParams(params, description)
	print("=== DEBUG " .. (description or "PARAMS") .. " ===")
	if type(params) == "table" then
		for i, v in ipairs(params) do
			print(string.format("  [%d] type=%s, value=%s", i, type(v), tostring(v)))
			if type(v) == "table" then
				for k, val in pairs(v) do
					print(string.format("      [%s] = %s (type=%s)", tostring(k), tostring(val), type(val)))
				end
			end
		end
	else
		print("  type=" .. type(params) .. ", value=" .. tostring(params))
	end
	print("=== END DEBUG ===")
end

return M
