local M = {}

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

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

-- ==================== 焊接通讯地址相关参数 ====================
-- 起弧成功 IO 地址
local arc_successed_address = 0
-- 起弧/熄弧 IO 地址
local arc_address = 0
-- 送丝 IO 地址
local gas_address = 2
-- 给定电流地址
local given_current_address = 0
-- 给定电压地址
local given_voltage_address = 1

-- ==================== 焊接工艺相关参数 ====================
-- 起弧电流
local arc_current_ = 0
-- 起弧电压
local arc_voltage_ = 0
-- 起弧等待时间
local start_arc_wait_time_ = 0
-- 焊接电流
local current_ = 0
-- 焊接电压
local voltage_ = 0
-- 熄弧电流
local stop_arc_current_ = 0
-- 熄弧电压
local stop_arc_voltage_ = 0
-- 熄弧等待时间
local stop_arc_wait_time_ = 0
-- 延迟送气时间
local delivery_time_ = 0
-- 是否检测到异常熄弧
local arc_lost_detected_ = false

local global_offset_ = { false, {}, {} }

-- ==================== 配置函数 ====================

-- 获取电弧IO控制值
local function getArcIoOutput()
	local _ENV = sched.select_robot(1)
	if type(getArcIoValue) == "function" then
		return getArcIoValue()
	else
		return getStandardDigitalInput(arc_successed_address)
	end
end

-- 设置电弧IO输出控制值
local function setArcIoOutput(value)
	if value then
		log_info(welding_common.log_prefix .. "setArcIoOutput:" .. "true")
	else
		log_info(welding_common.log_prefix .. "setArcIoOutput:" .. "false")
	end

	local _ENV = sched.select_robot(1)
	if type(setArcIoValue) == "function" then
		setArcIoValue(value)
	else
		setStandardDigitalOutput(arc_address, value)
	end
end

-- 设置气体电磁阀状态（true=打开，false=关闭）
local function setGasSolenoidState(state)
	local _ENV = sched.select_robot(1)
	if type(setGasIoValue) == "function" then
		setGasIoValue(state)
	else
		setStandardDigitalOutput(gas_address, state)
	end
end

-- 设置目标焊接电流输出值
local function setTargetCurrentOutput(current_value)
	local _ENV = sched.select_robot(1)
	if type(setGivenCurrentIoValue) == "function" then
		setGivenCurrentIoValue(current_value)
	else
		setStandardAnalogOutput(given_current_address, current_value)
	end
end

-- 设置目标焊接电压输出值
local function setTargetVoltageOutput(voltage_value)
	local _ENV = sched.select_robot(1)
	if type(setGivenVoltageIoValue) == "function" then
		setGivenVoltageIoValue(voltage_value)
	else
		setStandardAnalogOutput(given_voltage_address, voltage_value)
	end
end

local function updateWeldingParameters(
	current,
	voltage,
	stop_arc_voltage,
	stop_arc_current,
	stop_arc_wait_time,
	delivery_time,
	arc_voltage,
	arc_current,
	start_arc_wait_time
)
	-- 焊参快照统一在参数更新入口记录，避免调用方漏记。
	local welding_resume = require("welding_resume")
	welding_resume.recordWelderParamSnapshot({
		current = current or 0,
		voltage = voltage or 0,
		stop_arc_voltage = stop_arc_voltage or 0,
		stop_arc_current = stop_arc_current or 0,
		stop_arc_wait_time = stop_arc_wait_time or 0,
		delivery_time = delivery_time or 0,
		arc_voltage = arc_voltage or 0,
		arc_current = arc_current or 0,
		start_arc_wait_time = start_arc_wait_time or 0,
	})

	local _ENV = sched.select_robot(1)
	current_ = current
	voltage_ = voltage

	stop_arc_voltage_ = stop_arc_voltage
	stop_arc_current_ = stop_arc_current
	stop_arc_wait_time_ = stop_arc_wait_time
	delivery_time_ = delivery_time

	arc_voltage_ = arc_voltage
	arc_current_ = arc_current
	start_arc_wait_time_ = start_arc_wait_time

	local str = string.format(
		"updateWeldingParameters(%s,%s,%s,%s,%s,%s,%s,%s,%s)",
		current_,
		voltage_,
		stop_arc_voltage_,
		stop_arc_current_,
		stop_arc_wait_time_,
		delivery_time_,
		arc_voltage_,
		arc_current_,
		start_arc_wait_time_
	)

	log_info(log_prefix .. str)

	local welding_arc = require("welding_arc")
	if welding_arc.isArcing() then
		setTargetCurrentOutput(current_)
		log_info(log_prefix .. "setTargetCurrentOutput:" .. current_)
		setTargetVoltageOutput(voltage_)
		log_info(log_prefix .. "setTargetVoltageOutput:" .. voltage_)
	end
end

local function updateWeldingParametSIntermittent(welder_param)
	local _ENV = sched.select_robot(1)
	updateWeldingParameters(
		welder_param.current or 0,
		welder_param.voltage or 0,
		welder_param.off_voltage or 0,
		welder_param.off_current or 0,
		welder_param.arc_extinguishing_time or 0,
		welder_param.delivery_time or 0,
		welder_param.arc_voltage or 0,
		welder_param.arc_current or 0,
		welder_param.starting_arc_time or 0
	)
end

local function setArcLostDetected(value)
	arc_lost_detected_ = (value == true)
end

local function isArcLostDetected()
	return arc_lost_detected_ == true
end

-- ==================== 线程函数 ====================

local detection_arcing_thread = sched.thread(function()
	local _ENV = sched.select_robot(1)
	local count = 0
	local latency_time = 0.2
	while true do
		local successful_arc_initiation = getArcIoOutput()
		if not successful_arc_initiation and count == 3 then
			setArcLostDetected(true)
			setArcIoOutput(false)
			log_error(log_prefix .. "Detected welding arc interruption, low_count=" .. tostring(count))
			sched.sleep(latency_time)
			welding_common.showErrorMessage(welding_common.ERROR_ENUM.WELDING_ARC_LOST)
			abort()
		elseif not successful_arc_initiation then
			count = count + 1
			if count == 1 then
				log_warn(log_prefix .. "Arc detection input low, start counting")
			end
			sched.sleep(latency_time)
		else
			if count ~= 0 then
				log_info(log_prefix .. "Arc detection input recovered, low_count=" .. tostring(count))
				count = 0
			end
			sched.sleep(latency_time)
		end
	end
end, "Arc_Detection_Thread")

local function getStartArcWaitTime()
	return start_arc_wait_time_
end

local function getStartArcCurrent()
	return arc_current_
end

local function getStartArcVoltage()
	return arc_voltage_
end

local function getCurrent()
	return current_
end

local function getVoltage()
	return voltage_
end

local function getStopArcCurrent()
	return stop_arc_current_
end

local function getStopArcVoltage()
	return stop_arc_voltage_
end

local function getStopArcWaitTime()
	return stop_arc_wait_time_
end

local function getDeliveryTime()
	return delivery_time_
end

-- 导出模块
M.getArcIoOutput = getArcIoOutput
M.setArcIoOutput = setArcIoOutput
M.setGasSolenoidState = setGasSolenoidState
M.setTargetCurrentOutput = setTargetCurrentOutput
M.setTargetVoltageOutput = setTargetVoltageOutput
M.updateWeldingParameters = updateWeldingParameters
M.updateWeldingParametSIntermittent = updateWeldingParametSIntermittent
M.detection_arcing_thread = detection_arcing_thread
M.getStartArcWaitTime = getStartArcWaitTime
M.getStartArcCurrent = getStartArcCurrent
M.getStartArcVoltage = getStartArcVoltage
M.getCurrent = getCurrent
M.getVoltage = getVoltage
M.getStopArcCurrent = getStopArcCurrent
M.getStopArcVoltage = getStopArcVoltage
M.getStopArcWaitTime = getStopArcWaitTime
M.getDeliveryTime = getDeliveryTime
M.global_offset_ = global_offset_
M.setArcLostDetected = setArcLostDetected
M.isArcLostDetected = isArcLostDetected

return M
