local BattleBoardSkillEntity = class("BattleBoardSkillEntity", BaseData)
local BattleBuffEntity = require "app/userdata/battle/skill/battle_buff_entity"

function BattleBoardSkillEntity:ctor(skillId, side)
    self:refreshSkillId(skillId)
    self.side = side
    self.curEnergy = 0
    self.addRange = {}
    self.linkEffectEntities = {}    -- 链接攻击伤害 type = 3
    self.inInfluenceEntities = {}   -- 技能消除攻击伤害 type = 11
    self.skillAttackBeforeEffectEntities = {}   -- 战斗开始前获得技能效果 type = 12
    self.elementCountEffectEntities = {}    -- 根据消除数量获得次数的技能效果 type = 13
    self.linkCountMoreEffects = {}  -- 链接超过x元素获得一次技能效果 type = 14
    self.linkCountPowerEffects = {} -- 链接超过x元素获得倍数技能效果 type = 15
    self.skillEffectNumAdd = {} -- 技能效果参数增加 type = 7 用于技能替换时生效
    self.skillRoundAdd = {} -- 技能效果回合增加 type = 8 用于技能替换时生效
    self.skillRatioAdd = {} -- 技能效果概率增加 type = 16 用于技能替换时生效
    self.originSkillId = skillId

    self.upSkillIdMap = {}
    self.getUpSkillKind = 0
end

function BattleBoardSkillEntity:refreshSkillId(skillId)
    if self.skillId == skillId then
        return
    end
    self.skillId = skillId
    self.config = ConfigManager:getConfig("skill")[skillId]
end

function BattleBoardSkillEntity:getSkillId()
    return self.skillId
end

function BattleBoardSkillEntity:getUnlocked()
    -- return self.unlocked
    return true
end

function BattleBoardSkillEntity:setUnlock()
    if self.unlocked then
        return
    end
    self.unlocked = true
end

function BattleBoardSkillEntity:setUnlockId(unlockId)
    self.unlockId = unlockId
end

function BattleBoardSkillEntity:getUnlockId()
    return self.unlockId
end

function BattleBoardSkillEntity:getOriginId()
    return self.originSkillId or self:getSkillId()
end

function BattleBoardSkillEntity:getNeedEnergy()
    if not self.config then
        return 1
    end
    return self.config.energy
end

function BattleBoardSkillEntity:getPosition()
    if not self.config then
        return 1
    end
    return self.config.position
end

function BattleBoardSkillEntity:getMethond()
    if not self.config then
        return
    end

    if not self.methondType then
        self.methondType = self.config.method
    end

    return self.methondType
end

function BattleBoardSkillEntity:setMethond(method)
    self.methondType = method
end

function BattleBoardSkillEntity:getSkillType()
    if not self.config then
        return
    end
    return self.config.skill_type
end

function BattleBoardSkillEntity:isAttackOverActive()
    return GConst.BattleConst.ATTACK_OVER_ACTIVE_SKILL_TYPE[self:getSkillType()]
end

function BattleBoardSkillEntity:getSkillTypeParameter()
    if not self.config then
        return
    end
    return self.config.skill_type_parameter
end

function BattleBoardSkillEntity:getSkillEffectType()
    if not self.config then
        return nil
    end
    return self.config.effect_type
end

function BattleBoardSkillEntity:getBoardRange()
    if not self.config or not self.config.boardrange then
        return
    end

    local boardRangeList = {}
    local map
    for _, info in ipairs(self.config.boardrange) do
        local singleInfo = {
            type = info.type,
            range = info.range
        }
        if self.addRange[info.type] then
            if not map then
                map = {}
            end
            map[info.type] = true
            singleInfo.range = singleInfo.range + self.addRange[info.type]
        end
        table.insert(boardRangeList, singleInfo)
    end
    for t, v in pairs(self.addRange) do
        if not map or not map[t] then
            local singleInfo = {
                type = t,
                range = v
            }
            table.insert(boardRangeList, singleInfo)
        end
    end
    return boardRangeList
end

function BattleBoardSkillEntity:addBoardRange(range)
    for _, info in ipairs(range) do
        if self.addRange[info.type] then
            self.addRange[info.type] = self.addRange[info.type] + info.range
        else
            self.addRange[info.type] = info.range
        end
        if self.addRange[info.type] <= 0 then
            self.addRange[info.type] = nil
        end
    end
end

function BattleBoardSkillEntity:getEffect()
    if not self.config then
        return
    end
    return self.config.effect
end

function BattleBoardSkillEntity:getTartget()
    if not self.config then
        return
    end
    return self.config.obj
end

function BattleBoardSkillEntity:getIcon()
    if not self.config then
        return
    end
    return self.config.icon
end

function BattleBoardSkillEntity:getBattleIcon()
    if not self.config then
        return
    end
    if self.getUpSkillKind > 0 then
        return tostring(self.config.battle_icon) .. "_" .. self.getUpSkillKind
    else
        return tostring(self.config.battle_icon)
    end
end

function BattleBoardSkillEntity:getNameAct()
    if not self.config then
        return
    end
    return self.config.name_act
end

function BattleBoardSkillEntity:cfgLinkAny()
    if not self.config then
        return false
    end
    return self.config.link ~= nil
end

function BattleBoardSkillEntity:getEnergy()
    return self.curEnergy
end

function BattleBoardSkillEntity:getEnergyEnough(onlyGetBool)
    local enough = self.curEnergy >= self:getNeedEnergy()
    if enough and not onlyGetBool then
        self:clearEnergy()
    end
    return enough
end

function BattleBoardSkillEntity:addEnergy(count)
    self.curEnergy = self.curEnergy + count
end

function BattleBoardSkillEntity:clearEnergy()
    self.curEnergy = 0
end

function BattleBoardSkillEntity:getIgnoreElementType()
    if self:cfgLinkAny() then
        return true
    end

    return self.ignoreElementType
end

function BattleBoardSkillEntity:setIgnoreElementType(ignore)
    self.ignoreElementType = ignore
end

function BattleBoardSkillEntity:getLinkEffects()
    return self.linkEffectEntities
end

function BattleBoardSkillEntity:addLinkEffect(effect, unitEntity, targetSide)
    effect = GFunc.getTable(effect)
    local buffEntities = self.linkEffectEntities[effect.type]
    if not buffEntities then
        self.linkEffectEntities[effect.type] = {}
        buffEntities = self.linkEffectEntities[effect.type]
        local list = GConst.BattleConst.BUFF_MATCH_NAME[effect.type]
        if not list then
            return
        end

        for elementType, buffName in ipairs(list) do
            local buffEntity = BattleBuffEntity:create()
            effect.type = buffName
            buffEntity:init(effect, unitEntity)
            buffEntity:setTargetSide(targetSide)
            buffEntities[elementType] = buffEntity
        end
    else
        for elementType, buffEntity in pairs(buffEntities) do
            local buffNum = buffEntity:getEffectNum()
            buffEntity:setOwner(unitEntity)
            buffEntity:setEffectNum(buffEntity:getEffectNum() + buffNum)
            buffEntity:setTargetSide(targetSide)
        end
    end
end

function BattleBoardSkillEntity:getInInfluenceEffects()
    return self.inInfluenceEntities
end

function BattleBoardSkillEntity:addInInfluenceEffect(effect, unitEntity, targetSide)
    effect = GFunc.getTable(effect)
    local buffEntities = self.inInfluenceEntities[effect.type]
    if not buffEntities then
        self.inInfluenceEntities[effect.type] = {}
        buffEntities = self.inInfluenceEntities[effect.type]
        local list = GConst.BattleConst.BUFF_MATCH_NAME[effect.type]
        if not list then
            return
        end

        for elementType, buffName in ipairs(list) do
            local buffEntity = BattleBuffEntity:create()
            effect.type = buffName
            buffEntity:init(effect, unitEntity)
            buffEntity:setTargetSide(targetSide)
            buffEntities[elementType] = buffEntity
        end
    else
        for elementType, buffEntity in pairs(buffEntities) do
            local buffNum = buffEntity:getEffectNum()
            buffEntity:setOwner(unitEntity)
            buffEntity:setEffectNum(buffEntity:getEffectNum() + buffNum)
            buffEntity:setTargetSide(targetSide)
        end
    end
end

function BattleBoardSkillEntity:addSkillAttackBeforeEffect(rogueSkill, index, effect, unitEntity, targetSide)
    if not self.skillAttackBeforeEffectEntities[rogueSkill] then
        self.skillAttackBeforeEffectEntities[rogueSkill] = {}
    end
    local buffEntity = self.skillAttackBeforeEffectEntities[rogueSkill][index]
    if not buffEntity then
        buffEntity = BattleBuffEntity:create()
        buffEntity:init(effect, unitEntity)
        self.skillAttackBeforeEffectEntities[rogueSkill][index] = buffEntity
    else
        buffEntity:init(effect, unitEntity)
    end
    buffEntity:setTargetSide(targetSide)
end

function BattleBoardSkillEntity:removeSkillAttackBeforeEffect(rogueSkill)
    self.skillAttackBeforeEffectEntities[rogueSkill] = nil
end

function BattleBoardSkillEntity:getSkillAttackBeforeEffects()
    return self.skillAttackBeforeEffectEntities
end

function BattleBoardSkillEntity:addElementCountEffect(rogueSkill, index, effect, unitEntity, targetSide)
    if not self.elementCountEffectEntities[rogueSkill] then
        self.elementCountEffectEntities[rogueSkill] = {}
    end
    local buffEntities = self.elementCountEffectEntities[rogueSkill][index]
    if not buffEntities then
        self.elementCountEffectEntities[rogueSkill][index] = {}
        buffEntities = self.elementCountEffectEntities[rogueSkill][index]

        local originBuffEntity = BattleBuffEntity:create()
        originBuffEntity:init(effect, unitEntity)
        originBuffEntity:setTargetSide(targetSide)

        local useBuffEntity = BattleBuffEntity:create()
        useBuffEntity:init(effect, unitEntity)
        useBuffEntity:setTargetSide(targetSide)

        buffEntities.origin = originBuffEntity
        buffEntities.use = useBuffEntity
    else
        local originBuffEntity = buffEntities.origin
        local useBuffEntity = buffEntities.use
        local buffNum = originBuffEntity:getEffectNum()
        originBuffEntity:init(effect, unitEntity)
        originBuffEntity:setEffectNum(originBuffEntity:getEffectNum() + buffNum)
        originBuffEntity:setTargetSide(targetSide)

        useBuffEntity:init(effect, unitEntity)
        useBuffEntity:setEffectNum(originBuffEntity:getEffectNum())
        useBuffEntity:setTargetSide(targetSide)
    end
end

function BattleBoardSkillEntity:removeElementCountEffect(rogueSkill)
    self.elementCountEffectEntities[rogueSkill] = nil
end

function BattleBoardSkillEntity:getElementCountEffect()
    return self.elementCountEffectEntities
end

function BattleBoardSkillEntity:getEliminateEffects(battleController)
    local unitEntity = battleController:getCurActionTeam(self.side):getUnitComp()[self:getPosition()].unitEntity
    if not unitEntity or not self.config.eliminate_effect then
        return
    end

    if not self.eliminateBuffEntities then
        self.eliminateBuffEntities = {}
        for _, effect in ipairs(self.config.eliminate_effect) do
            local buffEntity = BattleBuffEntity:create()
            buffEntity:init(effect, unitEntity)
            buffEntity:setTargetSide(self:getEliminateEffectTarget())
            table.insert(self.eliminateBuffEntities, buffEntity)
        end
    end

    return self.eliminateBuffEntities
end

function BattleBoardSkillEntity:getEliminateEffectTarget()
    return self.config.eliminate_obj
end

function BattleBoardSkillEntity:addUpSkills(skillList)
    for _, skillId in ipairs(skillList) do
        self.upSkillIdMap[skillId] = false
    end
    self.getUpSkillKind = 0
end

function BattleBoardSkillEntity:gotUpSKill(skillId)
    if self.upSkillIdMap[skillId] == nil then
        return false
    end

    if not self.upSkillIdMap[skillId] then
        self.getUpSkillKind = self.getUpSkillKind + 1
    end

    self.upSkillIdMap[skillId] = true

    return true
end

function BattleBoardSkillEntity:addLinkCountMoreEffects(rogueSkill, index, effect, unitEntity, targetSide, paramsCount)
    if not self.linkCountMoreEffects[rogueSkill] then
        self.linkCountMoreEffects[rogueSkill] = {}
    end
    local info = self.linkCountMoreEffects[rogueSkill][index]
    if not info then
        info = {paramsCount = paramsCount}
        info.buffEntity = BattleBuffEntity:create()
        info.buffEntity:init(effect, unitEntity)
        self.linkCountMoreEffects[rogueSkill][index] = info
    else
        info.buffEntity:init(effect, unitEntity)
    end
    info.buffEntity:setTargetSide(targetSide)
end

function BattleBoardSkillEntity:removeLinkCountMoreEffects(rogueSkill)
    self.linkCountMoreEffects[rogueSkill] = nil
end

function BattleBoardSkillEntity:getLinkCountMoreEffects()
    return self.linkCountMoreEffects
end

function BattleBoardSkillEntity:addLinkCountPowerEffects(rogueSkill, index, effect, unitEntity, targetSide, paramsCount)
    if not self.linkCountPowerEffects[rogueSkill] then
        self.linkCountPowerEffects[rogueSkill] = {}
    end
    local info = self.linkCountPowerEffects[rogueSkill][index]
    if not info then
        info = {paramsCount = paramsCount}
        info.originBuffEntity = BattleBuffEntity:create()
        info.originBuffEntity:init(effect, unitEntity)
        info.originBuffEntity:setTargetSide(targetSide)

        info.useBuffEntity = BattleBuffEntity:create()
        info.useBuffEntity:init(effect, unitEntity)
        info.useBuffEntity:setTargetSide(targetSide)

        self.linkCountPowerEffects[rogueSkill][index] = info
    else
        info.originBuffEntity:init(effect, unitEntity)
        info.originBuffEntity:setTargetSide(targetSide)

        info.useBuffEntity:init(effect, unitEntity)
        info.useBuffEntity:setTargetSide(targetSide)
    end
end

function BattleBoardSkillEntity:removeLinkCountPowerEffects(rogueSkill)
    self.linkCountPowerEffects[rogueSkill] = nil
end

function BattleBoardSkillEntity:getLinkCountPowerEffects()
    return self.linkCountPowerEffects
end

function BattleBoardSkillEntity:addSkillEffecuNumAdd(effect)
    local effectInfo = self.skillEffectNumAdd[effect.type]
    if effectInfo then
        effectInfo.num = effectInfo.num + effect.num
    else
        self.skillEffectNumAdd[effect.type] = effect
    end
end

function BattleBoardSkillEntity:getSkillEffecuNumAdd()
    return self.skillEffectNumAdd
end

function BattleBoardSkillEntity:addSkillRoundAdd(effect)
    local effectInfo = self.skillRoundAdd[effect.type]
    if effectInfo then
        effectInfo.round = effectInfo.round + effect.round
    else
        self.skillRoundAdd[effect.type] = effect
    end
end

function BattleBoardSkillEntity:getSkillRoundAdd()
    return self.skillRoundAdd
end

function BattleBoardSkillEntity:addSkillRatioAdd(effect)
    local effectInfo = self.skillRatioAdd[effect.type]
    if effectInfo then
        effectInfo.round = effectInfo.round + effect.round
    else
        self.skillRatioAdd[effect.type] = effect
    end
end

function BattleBoardSkillEntity:getSkillRatioAdd()
    return self.skillRatioAdd
end

function BattleBoardSkillEntity:addSkillBreakEnergyMultiple(multiple)
    self.energyMultiple = multiple
end

function BattleBoardSkillEntity:getSkillBreakEnergyMultiple()
    return self.energyMultiple or 1
end

function BattleBoardSkillEntity:getSkillBreakEnergyMultipleStr()
    if not self.energyMultiple or self.energyMultiple <= 1 then
        return
    end

    return "x" .. self.energyMultiple
end

return BattleBoardSkillEntity