--主线任务流
--db
--[=[
    human.db.mainTaskData = {
    taskData = {
        [taskId] = {
            progress = ni, --当前进度
            isGetReward = nil,     --是否已领奖, isGetReward为真标识已领奖
        },
    },

    nowTaskId = nil, --当前任务
    }
]=]--

local Msg = require("core.Msg")
local Grid = require("bag.Grid")
local BagLogic = require("bag.BagLogic")
local Lang = require("common.Lang")
local Broadcast = require("broadcast.Broadcast")
local Config = require("excel.mainTask").mainTask
local TriggerLogic = require("trigger.TriggerLogic")
local TriggerDefine = require("trigger.TriggerDefine")
local ObjHuman = require("core.ObjHuman")
local EliteDefine = require("battle.EliteDefine")

--日志标识
local MAINTASKLOGTAG = "mainTask"


local function initTaskData(human)
    human.db.mainTaskData = {nowTaskId = 1, taskData = {}}
end

local function getTaskData(human)
    return human.db.mainTaskData
end

local function updateTaskProgress(human, taskId, val, isAdd)
    local mainTaskData = getTaskData(human)
    local taskData = mainTaskData.taskData
    taskData[taskId] = taskData[taskId] or {}

    if isAdd then
        taskData[taskId].progress = (taskData[taskId].progress or 0) + val
    else
        taskData[taskId].progress = val
    end
end

local function updateTaskStatus(human, taskId, newStatus)
    local mainTaskData = getTaskData(human)
    local taskData = mainTaskData.taskData
    taskData[taskId].isGetReward = newStatus
end

local function updateNowTaskId(human, newTaskId)
    local mainTaskData = getTaskData(human)
    mainTaskData.nowTaskId = newTaskId
end



--获取某类任务在该活动之前就达成的进度
local function getTaskOldProgress(human, eventType)
    local progress = 0

    if eventType == TriggerDefine.HUANJINGTOWER_PASS then
        local HuanJingTowerLogic = require("huanjingTower.HuanjingTowerLogic")
        progress = HuanJingTowerLogic.getTowerLevel(human)

    elseif eventType == TriggerDefine.LIANYU_PASS then
        local LianyuLogic = require("lianyu.LianyuLogic")
        progress = LianyuLogic.getMaxLv(human)

    elseif eventType == TriggerDefine.REALM_UPGRADE then
        local RoleRealmLogic = require("roleSystem.RoleRealmLogic")
        progress = RoleRealmLogic.GetNowRealmLv(human)

    elseif eventType == TriggerDefine.BATTLE_NORMAL_MODE_PASS then
        local BattleLogic = require("battle.BattleLogic")
        progress = BattleLogic.GetLevelByType(human, EliteDefine.COPY_ELITE_NORMAL)
    end

    return progress
end


-- 统计部分任务老的进度
local function calcTaskOldProgress(human)
    local mainTaskData = getTaskData(human)
    if not mainTaskData then
        initTaskData(human)

        local type2Val = {}
        for taskId, taskCfg in ipairs(Config)  do
            if taskCfg.isCalcOldVal > 0 then         --一些任务需要统计老的进度数据
                local eventType = taskCfg.eventType
                if not type2Val[eventType] then
                    type2Val[eventType] = getTaskOldProgress(human, eventType)
                end

                if type2Val[eventType] and type2Val[eventType] > 0 then
                    updateTaskProgress(human, taskId, type2Val[eventType], false)
                end
            end
        end
    end
end

-- 异常处理函数
-- 主线闯关, 恶魔之塔, 绝望深渊相关任务有时候出现统计不准确的情况, 暂未找到bug, 先做个异常处理
local function abnormalDeclFunc(human)
    local mainTaskData = getTaskData(human)
    if not mainTaskData then
        return
    end

    local taskData = mainTaskData.taskData
    if not next(taskData) then
        return
    end

    local nowTaskId = mainTaskData.nowTaskId
    local maxTaskId = #Config
    if nowTaskId >= maxTaskId and (taskData[nowTaskId] and taskData[nowTaskId].progress >= Config[nowTaskId].condProgress) then
        return
    end

    local type2Val = {}
    for taskId, singleTaskData in pairs(taskData) do
        local taskCfg = Config[taskId]

        if taskCfg and singleTaskData.progress < taskCfg.condProgress and taskCfg.isCalcOldVal > 0 then

            local eventType = taskCfg.eventType
            if not type2Val[eventType] then
                type2Val[eventType] = getTaskOldProgress(human, eventType)
            end

            if type2Val[eventType] > 0 then
                updateTaskProgress(human, taskId, type2Val[eventType], false)
            end
        end
    end
end



--订阅事件
local function subscribeEvents(human)
    local mainTaskData = getTaskData(human)
    local taskData = mainTaskData.taskData
    local nowTaskId = mainTaskData.nowTaskId
    local maxTaskId = #Config
    local maxTaskCfg = Config[maxTaskId]
    if nowTaskId == maxTaskId and taskData[maxTaskId] and taskData[maxTaskId].progress >= maxTaskCfg.condProgress then
        return
    end


    local registerTypeList = {}

    for taskId, taskCfg in ipairs(Config)  do
        if not registerTypeList[taskCfg.eventType] and (not taskData[taskId] or taskData[taskId].progress < taskCfg.condProgress) then
            TriggerLogic.SubscribeEvent(taskCfg.eventType, human.db._id, EventCBFunc)
            registerTypeList[ taskCfg.eventType] = 1
        end
    end
end


function onLogin(human)
    calcTaskOldProgress(human)

    abnormalDeclFunc(human)

    subscribeEvents(human)
end


--事件处理函数
function EventCBFunc(eventType, uuid, nValue1, nValue2)
    local human = ObjHuman.onlineUuid[uuid]
    if not human then
        return
    end

    local isNowTask = false
    local mainTaskData = getTaskData(human)
    local taskData = mainTaskData.taskData
    local nowTaskId = mainTaskData.nowTaskId

    for taskId, taskCfg in ipairs(Config) do
        if taskCfg.eventType == eventType and (not taskData[taskId] or taskData[taskId].progress < taskCfg.condProgress) then

            if taskCfg.extraCond <= 0 or (nValue2 and nValue2 >= taskCfg.extraCond) then

                updateTaskProgress(human, taskId, nValue1, true)

                if taskId == nowTaskId then
                    isNowTask = true
                end
            end
        end
    end

    --推数据给客户端更新
    if isNowTask then
        TaskQuery(human)
    end
end


--查询
function TaskQuery(human)
    local mainTaskData = getTaskData(human)
    local taskData = mainTaskData.taskData
    local nowTaskId = mainTaskData.nowTaskId
    local maxTaskId = #Config

    if nowTaskId > maxTaskId then
        nowTaskId =  maxTaskId
    end

    local nowTaskCfg = Config[nowTaskId]
    local msgRet = Msg.gc.GC_MAINTASK_QUERY
    msgRet.nowTaskId = nowTaskId
    msgRet.nowProgess = taskData[nowTaskId] and taskData[nowTaskId].progress or 0
    msgRet.condProgess = nowTaskCfg.condProgress
    msgRet.taskDesc = nowTaskCfg.taskDesc
    msgRet.panelID = nowTaskCfg.panelID
    Grid.makeItem(msgRet.taskAward, nowTaskCfg.reward[1], nowTaskCfg.reward[2])
    msgRet.isNoTask = 0

    if nowTaskId == maxTaskId and taskData[nowTaskId] and taskData[nowTaskId].isGetReward then
        msgRet.isNoTask = 1
    end

    Msg.send(msgRet, human.fd)
end


--领奖
function GetReward(human, taskId)
    local mainTaskData = getTaskData(human)
    local taskData = mainTaskData.taskData
    local nowTaskId = mainTaskData.nowTaskId

    local nowTaskCfg = Config[nowTaskId]
    if not taskData[nowTaskId] or taskData[nowTaskId].progress < nowTaskCfg.condProgress then
        return Broadcast.sendErr(human, Lang.UNION_TASK_NOT_COMPLETE)
    end

    if taskData[nowTaskId] and taskData[nowTaskId].isGetReward then
        return Broadcast.sendErr(human, Lang.FRIEND_HEART_GET_HAD)
    end

    updateTaskStatus(human, nowTaskId, true)


    local rewardCfg = nowTaskCfg.reward
    BagLogic.addItemList(human, { {rewardCfg[1], rewardCfg[2]} }, MAINTASKLOGTAG)


    nowTaskId = nowTaskId + 1
    --if Config[nowTaskId] then
        updateNowTaskId(human, nowTaskId)
    --end
    TaskQuery(human)
end

--GM 更新任务进度
function GM_UpdateTaskProgress(human, taskId, progress)
    if not taskId or not progress then
        return
    end
    updateTaskProgress(human, taskId, progress)
    TaskQuery(human)
end

--GM 更新当前任务
function GM_UpdateNowTask(human, newTaskId)
    if not Config[newTaskId] then
        return
    end
    updateNowTaskId(human, newTaskId)
    TaskQuery(human)
end

--GM 清除任务
function GM_ClearTask(human, taskId)
    if not taskId then
        return
    end

    local mainTaskData = getTaskData(human)
    mainTaskData[taskId] = nil
    TaskQuery(human)
end

function GM_ClearAllTaskData(human)
    human.db.mainTaskData = nil

    calcTaskOldProgress(human)

    TaskQuery(human)
end

