local schema = require "model.schema"
local logger = require "logger"
local asset = require "model.asset"
local stringify = require "stringify"
local common_fun = require "model.common_fun"
local hero
-- local skill_card
local powerfunc

local math_floor = math.floor

local module_name = "embattle"
local _M = schema.new(module_name, {
    adventure = {
        list = {
            -- [pos] = {
            --     sid = sid,
            --     pos = pos,
            -- }
        },
        card_list = {}
    }
})



local REQUEST = {}
local CMD = {}
local MODULE = {}
local THIS = {}

local function func_ret(fname, character, args)
    local f = THIS[fname]
    if not f then
        logger.error("func_ret not fname:%s !!!", fname)
        return {errno = STD_ERR.COMMON_SYS_ERR}
    end
    local errno, ret = f(character, args)
    if errno ~= 0 then
        return {errno = errno}
    end
    ret = ret or {}
    ret.errno = 0
    return ret
end

function MODULE.list_request_interests() return REQUEST end
function MODULE.list_command_interests() return CMD end

-- TODO: 解析/升级模块数据 在这里把数据初始化好
function MODULE.parse(character)
    local d = _M.load(character)
    d.adventure = d.adventure or {}
    d.adventure.list = d.adventure.list or {}
    d.adventure.card_list = d.adventure.card_list or {}
end

-- TODO: 侦听事件
function MODULE.monitor(character)

end

-- 
function MODULE.launch(character)
    local d = _M.assert_get(character)
    hero = hero or require "model.hero"
    -- skill_card = skill_card or require "model.skill_card"
end

-- 
function MODULE.ready(character)
    local d = _M.assert_get(character)
    logger.test("%s:ready, %s", module_name, stringify(d or {}))
end

-- TODO: 玩家下线时的处理
function MODULE.saybye(character)
end

function MODULE.battle_power(character)
    local all = 0
    local d = _M.assert_get(character) or {}
    powerfunc = powerfunc or require "model.powerfunc"
    for k, v in pairs(d.adventure.list) do
        local hero_data = hero.hero_get(character, v.sid)
        local power = powerfunc.build_role(character, hero_data)
        if power and power > 0 then
            all = all + power
        end
    end
    -- for k, v in pairs(d.adventure.card_list) do
    --     local card_data = skill_card.skill_card_get(character, v.sid)
    --     local power = powerfunc.build_card(character, card_data)
    --     if power and power > 0 then
    --         all = all + power
    --     end
    -- end
    return all
end

function MODULE.first_battle(character)
    local d = _M.assert_get(character) or {}
    local hero_list = hero.hero_get_list(character)
    local Data_conf = asset.DataConfig_proto[4]
    for pos, v in ipairs(Data_conf.data5 or {}) do
        if v > 0 then
            for _, info in pairs(hero_list) do
                if info.id == v then
                    d.adventure.list[pos] = {
                        sid = info.sid,
                        pos = pos
                    }
                end
            end
        end
    end
    logger.trace("adventure"..stringify(d.adventure.list))

    _M.persist(character)
end

function MODULE.max_power_hero(character)
    local d = _M.assert_get(character) or {}
    powerfunc = powerfunc or require "model.powerfunc"
    local max_power = 0
    local hero_info
    for k, v in pairs(d.adventure.list) do
        local hero_data = hero.hero_get(character, v.sid)
        local power = powerfunc.build_role(character, hero_data)
        if power and power > max_power then
            max_power = power
            hero_info = hero_data
        end 
    end
    return max_power, hero_info
end

-- 获得阵上的英雄
function MODULE.get_embattle_hero_list(character)
    local d = _M.assert_get(character)
    local list = {}
    for _, v in pairs(d.adventure.list) do
        list[v.sid] = v.sid
    end
    return list
end

local function battle_sort(list, num)
    local ret = {}
    if num <= 0 then
        return ret
    end
    for i = 1, num do
        if list[i] then
            table.insert(ret, list[i])
        else
            table.insert(ret, {pos = 0, sid = ""})
        end
    end
    return ret
end

function THIS.embattle_battle(character, args)
    local d = _M.assert_get(character)
    local data_conf_list = assert(asset.DataConfig_proto, "DataConfig_proto")

    local pos = args.pos
    local sid = args.sid
    if sid == "" then
        sid = nil
    end
    if not pos then
        return STD_ERR.COMMON_PARM_ERR -- 参数异常
    end

    local data_conf
    local list
    local check_func
    if args.skill then
        data_conf = data_conf_list[4]
        list = d.adventure.card_list
        -- check_func = function()
        --     return skill_card.skill_card_check(character, sid)
        -- end
    else
        data_conf = data_conf_list[3]
        list = d.adventure.list
        check_func = function()
            return hero.hero_check(character, sid)
        end
    end

    local max_pos = data_conf.data1

    if pos > max_pos then
        return STD_ERR.COMMON_PARM_ERR -- 参数异常
    end

    if not sid then
        list[pos] = nil
        _M.persist(character)
        return 0, {
            list = battle_sort(d.adventure.list, data_conf_list[3].data1),
            card_list = battle_sort(d.adventure.card_list, data_conf_list[4].data1)
        }
    end

    -- 检查是否存在
    if not check_func or not check_func() then
        return STD_ERR.EMBATTLE_NOT_TARGET -- 未找到目标
    end

    local old_pos = -1
    for _, v in pairs(list) do
        if v.sid == sid then
            old_pos = v.pos
            break
        end
    end

    if old_pos == pos then
        return STD_ERR.COMMON_PARM_ERR -- 参数异常
    end

    -- 有旧位置,先处理旧位置逻辑
    if old_pos > 0 then
        --相当于换位置
        if list[pos] then
            list[old_pos] = list[pos]
        else
            list[old_pos] = nil
        end
    else
        if not args.skill then
            local temp = {}
            for _, v in pairs(d.adventure.list) do
                -- 不用检查相同位置上的同名卡
                if v.pos~= pos then
                    local hero_info = hero.hero_get(character, v.sid)
                    if hero_info then
                        temp[common_fun.get_hero_type(hero_info.id)] = 1
                    end
                end
            end
            local hero_info = hero.hero_get(character, sid)
            if temp[common_fun.get_hero_type(hero_info.id)] then
                return STD_ERR.EMBATTLE_SAME_NAME_HERO -- 不满足上阵需求
            end 
            local hero_conf = asset.RoleConfig_proto[hero_info.id]
            if not hero_conf then
                return STD_ERR.COMMON_CONF_ERR
            end
            if hero_conf.profession ~= pos then
                return STD_ERR.EMBATTLE_SAME_NAME_HERO
            end
        end
    end

    list[pos] = {
        sid = sid,
        pos = pos,
    }
    _M.persist(character)
    return 0, {
        list = battle_sort(d.adventure.list, data_conf_list[3].data1),
        card_list = battle_sort(d.adventure.card_list, data_conf_list[4].data1)
    }
end


function THIS.embattle_get_data(character, args)
    local data_conf_list = assert(asset.DataConfig_proto, "DataConfig_proto")
    local d = _M.assert_get(character)
    return 0, {
        list = battle_sort(d.adventure.list, data_conf_list[3].data1),
        card_list = battle_sort(d.adventure.card_list, data_conf_list[4].data1)
    }
end

-- 上阵
function REQUEST.embattle_battle(character, args)
    return func_ret("embattle_battle", character, args)
end

-- 上阵数据
function REQUEST.embattle_get_data(character, args)
    return func_ret("embattle_get_data", character, args)
end


return MODULE