local BattleHelper = require "app/module/battle/helper/battle_helper"
local BattleConst = require "app/module/battle/battle_const"

local BattleFormula = {}

local DEFAULT_FACTOR = 10000
local HURT_STATE_CRIT = BattleConst.HURT_STATE_CRIT

function BattleFormula:getDamageOrCureResult(unitComp, buff, targetUnitComp)
	local func = self.calculateFormula[buff:getFormula()]
	if func then
		return func(unitComp, buff, targetUnitComp)
	end
	return 0
end

function BattleFormula:getAffectedHeal(num, target)
	return BattleFormula.calculateFormula[5](num, target)
end

function BattleFormula:getExpectedDamageResult(unitComp, count, targetUnitComp, skillId, atkCompMap)
	-- (元素个数*攻击者攻击力+链接技能的伤害) * 受击者伤害减免
	-- 普攻
	local result = unitComp.unitEntity:getAtk() * count
	local atkMatchType = unitComp.unitEntity:getMatchType()
	local coefficient = math.max(DEFAULT_FACTOR - targetUnitComp.unitEntity:getDecDmg(atkMatchType), 0)
	result = result * coefficient // DEFAULT_FACTOR
	-- 技能
	if skillId and atkCompMap then
		local skillConfig = ConfigManager:getConfig("skill")[skillId]
		if skillConfig and skillConfig.effect and skillConfig.position then
			local matchType = skillConfig.position
			if atkCompMap[matchType] then
				local atk = atkCompMap[matchType].unitEntity:getAtk()
				local dmg = 0
				for _, effect in ipairs(skillConfig.effect) do
					local buffConfig = ConfigManager:getConfigWithOtherKey("buff", "name")[effect.type]
					if buffConfig and buffConfig.formula == 1 then -- 伤害公式
						dmg = dmg + effect.num * atk
					end
				end
				local coefficient = math.max(DEFAULT_FACTOR - targetUnitComp.unitEntity:getDecDmg(atkMatchType), 0)
				result = result + (dmg * coefficient // DEFAULT_FACTOR) // DEFAULT_FACTOR
			end
		end
	end
	-- 最终伤害
	result = result * (DEFAULT_FACTOR - unitComp.unitEntity:getEndDmgDecAll() + unitComp.unitEntity:getEndDmgAddtionAll()) // DEFAULT_FACTOR
	return result
end

BattleFormula.calculateFormula = {
	-- (（攻击）*技能倍率*(1+(攻击者元素伤害增加+所有伤害增加）（攻击者）- (攻击者元素伤害降低+所有伤害降低) +(受到元素伤害增加+受到所有伤害增加（受击）-受到元素伤害降低-受到所有伤害降低（受击） + 主动技能增伤) + 固定值) *暴击伤害*(1-最终造成伤害降低%+最终造成伤害增加%)
	[1] = function(unitComp, buff, targetUnit)
		local skillFixedAdd = 0
		local skillPAdd = 0
		local hostSkill = buff:getHostSkill()
		local atkMatchType = unitComp.unitEntity:getMatchType()
		if hostSkill then -- 技能伤害加成
			if hostSkill:getIsActiveType() then -- 主动技能
				skillFixedAdd = unitComp.unitEntity:getSkillHurtFixed()
				skillPAdd = unitComp.unitEntity:getSkillHurtP()
			elseif hostSkill:getIsNormalType() then -- 普攻
				skillFixedAdd = unitComp.unitEntity:getNormalSkillHurtFixed()
				skillPAdd = unitComp.unitEntity:getNormalSkillHurtP()
			end
			skillPAdd = skillPAdd + unitComp.unitEntity:getAllHurtP()
		end

		local result = unitComp.unitEntity:getAtk() * buff:getEffectNum() // DEFAULT_FACTOR -- 基础值(攻击 * 技能倍率)
		result = result * (DEFAULT_FACTOR
			+ unitComp.unitEntity:getDmgAddition() -- (攻击者元素伤害增加 + 所有伤害增加)
			- unitComp.unitEntity:getDmgDec()   -- (攻击者元素伤害降低 + 所有伤害降低)
			+ targetUnit.unitEntity:getWeakness(atkMatchType) -- (受击者受到元素伤害增加 + 受到所有伤害增加)
			- targetUnit.unitEntity:getDecDmg(atkMatchType) -- (受击者受到元素伤害降低 + 受到所有伤害降低)
			+ skillPAdd) // DEFAULT_FACTOR -- 技能增伤百分比
		result = result + skillFixedAdd -- 固定值

		-- 暴击
		local hurtState = 0
		local crit = unitComp.unitEntity:getCrit()
		if crit > 0 then
			if BattleHelper:random(1, DEFAULT_FACTOR) <= crit then -- 暴击了
				result = result * (BattleHelper:getDefaultCrittime() + unitComp.unitEntity:getCrittime()) // DEFAULT_FACTOR
				hurtState = HURT_STATE_CRIT
			end
		end
		-- 最终伤害
		result = result * (DEFAULT_FACTOR - unitComp.unitEntity:getEndDmgDecAll() + unitComp.unitEntity:getEndDmgAddtionAll()) // DEFAULT_FACTOR
		return result, hurtState
	end,
	-- 生命值*回合开始时的回血系数*(1 + 治疗效果增加)
	[2] = function(unitComp,  buff, targetUnit)
		local result = targetUnit.unitEntity:getMaxHp() * buff:getEffectNum() // DEFAULT_FACTOR * (unitComp.unitEntity:getCureAddition() - unitComp.unitEntity:getCureDec() + DEFAULT_FACTOR) // DEFAULT_FACTOR
		return result, 0
	end,
	-- 角色攻击力*技能倍率*(1+治疗效果增加)
	[3] = function(unitComp,  buff, targetUnit)
		local result = unitComp.unitEntity:getAtk() * buff:getEffectNum() // DEFAULT_FACTOR * (unitComp.unitEntity:getCureAddition() - unitComp.unitEntity:getCureDec() + DEFAULT_FACTOR) // DEFAULT_FACTOR
		return result, 0
	end,
	-- 释放者攻击*技能系数*(1+(攻击者元素伤害增加+所有伤害增加-攻击者元素伤害降低-所有伤害降低+受到元素伤害增加+受到所有伤害增加（受击）-受到元素伤害降低-受到所有伤害降低（受击）)
	[4] = function(unitComp, buff, targetUnit)
		local atkMatchType = unitComp.unitEntity:getMatchType()
		local result = unitComp.unitEntity:getAtk() * buff:getEffectNum() // DEFAULT_FACTOR *
						(DEFAULT_FACTOR + unitComp.unitEntity:getDmgAddition() - unitComp.unitEntity:getDmgDec() + targetUnit.unitEntity:getWeakness(atkMatchType) - targetUnit.unitEntity:getDecDmg(atkMatchType)) // DEFAULT_FACTOR
		return result, 0
	end,
	-- 治疗量 * （治疗效果增减效果）
	[5] = function(num, target)
		local result = num * (target.unitEntity:getCureAddition() - target.unitEntity:getCureDec() + DEFAULT_FACTOR) // DEFAULT_FACTOR
		return result, 0
	end
}

return BattleFormula