local BattleConst = require "app/module/battle/battle_const"
local BattleFormula = require "app/module/battle/helper/battle_formula"

local BattleBuffSpecial = {}

local BUFF_NAME = BattleConst.BUFF_NAME
local ATTR_NAME = BattleConst.ATTR_NAME
local EFFECT_TYPE = BattleConst.EFFECT_TYPE

local function _addSkillOn(unitComp, buff, target, buffEffect)
	return target:addSkill(buff:getEffectNum())
end

local function _addSkillOff(buffSender, target, buff, buffEffect)
	if buffEffect and buffEffect.result > 0 then
		target:removeSkill(buff:getEffectNum(), buffEffect.result)
	end
end

local function _skillFireTimesOn(unitComp, buff, target, buffEffect)
	target.unitEntity:addSkillExtraUseTimes(buff:getEffectNum(), 1)
	return 1
end

local function _skillFireTimesOff(buffSender, target, buff, buffEffect)
	target.unitEntity:addSkillExtraUseTimes(buff:getEffectNum(), -1)
	return 1
end

local function _bleedOn(buffSender, buff, target, buffEffect)
	target.unitEntity:addAttr(buff:getName(), buff:getEffectNum(), false)
	return target.unitEntity:addAttr(BattleConst.ATTR_NAME.BE_SUCKED, 500, false) -- 写死5%
end

local function _bleedOff(buffSender, target, buff, buffEffect)
	target.unitEntity:addAttr(buff:getName(), -buff:getEffectNum(), false)
	target.unitEntity:addAttr(BattleConst.ATTR_NAME.BE_SUCKED, -500, false) -- 写死5%
	return 1
end

local function _bleedWork(unitComp, buffEffect, buff)
	local damage, hurtStatus = BattleFormula:getDamageOrCureResult(buffEffect.sender, buff, unitComp)
	if damage <= 0 then
		damage = -1
	else
		damage = -damage
	end
	unitComp:takeDamageOrCure(buffEffect.sender, damage, EFFECT_TYPE.DOT, hurtStatus, buff:getName())
	return 1
end

local function _undeadOn(buffSender, buff, target, buffEffect)
	return target.unitEntity:setUndeadHp(1) -- 写死1
end

local function _undeadOff(buffSender, target, buff, buffEffect)
	target.unitEntity:setUndeadHp(0) -- 写死0
	return 1
end

local function _imprisonOn(buffSender, buff, target, buffEffect)
	local battleController = ModuleManager.BattleManager.battleController
	if battleController then
		battleController.battleData:lockAllSkillGrid(true, target.side)
	end
	target.unitEntity:addActiveSkillLimit(buff:getName())
	return 1
end

local function _imprisonOff(buffSender, target, buff, buffEffect)
	local battleController = ModuleManager.BattleManager.battleController
	if battleController then
		battleController.battleData:lockAllSkillGrid(false, target.side)
	end
	target.unitEntity:removeActiveSkillLimit(buff:getName())
	return 1
end

local function _frozenOn(buffSender, buff, target, buffEffect)
	if not target.unitEntity:getIsFrozen() then
		target:putCacheBuffByDecr(BattleConst.BUFF_DECR_TYPE.INCREASE_GAIN)
	end
	target.unitEntity:addLimit(buff:getName(), buffEffect)
	return 1
end

local function _frozenOff(buffSender, target, buff, buffEffect)
	target.unitEntity:removeLimit(buff:getName(), buffEffect)
	if not target.unitEntity:getIsFrozen() then
		target:popCacheBuffByDecr(BattleConst.BUFF_DECR_TYPE.INCREASE_GAIN)
	end
	return 1
end

local function _lockOn(buffSender, buff, target, buffEffect)
	target.battleController:lockElement(buff:getEffectNum(), false)
	return 1
end

local function _lockOff(buffSender, target, buff, buffEffect)
	target.battleController:lockElement(buff:getEffectNum(), true)
	return 1
end

local function _invalidControlOn(buffSender, buff, target, buffEffect)
	if not target.unitEntity:getIsInvalidControl() then --只能添加一次
		target.unitEntity:addAttr(BattleConst.ATTR_NAME.INVALID_CONTROL, 1, false)
	end
	return 1
end

local function _invalidControlOff(buffSender, target, buff, buffEffect)
	if target.unitEntity:getIsInvalidControl() then
		target.unitEntity:addAttr(BattleConst.ATTR_NAME.INVALID_CONTROL, -1, false)
	end
	return 1
end

local function _invincibleShieldOn(buffSender, buff, target, buffEffect)
	local shieldNum = buff:getEffectNum()
	target.team:addInvincibleShield(buffEffect)
	target.unitEntity:addAttr(ATTR_NAME.INVINCIBLE_SHIELD, shieldNum, false)
	return shieldNum
end

local function _invincibleShieldOff(buffSender, target, buff, buffEffect)
	target.team:removeShield(buffEffect)
	target.unitEntity:setAttr(ATTR_NAME.INVINCIBLE_SHIELD, 0)
	return 1
end

local function _rebirthOn(buffSender, buff, target, buffEffect)
	local atk = target.unitEntity:getAtk()
	target.unitEntity:setAttr(ATTR_NAME.REBIRTH, atk, false)
	return 1
end

local function _rebirthOff(buffSender, target, buff, buffEffect)
	-- 回血
	target.unitEntity:setAttr(ATTR_NAME.REBIRTH, 0)
	target:rebirth()
	local damage, hurtStatus = BattleFormula:getDamageOrCureResult(target, buff, target)
	if damage <= 0 then
		damage = 1
	end
	target:takeDamageOrCure(buffEffect.sender, damage, EFFECT_TYPE.HEAL, hurtStatus, buff:getName())
	return 1
end

local function _charmOn(buffSender, buff, target, buffEffect)
	local battleController = target.battleController
	if battleController then
		battleController.battleData:lockAllSkillGrid(true, target.side)
	end
	target.unitEntity:addActiveSkillLimit(buff:getName())
	target:removeBuffByDecr(BattleConst.BUFF_DECR_TYPE.INCREASE_GAIN)
	target:removeAllShield()

	return 1
end

local function _charmOff(buffSender, target, buff, buffEffect)
	local battleController = target.battleController
	if battleController then
		battleController.battleData:lockAllSkillGrid(false, target.side)
	end
	target.unitEntity:removeActiveSkillLimit(buff:getName())
	return 1
end

local function _immuneOn(buffSender, buff, target, buffEffect)
	target.unitEntity:addAttr(ATTR_NAME.IMMUNE_REDUCTION_BENEFIT, buff:getEffectNum(), false)
	target:removeBuffByDecr(BattleConst.BUFF_DECR_TYPE.REDUCE_GAIN)
	return 1
end

local function _immuneOff(buffSender, target, buff, buffEffect)
	target.unitEntity:addAttr(ATTR_NAME.IMMUNE_REDUCTION_BENEFIT, -buff:getEffectNum(), false)
	return 1
end

local _handleOn = {
	[BUFF_NAME.ADD_SKILL] = _addSkillOn,						-- 添加技能
	[BUFF_NAME.SKILL_FIRE_TIMES] = _skillFireTimesOn,			-- 技能额外使用次数
	[BUFF_NAME.BLEED] = _bleedOn,								-- 流血
	[BUFF_NAME.UNDEAD] = _undeadOn,								-- 不死
	[BUFF_NAME.IMPRISON] = _imprisonOn,							-- 禁锢
	[BUFF_NAME.FROZEN] = _frozenOn,								-- 冻结
	[BUFF_NAME.LOCK] = _lockOn,									-- 锁定
	[BUFF_NAME.INVALID_CONTROL] = _invalidControlOn,			-- 无控
	[BUFF_NAME.INVINCIBLE_SHIELD] = _invincibleShieldOn,		-- 层数护盾
	[BUFF_NAME.REBIRTH] = _rebirthOn,							-- 重生
	[BUFF_NAME.CHARM] = _charmOn,								-- 魅惑
	[BUFF_NAME.IMMUNE] = _immuneOn,								-- 免疫
}

local _handleOff = {
	[BUFF_NAME.ADD_SKILL] = _addSkillOff,						-- 添加技能
	[BUFF_NAME.SKILL_FIRE_TIMES] = _skillFireTimesOff,			-- 技能额外使用次数
	[BUFF_NAME.BLEED] = _bleedOff,								-- 流血
	[BUFF_NAME.UNDEAD] = _undeadOff,							-- 不死
	[BUFF_NAME.IMPRISON] = _imprisonOff,						-- 禁锢
	[BUFF_NAME.FROZEN] = _frozenOff,							-- 冻结
	[BUFF_NAME.LOCK] = _lockOff,								-- 锁定
	[BUFF_NAME.INVALID_CONTROL] = _invalidControlOff,			-- 无控
	[BUFF_NAME.INVINCIBLE_SHIELD] = _invincibleShieldOff,		-- 层数护盾
	[BUFF_NAME.REBIRTH] = _rebirthOff,							-- 重生
	[BUFF_NAME.CHARM] = _charmOff,								-- 魅惑
	[BUFF_NAME.IMMUNE] = _immuneOff,							-- 免疫
}

local _handleWork = {
	[BUFF_NAME.BLEED] = _bleedWork,								-- 流血
}

-- 特殊buff添加时
function BattleBuffSpecial.specialBuffOn(unitComp, buff, target, buffEffect)
	local func = _handleOn[buff:getName()]
	if func then
		return func(unitComp, buff, target, buffEffect)
	end
	return 0
end

-- 特殊buff移除时
function BattleBuffSpecial.specialBuffOff(buffSender, target, buff, buffEffect)
	local func = _handleOff[buff:getName()]
	if func then
		func(buffSender, target, buff, buffEffect)
	end
end

-- 特殊buff生效
function BattleBuffSpecial.specialBuffWork(unitComp, buffEffect, buff)
	local func = _handleWork[buff:getName()]
	if func then
		func(unitComp, buffEffect, buff)
	end
end

return BattleBuffSpecial