local BattleBuffEntity = require "app/userdata/battle/skill/battle_buff_entity"
local BattleConst = require "app/module/battle/battle_const"

local BattleSkillEntity = class("BattleSkillEntity", BaseData)

BattleSkillEntity.sid = 0

function BattleSkillEntity:ctor(skillId, skillType, owner, skillShowId)
	self.skillType = skillType
	self.skillId = skillId
	self.owner = owner
	if skillShowId then
		self.skillShow = ConfigManager:getConfig("skin_skill")[skillShowId]
	else
		self.skillShow = nil
	end
	BattleSkillEntity.sid = BattleSkillEntity.sid + 1
	self.sid = BattleSkillEntity.sid
	self:init()
end

function BattleSkillEntity:init()
	self.skillInfo = ConfigManager:getConfig("skill")[self.skillId]
	self.coolingRounds = self.skillInfo.cd or 0
	if self.skillInfo.cd_start then -- 开场就进入cd
		self.cd = self.skillInfo.cd_start
	else
		self.cd = 0
	end
	self:initSkillEffect()
	self:initEffectBlock()
	if self.skillInfo.effect or self.skillInfo.name_act or self.skillInfo.skill_type then
		self.available = true
	else
		self.available = false
	end
	self:clearRecordData()
	self.buffConditionRel = nil
end

function BattleSkillEntity:initSkillEffect()
	self.effectList = {}
	self.isHurtType = false
	local effect = self.skillInfo.effect
	if self:getUsePvpEffect() then
		effect = self.skillInfo.pvp_effect or effect
	end
	if effect then
		for k, v in ipairs(effect) do
			local buffEntity = BattleBuffEntity:create()
			buffEntity:init(v, self.owner, self)
			if buffEntity:getIsHurtType() then
				self.isHurtType = true
			end
			table.insert(self.effectList, buffEntity)
		end
	end
end

function BattleSkillEntity:initEffectBlock()
	if not self.effectBlock then
		self.effectBlock = {}
		self.blockTime = {}
	else
		for i = #self.effectBlock, 1, -1 do
			table.remove(self.effectBlock)
		end
		for i = #self.blockTime, 1, -1 do
			table.remove(self.blockTime)
		end
	end
	if self.skillInfo.effect_block then
		for _, idx in ipairs(self.skillInfo.effect_block) do
			table.insert(self.effectBlock, idx)
		end
	else
		local count = 0
		local effect = self.skillInfo.effect
		if self:getUsePvpEffect() then
			effect = self.skillInfo.pvp_effect or effect
		end
		if effect then
			count = #effect
		end
		table.insert(self.effectBlock, count)
	end
	if self.skillInfo.block_time then
		for _, time in ipairs(self.skillInfo.block_time) do
			table.insert(self.blockTime, time / 1000)
		end
	end
end

function BattleSkillEntity:setUsePvpEffect(use)
	self.usePvpEffect = use
end

function BattleSkillEntity:getUsePvpEffect()
	if self.usePvpEffect == nil then
		local battleController = ModuleManager.BattleManager.battleController
		self.usePvpEffect = battleController:getIsPvpBattle() or false
	end
	return self.usePvpEffect
end

function BattleSkillEntity:startUse()
	self.skillCanUseTimes = self.owner:getSkillExtraUseTimes(self.skillId) + 1
end

function BattleSkillEntity:getSkillCanUseTimes()
	return self.skillCanUseTimes
end

function BattleSkillEntity:cooldown(round)
	if self.cd > 0 then
		self.cd = self.cd - (round or 1)
		if self.cd < 0 then
			self.cd = 0
		end
	end
end

-- 技能是否可用
function BattleSkillEntity:getIsAvailable()
	if not self.available then
		return false
	end
	return self.cd == 0
end

-- 技能释放完毕
function BattleSkillEntity:endUse()
	self.cd = self.coolingRounds
	if self.skillCanUseTimes then
		self.skillCanUseTimes = self.skillCanUseTimes - 1
	end
end

function BattleSkillEntity:addSkillEffectParams(effect)
	local buffEntity
	for _, entity in ipairs(self.effectList) do
		if entity:getName() == effect.type then
			buffEntity = entity
			buffEntity:setEffectNum(buffEntity:getEffectNum() + effect.num)
		end
	end
	if not buffEntity then
		buffEntity = BattleBuffEntity:create()
		buffEntity:init(effect, self.owner, self)
		table.insert(self.effectList, buffEntity)
	end
end

function BattleSkillEntity:addSkillEffectRound(effect)
	local buffEntity
	for _, entity in ipairs(self.effectList) do
		if entity:getName() == effect.type then
			buffEntity = entity
			buffEntity:setRound(buffEntity:getRound() + effect.round)
		end
	end
	if not buffEntity then
		buffEntity = BattleBuffEntity:create()
		buffEntity:init(effect, self.owner, self)
		table.insert(self.effectList, buffEntity)
	end
end

function BattleSkillEntity:addSkillEffectRatio(effect)
	local buffEntity
	for _, entity in ipairs(self.effectList) do
		if entity:getName() == effect.type then
			buffEntity = entity
			buffEntity:setRatio(buffEntity:getRatio() + effect.ratio)
		end
	end
	if not buffEntity then
		buffEntity = BattleBuffEntity:create()
		buffEntity:init(effect, self.owner, self)
		table.insert(self.effectList, buffEntity)
	end
end

function BattleSkillEntity:getSkillSide()
	if self.owner then
		return self.owner:getSide()
	end
end

function BattleSkillEntity:getIsAtkSideSkill()
	return self:getSkillSide() == GConst.BattleConst.SIDE_ATK
end

function BattleSkillEntity:getSkillId()
	return self.skillId
end

function BattleSkillEntity:getIsPassiveType()
	return self.skillType == BattleConst.SKILL_TYPE_PASSIVE
end

function BattleSkillEntity:getIsNormalType()
	return self.skillType == BattleConst.SKILL_TYPE_NORMAL
end

function BattleSkillEntity:getIsActiveType()
	return self.skillType == BattleConst.SKILL_TYPE_ACTIVE
end

-- 消除类技能
function BattleSkillEntity:getEliminateSkillType()
	return self.skillInfo.skill_type
end

function BattleSkillEntity:isAttackOverActive()
    return GConst.BattleConst.ATTACK_OVER_ACTIVE_SKILL_TYPE[self:getEliminateSkillType()]
end

-- 消除类技能参数
function BattleSkillEntity:getEliminateSkillParameter()
	return self.skillInfo.skill_type_parameter
end

function BattleSkillEntity:getComboPosition()
	return self.skillInfo.combo_position
end

function BattleSkillEntity:changeSkillId(skillId)
	self.skillId = skillId
	self:init()
end

function BattleSkillEntity:getMoveType()
	if self.skillShow then
		if not self.skillShow.skill_position then
			return
		end
		return self.skillShow.skill_position[1]
	end

	if not self.skillInfo.skill_position then
		return
	end
	return self.skillInfo.skill_position[1]
end

function BattleSkillEntity:getMoveTypeParams()
	if self.skillShow then
		if not self.skillShow.skill_position then
			return 0
		end
		return self.skillShow.skill_position[2] or 0
	end

	if not self.skillInfo.skill_position then
		return 0
	end
	return self.skillInfo.skill_position[2] or 0
end

function BattleSkillEntity:getSkillAttackName()
	if self.skillShow then
		return self.skillShow.name_act
	end

	return self.skillInfo.name_act
end

function BattleSkillEntity:getEffectList()
	return self.effectList
end

function BattleSkillEntity:getEffectBlock()
	return self.effectBlock
end

function BattleSkillEntity:isFinalBlock(index)
	return self.effectBlock[index + 1] == nil
end

function BattleSkillEntity:getEffectBlockTime()
	return self.blockTime
end

function BattleSkillEntity:getBuffCondition(index)
	if not self.skillInfo.buff_condition then
		return
	end
	return self.skillInfo.buff_condition[index]
end

function BattleSkillEntity:getBuffConditionRel(index)
	if not self.skillInfo.condition_rel then
		return
	end
	if not self.buffConditionRel then
		self.buffConditionRel = {}
		for i, info in ipairs(self.skillInfo.condition_rel)  do
			self.buffConditionRel[info[1]] = {i, info[2]}
		end
	end
	return self.buffConditionRel[index]
end

function BattleSkillEntity:haveBuffCondition()
	return self.skillInfo.condition_rel ~= nil
end

function BattleSkillEntity:getTargetType()
	return self.skillInfo.obj
end

function BattleSkillEntity:getSid()
	return self.sid
end

function BattleSkillEntity:getPassiveTriggerValue()
	return self.skillInfo.trigger_value
end

function BattleSkillEntity:getPassiveTriggerId()
	return self.skillInfo.trigger
end

function BattleSkillEntity:getFxBg()
	if self.skillShow then
		if not self:getIsAtkSideSkill() and self:getUsePvpEffect() then
			return self.skillShow.fx_bg_mirror or self.skillShow.fx_bg
		else
			return self.skillShow.fx_bg
		end
	end

	if not self:getIsAtkSideSkill() and self:getUsePvpEffect() then
		return self.skillInfo.fx_bg_mirror or self.skillInfo.fx_bg
	else
		return self.skillInfo.fx_bg
	end
end

function BattleSkillEntity:getFxSelf()
	if self.skillShow then
		if not self:getIsAtkSideSkill() and self:getUsePvpEffect() then
			return self.skillShow.fx_self_mirror or self.skillShow.fx_self
		else
			return self.skillShow.fx_self
		end
	end

	if not self:getIsAtkSideSkill() and self:getUsePvpEffect() then
		return self.skillInfo.fx_self_mirror or self.skillInfo.fx_self
	else
		return self.skillInfo.fx_self
	end
end

function BattleSkillEntity:getFxSelfDelay()
	if self.skillShow then
		return self.skillShow.fx_self_delay
	end

	return self.skillInfo.fx_self_delay
end

function BattleSkillEntity:getFxTarget()
	if self.skillShow then
		if not self:getIsAtkSideSkill() and self:getUsePvpEffect() then
			return self.skillShow.fx_target_mirror or self.skillShow.fx_target
		else
			return self.skillShow.fx_target
		end
	end

	if not self:getIsAtkSideSkill() and self:getUsePvpEffect() then
		return self.skillInfo.fx_target_mirror or self.skillInfo.fx_target
	else
		return self.skillInfo.fx_target
	end
end

function BattleSkillEntity:getFxTargetDelay()
	if self.skillShow then
		return self.skillShow.fx_target_delay
	end

	return self.skillInfo.fx_target_delay
end

function BattleSkillEntity:getShakeType()
	if self.skillShow then
		return self.skillShow.shake_type
	end

	return self.skillInfo.shake_type
end

function BattleSkillEntity:getShakeTime()
	if self.skillShow then
		return self.skillShow.shake_time
	end

	return self.skillInfo.shake_time
end

function BattleSkillEntity:getSoundHit()
	if self.skillShow then
		return self.skillShow.sound_hit
	end

	return self.skillInfo.sound_hit
end

function BattleSkillEntity:getSoundDelay()
	if self.skillShow then
		return self.skillShow.sound_delay or 0
	end

	return self.skillInfo.sound_delay or 0
end

function BattleSkillEntity:getSkillSound()
	if self.skillShow then
		return self.skillShow.sound
	end

	return self.skillInfo.sound
end

function BattleSkillEntity:getRecordData(name)
	if self.recordData == nil then
		self.recordData = {}
	end
	return self.recordData[name]
end

function BattleSkillEntity:setRecordData(name, value)
	if self.recordData == nil then
		self.recordData = {}
	end
	self.recordData[name] = value
end

function BattleSkillEntity:clearRecordData()
	if self.recordData then
		for k, v in pairs(self.recordData) do
			self.recordData[k] = nil
		end
	end
end

-- 子弹时间参数
function BattleSkillEntity:getSlowDownBulletTimeParams()
	if self.skillShow then
		return self.skillShow.bullet_time
	end

	return self.skillInfo.bullet_time
end

function BattleSkillEntity:getIsHurtType()
	return self.isHurtType
end

function BattleSkillEntity:getHitNameList()
	return self.skillInfo.name_hit or {}
end

return BattleSkillEntity