local M = {}

-- 导入必要的模块
local sched = sched or require("aubo").sched
local math = math or require("aubo").math

-- 导入错误处理模块
local welding_common = require("welding_common")

-- 导入运动模块
local welding_motion = require("welding_motion")
local welding_utils = require("welding_utils")
local welding_resume = require("welding_resume")

-- 导入焊接通信模块
local welding_communication = require("welding_communication")

-- 导入焊接算法模块
local aubo_math = require("aubo_math")

-- 导入电弧控制模块
local welding_arc = require("welding_arc")

-- ==================== 摆动参数生成 ====================

local function getSwingParams(motion_param)
	local _ENV = sched.select_robot(1)
	-- 参数校验与默认值处理
	motion_param = motion_param or {}
	local amplitude = tonumber(motion_param.amplitude) or 0.0
	local frequency = tonumber(motion_param.frequency) or 1.0 -- 默认1Hz防止除零
	local welding_speed = tonumber(motion_param.welding_speed) or 0.0
	local hold_distance = tonumber(motion_param.hold_distance) or 0
	local standing_time = tonumber(motion_param.standing_time)
	local left_standing_time, right_standing_time

	if standing_time and standing_time >= 0.0 then
		left_standing_time = standing_time
		right_standing_time = standing_time
	else
		left_standing_time = motion_param.left_standing_time or 0.0
		right_standing_time = motion_param.right_standing_time or 0.0
	end
	local angle = tonumber(motion_param.angle) or 0
	local direction = tonumber(motion_param.direction) or 0
	local weave = motion_param.weave or 0 -- 默认无摆动

	-- 计算步长（保留8位小数）
	local step = tonumber(string.format("%.8f", welding_speed / frequency))

	-- 摆动类型映射
	local weave_type = ({
		[1] = "SINE",
		[2] = "SPIRAL",
		[3] = "CRESCENT",
		[4] = "ZIGZAG",
	})[weave] or "NONE"

	-- 生成标准JSON格式（不带外层引号）
	local json_str = string.format(
		'{"type":"%s","step":%.8f,"amplitude":[%.8f,%.8f],'
			.. '"hold_distance":[%.8f,%.8f],"hold_time":[%.8f,%.8f],'
			.. '"angle":%.8f,"direction":%d}',
		weave_type,
		step,
		amplitude,
		amplitude,
		hold_distance,
		hold_distance,
		left_standing_time,
		right_standing_time,
		angle,
		direction
	)

	-- 调试输出
	log_info(welding_common.log_prefix .. "Generated swing parameters JSON:")
	log_info(welding_common.log_prefix .. json_str)
	return json_str
end

-- ==================== 摆动处理 ====================

local function validateWeaveInputParameters(prev_action, points)
	local _ENV = sched.select_robot(1)
	if not prev_action or not prev_action.roadpoints or #prev_action.roadpoints == 0 then
		log_error(welding_common.log_prefix .. "Invalid previous action data")
		return false, "Invalid previous action data"
	end
	if not points or #points == 0 then
		log_error(welding_common.log_prefix .. "No target points provided")
		return false, "No target points provided"
	end
	return true
end

local function getPoseFromPoint(point)
	return point and (point.pose or point.tcp_pose) or { 0, 0, 0, 0, 0, 0 }
end

local function prepareWeaveParams(motion_param)
	return {
		angle = motion_param.angle or 0,
		speed = (motion_param.welding_speed or 0.0005), -- 默认0.5mm/s
		freq = motion_param.frequency or 1.0,
		hold_dist = (motion_param.hold_distance or 0),
		amp = (motion_param.amplitude or 0.005), -- 默认5mm
		dir = motion_param.direction or 0,
	}
end

local function printWeaveParams(params)
	local _ENV = sched.select_robot(1)
	log_info(
		welding_common.log_prefix
			.. string.format(
				"Swing parameters: angle=%f, speed=%f, freq=%f, hold=%f, amp=%f, dir=%d",
				params.angle,
				params.speed,
				params.freq,
				params.hold_dist,
				params.amp,
				params.dir
			)
	)
end

local function calculateActualSpeed(motion_param)
	local _ENV = sched.select_robot(1)
	local v = motion_param.welding_speed
	local f = motion_param.frequency
	local h = motion_param.amplitude

	if f == 0 then
		log_error(welding_common.log_prefix .. "Frequency does not meet the requirements:" .. f)
		return 0.0
	end

	return 4 * f * math.sqrt((v / f * 0.25) ^ 2 + h ^ 2)
end

-- 锯齿摆动的左右停留时间要跟“起摆方向”绑定：
-- direction=0(向上起摆)时，第一个摆点按左侧停留；direction=1(向下起摆)时，第一个摆点按右侧停留。
local function isFirstZigzagPointLeft(motion_param)
	local direction = tonumber(motion_param and motion_param.direction) or 0
	return direction == 0
end

-- 通用摆动路径执行器：
-- - 逐点执行前动态读取恢复状态；
-- - execute_motion=false 时仅推进程序点位/标签，不做真实运动等待。
-- - 左/右停留时间严格按起摆方向映射，不允许调用方覆盖首点侧别。
-- - invert_first_side 用于处理圆弧锯齿算法返回首点侧别与直线相反的情况。
local function processWeavePath(path, motion_param, params, state, invert_first_side)
	local _ENV = sched.select_robot(1)
	if not path or #path == 0 then
		log_error(welding_common.log_prefix .. "Swing Path is empty")
		return
	end

	log_info(welding_common.log_prefix .. string.format("Swing path contains %d points:", #path))

	local sign = isFirstZigzagPointLeft(motion_param)
	if invert_first_side then
		sign = not sign
	end

	local standing_time = motion_param.standing_time or 0.0
	local left_standing_time, right_standing_time

	if standing_time and standing_time >= 0.0 then
		left_standing_time = standing_time
		right_standing_time = standing_time
	else
		left_standing_time = motion_param.left_standing_time or 0.0
		right_standing_time = motion_param.right_standing_time or 0.0
	end

	for i, point in ipairs(path) do
		-- 优化数据验证
		if not point or type(point) ~= "table" or #point < 6 then
			log_error(
				welding_common.log_prefix
					.. string.format(
						"Point %d: INVALID_DATA (expected 6D vector, got %s)",
						i,
						point and type(point) or "nil"
					)
			)
		else
			-- 解构赋值
			local x, y, z, rx, ry, rz =
				point[1] or 0, point[2] or 0, point[3] or 0, point[4] or 0, point[5] or 0, point[6] or 0

			log_info(
				welding_common.log_prefix
					.. string.format("Point %d: [%.3f, %.3f, %.3f, %.3f, %.3f, %.3f]", i, x, y, z, rx, ry, rz)
			)

			local _, execute_now = welding_resume.resolveResumeExecutionState()
			welding_motion.generateMoveLine(
				point,
				calculateActualSpeed(motion_param),
				params,
				state,
				false,
				motion_param.weld_type,
				false,
				execute_now
			)

			local current_standing_time = sign and right_standing_time or left_standing_time
			if execute_now and current_standing_time > 0.0 then
				sched.sleep(current_standing_time)
				log_info(
					welding_common.log_prefix
						.. string.format("sleep(%.3f), side=%s", current_standing_time, sign and "left" or "right")
				)
			end
			sign = not sign
		end
	end
	local _, execute_sync = welding_resume.resolveResumeExecutionState()
	if execute_sync then
		welding_arc.syncProgramPoint()
	end

	return true
end

-- 直线月牙摆动。
-- 注意：该函数内部按“每个子路点”动态读取恢复状态，避免只在入口判断一次导致恢复点后行为不一致。
local function linearCrescentOscillation(motion_param, prev_point, current_point, params, state)
	local _ENV = sched.select_robot(1)
	log_info(welding_common.log_prefix .. "Starting pose data used:", table.unpack(prev_point))
	log_info(welding_common.log_prefix .. "Target pose data used:", table.unpack(current_point))

	local weave_params = prepareWeaveParams(motion_param)
	printWeaveParams(weave_params)

	if welding_resume.consumeResumeJustRestoredFlag and welding_resume.consumeResumeJustRestoredFlag() then
		prev_point = getTcpPose()
		log_info(
			welding_common.log_prefix
				.. "crescent weave resume from current tcp pose: "
				.. welding_motion.formatPoseString(prev_point)
		)
	end

	local ok, saw_result = pcall(function()
		return aubo_math.getStraightCrescentSwingingPath(
			welding_motion.formatPose(prev_point),
			welding_motion.formatPose(current_point),
			weave_params.angle,
			weave_params.speed,
			weave_params.freq,
			weave_params.hold_dist,
			weave_params.amp,
			weave_params.dir
		)
	end)

	if not ok or type(saw_result) ~= "table" then
		return "", welding_common.ErrorCode.COMMON.TABLE_ERROR
	end

	if not saw_result.success then
		return "", saw_result.error or welding_common.ErrorCode.COMMON.UNKNOWN_ERROR
	end

	if not saw_result.path or #saw_result.path == 0 then
		log_error(welding_common.log_prefix .. "Swing Path is empty")
		return "", welding_common.ErrorCode.COMMON.SUCCESS
	end

	log_info(welding_common.log_prefix .. string.format("Swing path contains %d points:", #saw_result.path))

	local path = saw_result.path

	local start_point_swing = path[1]
	local end_point_swing = path[#path]
	local welding_speed = calculateActualSpeed(motion_param)
	local _, execute_motion = welding_resume.resolveResumeExecutionState()

	welding_motion.generateMoveLine(
		start_point_swing,
		welding_speed,
		params,
		state,
		false,
		motion_param.weld_type,
		true,
		execute_motion
	)

	if tonumber(welding_resume.getResumeRunState and welding_resume.getResumeRunState() or 0) == 2 then
		welding_resume.resolveResumeExecutionState()
		log_info(welding_common.log_prefix .. "crescent weave reached resume target, skip current weave path")
		return "", welding_common.ErrorCode.COMMON.SUCCESS
	end

	local path = saw_result.path

	-- 安全判断
	if not path or #path < 3 then
		log_error(welding_common.log_prefix .. "Path must contain at least 3 points for grouping.")
		return "", welding_common.ErrorCode.COMMON.SUCCESS
	end

	for i = 2, #path - 2, 2 do -- 每次步进 2，保证取连续的 3 个点，且第3点给下一组用
		local point1 = path[i]
		local point2 = path[i + 1]
		local point3 = path[i + 2]

		log_info(
			welding_common.log_prefix
				.. string.format(
					"Processing group %d: point1=path[%d], point2=path[%d], point3=path[%d]",
					i // 3 + 1,
					i,
					i + 1,
					i + 2
				)
		)

		-- 安全检查每个点
		if type(point1) ~= "table" or #point1 < 6 then
			log_error(welding_common.log_prefix .. string.format("  Point 1 (index %d): INVALID_DATA", i))
		else
			log_info(
				welding_common.log_prefix
					.. string.format(
						"  Point 1: [%f, %f, %f, %f, %f, %f]",
						point1[1],
						point1[2],
						point1[3],
						point1[4],
						point1[5],
						point1[6]
					)
			)
		end

		if type(point2) ~= "table" or #point2 < 6 then
			log_error(welding_common.log_prefix .. string.format("  Point 2 (index %d): INVALID_DATA", i + 1))
		else
			log_info(
				welding_common.log_prefix
					.. string.format(
						"  Point 2: [%f, %f, %f, %f, %f, %f]",
						point2[1],
						point2[2],
						point2[3],
						point2[4],
						point2[5],
						point2[6]
					)
			)
		end

		if type(point3) ~= "table" or #point3 < 6 then
			log_error(welding_common.log_prefix .. string.format("  Point 3 (index %d): INVALID_DATA", i + 2))
		else
			log_info(
				welding_common.log_prefix
					.. string.format(
						"  Point 3: [%f, %f, %f, %f, %f, %f]",
						point3[1],
						point3[2],
						point3[3],
						point3[4],
						point3[5],
						point3[6]
					)
			)
		end

		if point1 and #point1 >= 6 then
			local _, execute_motion = welding_resume.resolveResumeExecutionState()
			welding_motion.generateMoveLine(
				point1,
				welding_speed,
				params,
				state,
				false,
				motion_param.weld_type,
				true,
				execute_motion
			)
		end

		-- 如果有 point3，执行 point2 -> point3 的圆弧（或其他操作）
		if point3 and #point3 >= 6 then
			local standing_time = motion_param.standing_time or 0.0

			if point2 and #point2 >= 6 then
				local _, execute_motion = welding_resume.resolveResumeExecutionState()
				welding_motion.generateMoveArc(
					point2,
					point3,
					welding_speed,
					params,
					state,
					false,
					motion_param.weld_type,
					true,
					execute_motion
				)

				if execute_motion and standing_time > 0.0 then
					sched.sleep(standing_time)
					log_info(welding_common.log_prefix .. string.format("sleep(%f)", standing_time))
				end
			else
				log_error(welding_common.log_prefix .. "Point 2 is invalid for arc.")
			end
		else
			local _, execute_motion = welding_resume.resolveResumeExecutionState()
			welding_motion.generateMoveLine(
				point2,
				welding_speed,
				params,
				state,
				false,
				motion_param.weld_type,
				true,
				execute_motion
			)
			log_info(welding_common.log_prefix .. "No Point 3 or not enough points: ending group.")
		end
	end
	local _, execute_last = welding_resume.resolveResumeExecutionState()
	welding_motion.generateMoveLine(
		end_point_swing,
		welding_speed,
		params,
		state,
		false,
		motion_param.weld_type,
		true,
		execute_last
	)

	local _, execute_sync = welding_resume.resolveResumeExecutionState()
	if execute_sync then
		welding_arc.syncProgramPoint()
	end

	return "", welding_common.ErrorCode.COMMON.SUCCESS
end

--直线锯齿摆动
local function handleStraightWeave(motion_param, prev_point, current_point, params, state)
	local _ENV = sched.select_robot(1)
	-- 记录姿态数据（添加空值检查）
	local prev_pose_str = prev_point and welding_motion.formatPoseString(prev_point) or "nil"
	local current_pose_str = current_point and welding_motion.formatPoseString(current_point) or "nil"

	log_info(welding_common.log_prefix .. "Starting pose data used: " .. prev_pose_str)
	log_info(welding_common.log_prefix .. "Target pose data used: " .. current_pose_str)

	-- 准备摆动参数
	local weave_params = prepareWeaveParams(motion_param)
	if not weave_params then
		log_error(welding_common.log_prefix .. "Failed to prepare weave parameters")
		return "", welding_common.ErrorCode.COMMON.PARAM_ERROR
	end

	printWeaveParams(weave_params)

	-- 验证姿态数据有效性
	if not prev_point or not current_point then
		log_error(welding_common.log_prefix .. "Invalid pose data: prev_point or current_point is nil")
		return "", welding_common.ErrorCode.COMMON.INVALID_PARAM
	end

	-- 格式化姿态数据（添加验证）
	local prev_formatted = welding_motion.formatPose(prev_point)
	local current_formatted = welding_motion.formatPose(current_point)

	if not prev_formatted or not current_formatted then
		log_error(welding_common.log_prefix .. "Failed to format pose data")
		return "", welding_common.ErrorCode.COMMON.FORMAT_ERROR
	end

	-- 调用焊接通信函数（修正语法错误）
	local response, err = welding_communication.getFunctionResult("LineStitchPath.getStraightSawtoothSwingPath", {
		prev_formatted,
		current_formatted,
		weave_params.angle,
		weave_params.speed,
		weave_params.freq,
		weave_params.hold_dist,
		weave_params.amp,
		weave_params.dir,
	})

	-- 检查通信错误
	if err then
		log_error(welding_common.log_prefix .. "Communication error: " .. tostring(err))
		return "", welding_common.ErrorCode.COMMON.COMMUNICATION_ERROR
	end

	-- 检查响应有效性
	if not response or type(response) ~= "table" then
		log_error(welding_common.log_prefix .. "Invalid response format from welding communication")
		return "", welding_common.ErrorCode.COMMON.RESPONSE_ERROR
	end

	-- 提取结果（更安全的方式）
	local ok = response[1]
	local saw_result = response[2]

	-- 检查结果有效性
	if not ok then
		log_error(welding_common.log_prefix .. "Straight line zigzag swing calculation error")
		if saw_result and saw_result.error_msg then
			log_error(welding_common.log_prefix .. "Error details: " .. saw_result.error_msg)
		end
		return "", welding_common.ErrorCode.COMMON.TABLE_ERROR
	end

	if not saw_result or next(saw_result) == nil then
		welding_common.showErrorMessage(welding_common.ERROR_ENUM.SWING_CALCULATION_ERROR)
		return "", saw_result and saw_result.error or welding_common.ErrorCode.COMMON.UNKNOWN_ERROR
	end

	-- 直线锯齿：手动记录为 MoveL
	local straight_entry =
		welding_motion.recordMotion(welding_motion.MoveMode.MoveL, current_formatted, motion_param.weld_type)
	if straight_entry and straight_entry.point_index then
		welding_resume.onPointIndexUpdated(straight_entry.point_index)
	end

	-- state=1 干跑命中恢复点时，当前段属于“已执行路径”，只恢复状态并结束本段。
	-- 剩余路径由后续运动段按正常流程继续，避免在当前段内补跑回原始起点。
	if tonumber(welding_resume.getResumeRunState and welding_resume.getResumeRunState() or 0) == 2 then
		welding_resume.resolveResumeExecutionState()
		log_info(welding_common.log_prefix .. "straight weave reached resume target, skip current weave path")
		return true
	end

	-- 如果恢复已经在前一个动作完成，而当前直线锯齿才是未完成动作，则从当前 TCP 重新生成路径。
	welding_resume.resolveResumeExecutionState()
	if welding_resume.consumeResumeJustRestoredFlag and welding_resume.consumeResumeJustRestoredFlag() then
		local resume_start_pose = getTcpPose()
		log_info(
			welding_common.log_prefix
				.. "straight weave resume from current tcp pose: "
				.. welding_motion.formatPoseString(resume_start_pose)
		)
		response, err = welding_communication.getFunctionResult("LineStitchPath.getStraightSawtoothSwingPath", {
			welding_motion.formatPose(resume_start_pose),
			current_formatted,
			weave_params.angle,
			weave_params.speed,
			weave_params.freq,
			weave_params.hold_dist,
			weave_params.amp,
			weave_params.dir,
		})
		if err then
			log_error(welding_common.log_prefix .. "Communication error: " .. tostring(err))
			return "", welding_common.ErrorCode.COMMON.COMMUNICATION_ERROR
		end
		ok = response and response[1]
		saw_result = response and response[2]
		if not ok or not saw_result or next(saw_result) == nil then
			log_error(welding_common.log_prefix .. "Straight weave resume path calculation error")
			return "", welding_common.ErrorCode.COMMON.TABLE_ERROR
		end
	end

	-- 处理摆动路径
	local process_ok = processWeavePath(saw_result, motion_param, params, state)
	if not process_ok then
		log_error(welding_common.log_prefix .. "Failed to process weave path")
		return "", welding_common.ErrorCode.COMMON.PROCESS_ERROR
	end

	if straight_entry and straight_entry.point_index then
		welding_utils.setAuboLabelPointIndex(straight_entry.point_index)
	end

	log_info(welding_common.log_prefix .. "Straight line zigzag swing calculation completed successfully")
	return true
end

--圆弧锯齿摆动
local function handleCircularWeave(motion_param, points, params, state)
	local _ENV = sched.select_robot(1)

	-- 参数验证
	if not points or type(points) ~= "table" or #points < 3 then
		log_error(welding_common.log_prefix .. "Invalid points parameter: expected at least 3 points")
		return "", welding_common.ErrorCode.COMMON.INVALID_PARAM
	end

	if not motion_param then
		log_error(welding_common.log_prefix .. "Motion parameters are nil")
		return "", welding_common.ErrorCode.COMMON.INVALID_PARAM
	end

	-- 安全提取姿态点并验证
	local function safeGetPose(index, point_var)
		local point = points[index]
		if not point then
			log_error(welding_common.log_prefix .. string.format("Point %d is nil", index))
			return nil
		end

		local formatted_pose = welding_motion.formatPose(point)
		if not formatted_pose then
			log_error(welding_common.log_prefix .. string.format("Failed to format point %d", index))
			return nil
		end

		return formatted_pose
	end

	local start_pose = safeGetPose(1, "start_pose")
	local middle_pose = safeGetPose(2, "middle_pose")
	local end_pose = safeGetPose(3, "end_pose")

	if not start_pose or not middle_pose or not end_pose then
		return "", welding_common.ErrorCode.COMMON.FORMAT_ERROR
	end

	-- 记录姿态数据（修正日志格式）
	log_info(welding_common.log_prefix .. "Using starting target pose: " .. welding_motion.formatPoseString(start_pose))
	log_info(
		welding_common.log_prefix .. "Using intermediate target pose: " .. welding_motion.formatPoseString(middle_pose)
	)
	log_info(welding_common.log_prefix .. "Using ending target pose: " .. welding_motion.formatPoseString(end_pose))

	-- 提取摆动参数（添加合理范围检查）
	local angle = motion_param.angle or 0
	local amplitude = motion_param.amplitude or 0
	local welding_speed = motion_param.welding_speed or 0
	local frequency = motion_param.frequency or 1

	-- 参数合理性检查
	if welding_speed <= 0 then
		log_warn(
			welding_common.log_prefix .. string.format("Invalid welding speed: %.3f, using default", welding_speed)
		)
		welding_speed = 0.01 -- 设置最小有效值
	end

	if frequency <= 0 then
		log_warn(welding_common.log_prefix .. string.format("Invalid frequency: %.3f, using default", frequency))
		frequency = 1.0 -- 默认频率
	end

	local step = welding_speed / frequency

	-- 记录摆动参数（修正变量名和格式）
	log_info(
		welding_common.log_prefix
			.. string.format(
				"Swing parameters: angle=%.3f°, amplitude=%.3fmm, speed=%.3fmm/s, frequency=%.3fHz, step=%.6fmm",
				angle,
				amplitude,
				welding_speed,
				frequency,
				step
			)
	)

	-- 调用焊接通信函数
	local response, err = welding_communication.getFunctionResult("LineStitchPath.getCircularArcSawtoothSwingingPath", {
		start_pose,
		middle_pose,
		end_pose,
		amplitude, -- amplitude_inner (内幅值)
		amplitude, -- amplitude_outer (外幅值，这里使用相同值)
		step, -- 步长
		angle, -- 角度
	})

	-- 检查通信错误
	if err then
		log_error(welding_common.log_prefix .. "Circular arc swing communication error: " .. tostring(err))
		return "", welding_common.ErrorCode.COMMON.COMMUNICATION_ERROR
	end

	-- 检查响应有效性
	if not response or type(response) ~= "table" then
		log_error(welding_common.log_prefix .. "Invalid circular arc swing response format")
		return "", welding_common.ErrorCode.COMMON.RESPONSE_ERROR
	end

	-- 提取结果（更安全的方式）
	local ok = response[1]
	local saw_result = response[2]

	-- 检查结果有效性
	if not ok then
		log_error(welding_common.log_prefix .. "Circular arc zigzag swing calculation error")
		if saw_result and saw_result.error_msg then
			log_error(welding_common.log_prefix .. "Error details: " .. saw_result.error_msg)
		else
			log_error(welding_common.log_prefix .. "No detailed error message available")
		end
		return "", welding_common.ErrorCode.COMMON.CALCULATION_ERROR -- 使用更准确的错误码
	end

	-- 检查摆动路径结果
	if not saw_result or next(saw_result) == nil then
		log_error(welding_common.log_prefix .. "No circular arc swing path result generated")
		return "", welding_common.ErrorCode.COMMON.NO_RESULT
	end

	-- 圆弧锯齿：手动记录为 MoveC(via,end)
	local circular_entry =
		welding_motion.recordMotion(welding_motion.MoveMode.MoveC, { middle_pose, end_pose }, motion_param.weld_type)
	if circular_entry and circular_entry.point_index then
		welding_resume.onPointIndexUpdated(circular_entry.point_index)
	end

	-- state=1 干跑命中恢复点时，当前圆弧锯齿段也只推进点位，不执行内部小路径。
	if tonumber(welding_resume.getResumeRunState and welding_resume.getResumeRunState() or 0) == 2 then
		welding_resume.resolveResumeExecutionState()
		log_info(welding_common.log_prefix .. "circular weave reached resume target, skip current weave path")
		return true
	end

	-- 回退恢复命中圆弧锯齿的大点后，不能继续使用原始 start/middle/end。
	-- start 取当前 TCP，middle/end 优先取 calculateRollbackPath 预置的剩余圆弧点。
	welding_resume.resolveResumeExecutionState()
	if welding_resume.consumeResumeJustRestoredFlag and welding_resume.consumeResumeJustRestoredFlag() then
		local resume_arc = welding_resume.consumeResumeArcContinuation and welding_resume.consumeResumeArcContinuation()
			or nil
		start_pose = getTcpPose()
		if resume_arc and type(resume_arc.via_pose) == "table" and type(resume_arc.end_pose) == "table" then
			middle_pose = welding_motion.formatPose(resume_arc.via_pose)
			end_pose = welding_motion.formatPose(resume_arc.end_pose)
		end
		log_info(
			welding_common.log_prefix
				.. "circular weave resume from current tcp pose: "
				.. welding_motion.formatPoseString(start_pose)
		)
		response, err = welding_communication.getFunctionResult("LineStitchPath.getCircularArcSawtoothSwingingPath", {
			start_pose,
			middle_pose,
			end_pose,
			amplitude,
			amplitude,
			step,
			angle,
		})
		if err then
			log_error(welding_common.log_prefix .. "Circular arc swing communication error: " .. tostring(err))
			return "", welding_common.ErrorCode.COMMON.COMMUNICATION_ERROR
		end
		ok = response and response[1]
		saw_result = response and response[2]
		if not ok or not saw_result or next(saw_result) == nil then
			log_error(welding_common.log_prefix .. "Circular weave resume path calculation error")
			return "", welding_common.ErrorCode.COMMON.CALCULATION_ERROR
		end
	end

	-- 处理摆动路径
	local process_ok, process_err = processWeavePath(saw_result, motion_param, params, state)
	if not process_ok then
		log_error(welding_common.log_prefix .. "Failed to process circular arc weave path: " .. tostring(process_err))
		return "", welding_common.ErrorCode.COMMON.PROCESS_ERROR
	end

	if circular_entry and circular_entry.point_index then
		welding_utils.setAuboLabelPointIndex(circular_entry.point_index)
	end

	log_info(welding_common.log_prefix .. "Circular arc zigzag swing calculation completed successfully")
	return true
end

-- 导出模块
M.getSwingParams = getSwingParams
M.validateWeaveInputParameters = validateWeaveInputParameters
M.getPoseFromPoint = getPoseFromPoint
M.prepareWeaveParams = prepareWeaveParams
M.printWeaveParams = printWeaveParams
M.calculateActualSpeed = calculateActualSpeed
M.isFirstZigzagPointLeft = isFirstZigzagPointLeft
M.processWeavePath = processWeavePath
M.linearCrescentOscillation = linearCrescentOscillation
M.handleStraightWeave = handleStraightWeave
M.handleCircularWeave = handleCircularWeave

return M
