local Msg = require("core.Msg")
local Grid = require("bag.Grid")
local BagLogic = require("bag.BagLogic")
local AbsActLogic = require("absAct.AbsActLogic")
local Broadcast = require("broadcast.Broadcast")
local Lang = require("common.Lang")
local Config = require("excel.commonact").ectype
local CommonDefine = require("common.CommonDefine")
local Util = require("common.Util")
local CombatDefine = require("combat.CombatDefine")
local CombatLogic = require("combat.CombatLogic")
local YunYingLogic = require("yunying.YunYingLogic")
local AbsActExcel = require("excel.absAct")


local COMMONACTBOSSABSID = 7501
local COMMONACTFREENUM = 3  -- 免费挑战次数
local COMMONACTDAYID = 99
local COMMONACTBOOSPRIZE = 1 -- BOSS奖励类型
local COMMONACTFIGHTPRIZE = 2 -- 战斗奖励类型

local CommonAct_BossID = nil
local CommonAct_MapID = nil

local function ComActBoss_CreateDB(human)
    if not human.db.absAct[COMMONACTBOSSABSID] then
        human.db.absAct[COMMONACTBOSSABSID] = {}
    end
    
    human.db.absAct[COMMONACTBOSSABSID].tBossInfo = {
        nFreeNum = COMMONACTFREENUM,
        nFreeTime = os.time(),
        nDamage = 0,
        tPrizeInfo = {}
    }

    for nID, v in pairs(Config) do
        if nID ~= COMMONACTDAYID then
            human.db.absAct[COMMONACTBOSSABSID].tBossInfo.tPrizeInfo[nID] = CommonDefine.COMMON_PRIZE_STATE_NOGET
        end
    end
end

-- 检测并创建DB数据
local function ComActBoss_CheckAndCreateDB(human)
    if not human.db.absAct[COMMONACTBOSSABSID] or not human.db.absAct[COMMONACTBOSSABSID].tBossInfo then
        ComActBoss_CreateDB(human)
    end
end

-- 获取奖励数据
local function CommonActBoss_GetPrizeData(human)
    return human.db.absAct[COMMONACTBOSSABSID].tBossInfo.tPrizeInfo
end

-- 获取奖励状态
local function CommonActBoss_GetPrizeStatus(human, nID)
    local tPrizeInfo = CommonActBoss_GetPrizeData(human)
    
    return tPrizeInfo[nID]
end

-- 设置奖励状态
local function CommonActBoss_SetPrizeStatus(human, nID, nValue)
    local tPrizeInfo = CommonActBoss_GetPrizeData(human)

    tPrizeInfo[nID] = nValue
end

-- 获取总伤害
local function CommonActBoss_GetDamage(human)
    return human.db.absAct[COMMONACTBOSSABSID].tBossInfo.nDamage
end

-- 增加总伤害
local function CommonActBoss_AddDamage(human, nNum)
    human.db.absAct[COMMONACTBOSSABSID].tBossInfo.nDamage = human.db.absAct[COMMONACTBOSSABSID].tBossInfo.nDamage + nNum
end

-- 获取免费次数
local function CommonActBoss_GetFreeNum(human)
    return human.db.absAct[COMMONACTBOSSABSID].tBossInfo.nFreeNum
end

-- 设置免费次数
local function CommonActBoss_SetFreeNum(human, nNum)
    human.db.absAct[COMMONACTBOSSABSID].tBossInfo.nFreeNum = nNum
end

-- 获取免费刷新时间
local function CommonActBoss_GetFreeTime(human)
    return human.db.absAct[COMMONACTBOSSABSID].tBossInfo.nFreeTime
end

-- 设置免费刷新时间
local function CommonActBoss_SetFreeTime(human, nTime)
    human.db.absAct[COMMONACTBOSSABSID].tBossInfo.nFreeTime = nTime
end

local function CommonActBoss_IsPrizeRed(human)
    for nID, v in pairs(Config) do
        if nID ~= COMMONACTDAYID then
            local nState = CommonActBoss_GetPrizeStatus(human, nID)
            if nState == CommonDefine.COMMON_PRIZE_STATE_CANGET then
                return true
            end
        end
    end

    return false
end


function isRed(human)
    local state, nEndTime, nOpenTime = AbsActLogic.isStarted(human, COMMONACTBOSSABSID)
    if not state then
        return false
    end

    ComActBoss_CheckAndCreateDB(human)

    local nFreeNum = CommonActBoss_GetFreeNum(human)
    if nFreeNum > 0 then
        return true
    end

    return CommonActBoss_IsPrizeRed(human)
end

function isOpen(human, YYInfo, funcConfig)
    local state, endTime, startTime = AbsActLogic.isStarted(human, funcConfig and funcConfig.funcID or COMMONACTBOSSABSID)
    if not state then
        print("[CommonActBoss_isOpen] 当前活动未开启")
        return 
    end
    -- print("[CommonActBoss_isOpen] 进入判断 endTime = "..endTime.." startTime = "..startTime)
    return true, endTime, startTime
end

function isActive(human, YYInfo, funcConfig)
    return not isOpen(human, YYInfo, funcConfig)
end

function onZero(human, funcID)
    local state, nEndTime, nOpenTime = AbsActLogic.isStarted(human, COMMONACTBOSSABSID)
    if not state then
        return
    end

    CommonActBoss_SetFreeNum(human, COMMONACTFREENUM)
    CommonActBoss_SetFreeTime(human, os.time())
end

function onLogin(human, funcID)
    local state, nEndTime, nOpenTime = AbsActLogic.isStarted(human, COMMONACTBOSSABSID)
    if not state then
        return
    end

    ComActBoss_CheckAndCreateDB(human)

    local nFreeRefreshTime = CommonActBoss_GetFreeTime(human)
    if true ~= Util.isSameDayByTimes(nFreeRefreshTime, os.time()) then
        CommonActBoss_SetFreeNum(human, COMMONACTFREENUM)
        CommonActBoss_SetFreeTime(human, os.time())
    end
end


------------------------------------ 客户端请求处理开始 ---------------------------------
function CommonActBoss_Query(human)
    local state = AbsActLogic.isStarted(human, COMMONACTBOSSABSID)
    if not state then
        print("[CommonActBoss_Query] 当前活动未开启")
        return
    end

    ComActBoss_CheckAndCreateDB(human)

    local tMsgData = Msg.gc.GC_ABS_FESTIVAL_BOSS_QUERY
    tMsgData.nNum = CommonActBoss_GetFreeNum(human)
    tMsgData.nMaxNum = COMMONACTFREENUM
    tMsgData.nHarm = CommonActBoss_GetDamage(human)
    tMsgData.bRedPrize = CommonActBoss_IsPrizeRed(human) == true and 1 or 0

    Msg.send(tMsgData, human.fd)
end

function CommonActBoss_QueryPrize(human)
    local tMsgData = Msg.gc.GC_ABS_FESTIVAL_BOSS_REWARD
    tMsgData.tPrize[0] = 0

    for nID, v in pairs(Config) do
        if v.nType == COMMONACTBOOSPRIZE then
            tMsgData.tPrize[0] =  tMsgData.tPrize[0] + 1
            local tData = tMsgData.tPrize[tMsgData.tPrize[0]]
            tData.nID = nID
            tData.nHarm = v.hurt
            tData.nState = CommonActBoss_GetPrizeStatus(human, nID)

            tData.tPrize[0] = #v.tPrize
            for i, value in ipairs(v.tPrize) do
                Grid.makeItem(tData.tPrize[i], value[1], value[2])
            end
        end
    end

    Msg.send(tMsgData, human.fd)
end

function CommonActBoss_GetPrize(human)
    local tItem = {}

    for nID, v in pairs(Config) do
        if v.nType == COMMONACTBOOSPRIZE then
            local nState = CommonActBoss_GetPrizeStatus(human, nID)
            if CommonDefine.COMMON_PRIZE_STATE_CANGET == nState then
                CommonActBoss_SetPrizeStatus(human, nID, CommonDefine.COMMON_PRIZE_STATE_GET)
                for i, value in ipairs(v.tPrize) do
                    if not tItem[value[1]] then
                        tItem[value[1]] = 0
                    end

                    tItem[value[1]] = tItem[value[1]] + value[2]
                end
            end
        end
    end

    if nil ~= _G.next(tItem) then
        local tGoods = {}
        for nID, nNum in pairs(tItem) do
            table.insert(tGoods, {nID, nNum})
        end

        BagLogic.addItemList(human, tGoods, "CommonActBoss")
        CommonActBoss_Query(human)
        CommonActBoss_QueryPrize(human)
        YunYingLogic.sendBanner(human)
        local config = AbsActExcel.absActivity[COMMONACTBOSSABSID]
        YunYingLogic.sendGroupUpdate(YYInfo[COMMONACTBOSSABSID], human, config.panelID)
    end
end

------------------------------------ 战斗处理开始 ---------------------------------
-- 调用开始战斗
function fight(human, args, combatType)
    if CombatDefine.COMBAT_TYPE34 ~= combatType then
        print("[CommonActBoss_fight] 战斗类型不正确 combatType = "..combatType)
        return
    end

    local nMapID = getMapID(human, nil)

    -- print("[CommonActBoss_fight] 11111 combatType = "..combatType)
    local nNowFreeNum = CommonActBoss_GetFreeNum(human)
    if 0 >= nNowFreeNum then
        return
    end

    nNowFreeNum = nNowFreeNum - 1
    CommonActBoss_SetFreeNum(human, nNowFreeNum)

    CombatLogic.combatBegin(human, nMapID, args, CombatDefine.COMBAT_TYPE34)
    -- print("[CommonActBoss_fight] 2222 combatType = "..combatType)
end

-- 获取人物对战列表
function getCombatObjList(human, side, args)
    if not human then
        print("[getCombatObjList] 获取进攻方,但是不存在对应的human")
        return
    end

    if side ~= CombatDefine.ATTACK_SIDE then
        return
    end

    -- print("[getCombatObjList] 进攻方 获取人物对战列表")
    local objList, helpList, rolebase, formation,jiban, elfList = CombatLogic.getHumanObjList(human, CombatDefine.COMBAT_TYPE34)
    if not objList or nil == _G.next(objList) then
        print("[getCombatObjList] 没有获取到对应的进攻方防守阵容,取默认对战阵容")
        objList, helpList, rolebase, formation,jiban, elfList = CombatLogic.getHumanObjList(human, CombatDefine.COMBAT_TYPE1)
    end

    return objList, helpList, rolebase, formation,jiban, elfList
end

-- 获取机器人对应战斗ID
function getCombatMonsterOutID(human, side, args)
    if side ~= CombatDefine.DEFEND_SIDE then
        return
    end

    if not CommonAct_BOSSID then
        for key, v in pairs(Config) do
            if v.nMonsterOutID and v.nType == COMMONACTFIGHTPRIZE then
                CommonAct_BOSSID = v.nMonsterOutID
                break
            end
        end
    end

    -- print("[getCombatMonsterOutID] 获取到的战斗ID CommonAct_BOSSID = "..CommonAct_BOSSID)
    return CommonAct_BOSSID
end

function getMapID(human, param)
    if not CommonAct_MapID then
        for key, v in pairs(Config) do
            if v.mapID and v.nType == COMMONACTFIGHTPRIZE then
                CommonAct_MapID = v.mapID
                break
            end
        end
    end

    return CommonAct_MapID
end

function onFightEnd(human, result, combatType, defUuid, combatInfo)
    local atkHurt = 0
	for pos = 1, CombatDefine.COMBAT_HERO_CNT do
		local obj = combatInfo.objList and combatInfo.objList[pos]
		if obj then
			atkHurt = atkHurt + obj.result[1]
		end
	end

    -- 魔兽 造成伤害
    for _,pos in ipairs(CombatDefine.SIDE2HELPPOS[CombatDefine.ATTACK_SIDE]) do
		local pet = combatInfo.helpList and combatInfo.helpList[pos]
		if pet and pet.isPet then
            atkHurt = atkHurt + pet.result[1]
		end
	end

    -- 精灵 造成伤害
    for _,pos in ipairs(CombatDefine.SIDE2ELFPOS[CombatDefine.ATTACK_SIDE]) do
		local elf = combatInfo.elfList and combatInfo.elfList[pos]
		if elf then
            atkHurt = atkHurt + elf.result[1]
		end
	end

    local nNowDamage = CommonActBoss_GetDamage(human)
    nNowDamage = nNowDamage + atkHurt

    local bChange = false
    local tPrize = nil
    for nID, v in pairs(Config) do
        if v.nType == COMMONACTBOOSPRIZE then
            if nNowDamage >= v.hurt then
                local nState = CommonActBoss_GetPrizeStatus(human, nID)
                if CommonDefine.COMMON_PRIZE_STATE_NOGET == nState then
                    CommonActBoss_SetPrizeStatus(human, nID, CommonDefine.COMMON_PRIZE_STATE_CANGET)
                    bChange = true
                end
            else
                bChange = true
            end
        else
            tPrize = v.tPrize
        end
    end

    if true == bChange then
        YunYingLogic.sendBanner(human)
        local config = AbsActExcel.absActivity[COMMONACTBOSSABSID]
        YunYingLogic.sendGroupUpdate(YYInfo[COMMONACTBOSSABSID], human, config.panelID)
        
        CommonActBoss_AddDamage(human, atkHurt)
        CommonActBoss_Query(human)
    end

    BagLogic.addItemList(human, tPrize, "CommonActBoss")
end