local Msg = require("core.Msg")
local Util = require("common.Util")
local CombatPosLogic = require("combat.CombatPosLogic")
local HeroGrid = require("hero.HeroGrid")
local BeSkill = require("combat.BeSkill")
local CombatDefine = require("combat.CombatDefine")
local JibanExcel = require("excel.jiban")
local RoleSystemLogic = require("roleSystem.RoleSystemLogic")
local RoleSystemDefine = require("roleSystem.RoleSystemDefine")
local Broadcast = require("broadcast.Broadcast")
local Lang = require("common.Lang")
local HeroLogic = require("hero.HeroLogic")
local GuideLogic = require("guide.GuideLogic")
local CombatExcel = require("excel.combat")
local Json = require("common.Json")
local HeroConfig = require("excel.hero").hero

local AnotherWorldBattleNS
local HeroBook
local ServerCommerceActBattleGroundNS

CMD1 = 1	-- 主线通关
CMD2 = 2	-- 获得英雄
CMD3 = 3	-- 通关通天塔
CMD4 = 4	-- 等级
FATHER2ID = nil
HERO2ID = nil
CMD2POS = nil
JIBATEMP = nil

local function getDB(human)
	human.db.jiban = human.db.jiban or {[1] = 1}
	return human.db.jiban
end

-- 获取全部设置的羁绊位置英雄ID
local function getDB_AllJibanHeroID(human)
	human.db.jibanheroid = human.db.jibanheroid or {}
	return human.db.jibanheroid
end

-- 获取某个羁绊位置英雄ID
local function getDB_JibanHeroIDByIndex(human, nIndex)
	local jibanheroid = getDB_AllJibanHeroID(human)
	return jibanheroid[nIndex] and jibanheroid[nIndex] or -1
end

-- 设置羁绊位置英雄ID
local function setDB_JibanHeroID(human, nIndex, nHeroID)
	local jibanheroid = getDB_AllJibanHeroID(human)
	jibanheroid[nIndex] = nHeroID
end

-- -- 通过阵容类型获取羁绊英雄数据
-- local function getJibanHeroData(human, combatType)
-- 	human.db.jibanHeroData = human.db.jibanHeroData or {}
-- 	human.db.jibanHeroData[combatType] = human.db.jibanHeroData[combatType] or {}
-- 	return human.db.jibanHeroData[combatType]
-- end

-- -- 获取某个阵容羁绊英雄Id
-- local function getJibanHeroId(human, combatType, heroIdx)
-- 	local singleJibanHeroData = getJibanHeroData(human, combatType)
-- 	return singleJibanHeroData[heroIdx] and singleJibanHeroData[heroIdx] or -1
-- end

-- -- 设置羁绊位置英雄ID
-- local function setJiBanHero(human, combatType, heroIdx, heroId)
-- 	local singleJibanHeroData = getJibanHeroData(human, combatType)
-- 	singleJibanHeroData[heroIdx] = heroId
-- end


local function fontJibanInfo(net,id)
	local conf = JibanExcel.jiban[id]
	net.id = id
	net.name = conf.name
	net.desc = conf.desc
	net.quality = conf.quality
	local len = 0
	for _,v in ipairs(conf.hero) do
		len = len + 1
		HeroGrid.makeHeroSimpleByID(net.heroList[len], v)
	end
	net.heroList[0] = len
end

function initAfterHot()
	-- 同一father下的羁绊互斥
	--[[
		FATHER2ID = {
			[jibanCfg.father] = {
				jibanCfg.id,
			} -- array
		}
	]]
	FATHER2ID = {} 
	HERO2ID = {}
	--[[
		temp = {
			{jibanCfg.quality,jibanCfg.id},
		} -- array
	]]
	JIBATEMP = {}


	for k,v in ipairs(JibanExcel.jiban) do
		JIBATEMP[#JIBATEMP + 1] = {v.quality,k}
		for _,v1 in ipairs(v.hero) do
			HERO2ID[v1] = HERO2ID[v1] or {}
			HERO2ID[v1][#HERO2ID[v1] + 1] = k
		end
	end

	table.sort(JIBATEMP,function(a,b)
		if a[1] > b[1] then
			return true
		elseif a[1] == b[1] and a[2] < b[2] then
			return true
		else
			return false
		end
	end)

	local msgRet = Msg.gc.GC_JIBAN_PREVIEW
	local len = 0
	for k,v in ipairs(JIBATEMP) do
		local conf = JibanExcel.jiban[v[2]]
		FATHER2ID[conf.father] = FATHER2ID[conf.father] or {}
		FATHER2ID[conf.father][#FATHER2ID[conf.father] + 1] = v[2]
		-- len = len + 1
		-- local net = msgRet.list[len]
		-- fontJibanInfo(net,k)
	end
	-- msgRet.list[0] = len

	CMD2POS = {}
	for k,v in ipairs(JibanExcel.pos) do
		if v.cmd > 0 then
			CMD2POS[v.cmd] = k
		end
	end
end

function query(human,combatType,heroID, extraArgs)
	local flag = RoleSystemLogic.isOpen(human,RoleSystemDefine.ROLE_SYS_ID_207)
	if flag ~= true then
		return
	end

	local msgRet = Msg.gc.GC_JIBAN_QUERY
	local len = 0
	if HERO2ID[heroID] then
		for k,v in ipairs(HERO2ID[heroID]) do
			len = len + 1
			local net = msgRet.jibanList[len]
			fontJibanInfo(net,v)
		end
	end
	msgRet.jibanList[0] = len
	len = 0
	local db = getDB(human)
	local combatHeroDB
	if combatType == CombatDefine.COMBAT_TYPE36 and extraArgs then
		AnotherWorldBattleNS = AnotherWorldBattleNS or require("anotherWorldBattle.AnotherWorldBattleNS")
		local v1,v2, v3
		v1, v2, v3, combatHeroDB = AnotherWorldBattleNS.getCombatHeros(human, combatType, extraArgs)
		combatHeroDB = combatHeroDB or {}
	else
		combatHeroDB = CombatPosLogic.getCombatHeroDB(human,combatType)
	end

	local jibanDB = combatHeroDB.jiban or {}
	for k,v in ipairs(JibanExcel.pos) do
		len = len + 1
		local net = msgRet.posList[len]
		net.id = k
		net.tip = v.tip
		net.isOpen = db[k] or 0
        net.sort = v.sort
		local heroGrid
		-- if jibanDB[k] and jibanDB[k] ~= "" and jibanDB[k] ~= "0" then
		-- 	heroGrid = HeroLogic.getHeroGridByUuid(human, jibanDB[k])
		-- end

		-- if not heroGrid then
		-- 	local nHeroID = getDB_JibanHeroIDByIndex(human, k)
		-- 	if -1 ~= nHeroID then
		-- 		local heroGridList = HeroLogic.getHeroListById(human, nHeroID)
		-- 		if nil ~= _G.next(heroGridList) then
		-- 			local nHeroIndex = heroGridList[1]
		-- 			heroGrid = HeroLogic.getHeroGrid(human, nHeroID, nHeroIndex)
		-- 		end
		-- 	end
		-- end

		if jibanDB[k] and jibanDB[k] ~= "" and jibanDB[k] ~= "0" and jibanDB[k] ~= 0 then
			-- len = len + 1
			-- local net = msgRet.posList[len]
			-- net.id = k
			-- net.tip = v.tip
			-- net.isOpen = db[k] or 0
			-- net.sort = v.sort
			-- local heroGrid

			-- 之前阵容数据的羁绊数据里保存的是英雄的uuid, 最新改成保存英雄id
			local heroId = tonumber(jibanDB[k])
			if heroId then
				heroGrid = {id = heroId }
			else
				-- heroGrid = HeroLogic.getHeroGridByUuid(human, jibanDB[k])
				if combatType == CombatDefine.COMBAT_TYPE37 then
					ServerCommerceActBattleGroundNS = ServerCommerceActBattleGroundNS or require("serverCommerce.ServerCommerceActBattleGroundNS")
					heroGrid = ServerCommerceActBattleGroundNS.getHeroGridByUuid(human, jibanDB[k])
				else
					heroGrid = HeroLogic.getHeroGridByUuid(human, jibanDB[k])
				end
			end
		end
		local index = heroGrid and heroGrid.bagIndex or 0
		HeroGrid.makeHeroSimple(net.hero, heroGrid, index)
	end
	msgRet.posList[0] = len
	Msg.send(msgRet,human.fd)
end

--
function sendQuery(human,combatType, teamType)
	local msgRet = Msg.gc.GC_JIBAN_QUERY_ALL
	local len = 0
	local db = getDB(human)
    msgRet.type = teamType
	local combatHeroDB = CombatPosLogic.getCombatHeroDB(human,combatType)
	local jibanDB = combatHeroDB.jiban or {}
	for k,v in ipairs(JibanExcel.pos) do
		len = len + 1
		local net = msgRet.posList[len]
		net.id = k
		net.tip = v.tip
		net.isOpen = db[k] or 0
        net.sort = v.sort
		local heroGrid
		-- if jibanDB[k] and jibanDB[k] ~= "" and jibanDB[k] ~= "0" then
		-- 	heroGrid = HeroLogic.getHeroGridByUuid(human, jibanDB[k])
		-- end
		
		-- if not heroGrid then
		-- 	local nHeroID = getDB_JibanHeroIDByIndex(human, k)
		-- 	if -1 ~= nHeroID then
		-- 		local heroGridList = HeroLogic.getHeroListById(human, nHeroID)
		-- 		if nil ~= _G.next(heroGridList) then
		-- 			local nHeroIndex = heroGridList[1]
		-- 			heroGrid = HeroLogic.getHeroGrid(human, nHeroID, nHeroIndex)
		-- 		end
		-- 	end
		-- end


		if jibanDB[k] and jibanDB[k] ~= "" and jibanDB[k] ~= "0" and jibanDB[k] ~= 0 then
			-- 之前阵容数据的羁绊数据里保存的是英雄的uuid, 最新改成保存英雄id
			local heroId = tonumber(jibanDB[k])
			if heroId then
				heroGrid = {id = heroId }
			else
				-- heroGrid = HeroLogic.getHeroGridByUuid(human, jibanDB[k])
				if combatType == CombatDefine.COMBAT_TYPE37 then
					ServerCommerceActBattleGroundNS = ServerCommerceActBattleGroundNS or require("serverCommerce.ServerCommerceActBattleGroundNS")
					heroGrid = ServerCommerceActBattleGroundNS.getHeroGridByUuid(human, jibanDB[k])
				else
					heroGrid = HeroLogic.getHeroGridByUuid(human, jibanDB[k])
				end
			end
		end
		local index = heroGrid and heroGrid.bagIndex or 0
		HeroGrid.makeHeroSimple(net.hero, heroGrid, index)

	end
	msgRet.posList[0] = len
	Msg.send(msgRet,human.fd)
end

function preview(human)
	local msgRet = Msg.gc.GC_JIBAN_PREVIEW
	msgRet.list[0] = 0
	msgRet.isend = 0
	local len = 0
	for k,v in ipairs(JIBATEMP) do
		len = len + 1
		local net = msgRet.list[len]
		fontJibanInfo(net,k)
		if len >=20 then
			msgRet.list[0] = len
            Msg.send(msgRet,human.fd)
            len = 0
		end
    end
	msgRet.list[0] = len
    msgRet.isend = 1
    Msg.send(msgRet,human.fd)
end

function getPosList(human)
	return getDB(human)
end

function onCallback(human,cmd,arg)
	local pos = CMD2POS[cmd]
	local db = getDB(human)
	if db[pos] then
		return
	end
	local conf = JibanExcel.pos[pos]
	if arg >= conf.arg then
		db[pos] = 1
	end
end

function getJiban(objList,jibanList)
	local objHero = {}
	local jibanHero = {}
	for i = 1,CombatDefine.COMBAT_HERO_CNT - 1 do
		local obj = objList[i]
        -- 不是玩家不计算羁绊
		if obj and obj.type == CombatDefine.COMBAT_OBJ_TYPE1 then
			objHero[obj.id] = objHero[obj.id] or 0
			objHero[obj.id] = objHero[obj.id] + 1
		end
	end

	if jibanList then
		-- for k,v in pairs(jibanList) do
		-- 	if v > 0 then
		-- 		objHero[v] = objHero[v] or 0
		-- 		objHero[v] = objHero[v] + 1
		-- 	end
		-- end

		for _, heroInfo in pairs(jibanList) do
			local heroID = heroInfo.heroID
			if heroID > 0 then
				jibanHero[heroID] = heroInfo
			end
		end
	end

	-- local jiban = {}
	-- for _,v in pairs(FATHER2ID) do
	-- 	for _,v1 in ipairs(v) do
	-- 		local conf = JibanExcel.jiban[v1]
	-- 		local canUse = true
	-- 		for _,v2 in ipairs(conf.hero) do
	-- 			if not objHero[v2] then
	-- 				canUse = false
	-- 				break
	-- 			end
	-- 		end
	-- 		if canUse then
	-- 			jiban[v1] = 1
	-- 			break
	-- 		end
	-- 	end
	-- end
	-- return jiban

	local jiban = {}
	for _,v in pairs(FATHER2ID) do
		for _,v1 in ipairs(v) do
			local conf = JibanExcel.jiban[v1]
			local canUse = true
			local jbHeroList = {}
			for _,v2 in ipairs(conf.hero) do
				if not objHero[v2] and not jibanHero[v2] then
					canUse = false
					break
				end
				if jibanHero[v2] then
					jbHeroList[v2] = 1
				end
			end
			if canUse then
				jiban[v1] = {}
				for jbHeroID in pairs(jbHeroList) do
					jiban[v1][jbHeroID] = jibanHero[jbHeroID]
				end
			end
		end
	end
	return jiban
end

function getJibanHero(human,combatHeroDB)
	local jibanHero = {}

	-- local jibanheroid = getDB_AllJibanHeroID(human)
	if combatHeroDB.jiban then
		-- for k, uuid in pairs(combatHeroDB.jiban) do
		-- 	if uuid ~= "0" and uuid ~= "" then
		-- 		local heroGrid = HeroLogic.getHeroGridByUuid(human, uuid)
		-- 		if heroGrid then
		-- 			jibanHero[k] =  heroGrid.id
		-- 		else
		-- 			local nHeroID = getDB_JibanHeroIDByIndex(human, k)
		-- 			if -1 ~= nHeroID then
		-- 				jibanHero[k] = nHeroID
		-- 			end
		-- 		end
		-- 	end
		-- end

		for k, uuid in pairs(combatHeroDB.jiban) do
			if uuid ~= "0" and uuid ~= "" and uuid ~= 0 then
				local finalId = tonumber(uuid)
				if finalId then
					local heroCfg = HeroConfig[finalId]
					jibanHero[k] = {
						heroID = finalId,
						icon = heroCfg and heroCfg.head or 0,
						star = 1,
						camp = heroCfg and heroCfg.camp or 1,
						grade = heroCfg and heroCfg.grade or 1,
					}
				else
					local heroGrid = HeroLogic.getHeroGridByUuid(human, uuid)
					if heroGrid then
						local heroCfg = HeroConfig[heroGrid.id]
						jibanHero[k] =  {
							heroID = heroGrid.id,
							icon = heroGrid.head or (heroCfg and heroCfg.head or 0),
							star = heroGrid.star or 1,
							camp = heroCfg and heroCfg.camp or 1,
							grade = heroGrid.grade or (heroCfg and heroCfg.grade or 1),
						}
					end
				end
			end

			-- 	if heroGrid then
			-- 		local heroCfg = HeroConfig[heroGrid.id]
			-- 		jibanHero[k] =  {
			-- 			heroID = heroGrid.id,
			-- 			icon = heroGrid.head or (heroCfg and heroCfg.head or 0),
			-- 			star = heroGrid.star or 1,
			-- 			camp = heroCfg and heroCfg.camp or 1,
			-- 			grade = heroGrid.grade or (heroCfg and heroCfg.grade or 1),
			-- 		}
			-- 	else
			-- 		local nHeroID = getDB_JibanHeroIDByIndex(human, k)
			-- 		if -1 ~= nHeroID then
			-- 			local heroCfg = HeroConfig[nHeroID]
			-- 			jibanHero[k] = {
			-- 				heroID = nHeroID,
			-- 				icon = heroCfg and heroCfg.head or 0,
			-- 				star = 1,
			-- 				camp = heroCfg and heroCfg.camp or 1,
			-- 				grade = heroCfg.grade or 1,
			-- 			}
			-- 		end
			-- 	end
		end
	end
	return jibanHero
end

function getDesc(jiban)
    -- local desc = {}
    -- local len = 0
	-- for k,v in pairs(jiban) do
	-- 	local conf = JibanExcel.jiban[k]
    --     if len > 0 then
    --        len = len + 1
    --        desc[len] = "|"
    --     end
    --     len = len + 1
    --     desc[len] = conf.name
    --     len = len + 1
    --     desc[len] = ","
    --     len = len + 1
    --     desc[len] = conf.desc
    --     len = len + 1
    --     desc[len] = ","
    --     len = len + 1
    --     desc[len] = conf.quality
	-- end

    -- local descStr = table.concat(desc)
	-- return descStr

	local len = 0
	local JiBanInfo = {}

	for k, jbHeroInfo in pairs(jiban) do
		local conf = JibanExcel.jiban[k]
		len = len + 1
		JiBanInfo[len] = {
			name = conf.name,
			desc = conf.desc,
			quality = conf.quality,
			hero = conf.hero,
		}

		if next(jbHeroInfo) then
			JiBanInfo[len].jbHeroInfo = {}
			local info = JiBanInfo[len].jbHeroInfo

			for jbHeroId, data in pairs(jbHeroInfo) do
				info[jbHeroId] = data
			end
		end
	end

	return Json.Encode(JiBanInfo)
end


function setBeSkill(objList,jiban)
	if not jiban then return end
	local skillList = {}
	for k in pairs(jiban) do
		local conf = JibanExcel.jiban[k]
		local skillID = conf.skill
		if skillID > 0 then
			for i = 1,CombatDefine.COMBAT_HERO_CNT - 1 do
				local obj = objList[i]
				if obj then
					BeSkill.setBeSkillID(obj,skillID)
				end
			end
		end
	end
end

-- 更新羁绊
function update(human,combatType,jibanListStr, heroIdStr, extraArgs)
    local conf = CombatExcel.combat[combatType]
    if not conf then return end

	local posList = getPosList(human)
	local jibanList = Util.split(jibanListStr,",")
	local jibanHeroIdArr = Util.split(heroIdStr,",", true)
	local combatHeroDB

	if combatType == CombatDefine.COMBAT_TYPE36 and extraArgs then
		AnotherWorldBattleNS = AnotherWorldBattleNS or require("anotherWorldBattle.AnotherWorldBattleNS")
		local v1,v2, v3
		v1, v2, v3, combatHeroDB = AnotherWorldBattleNS.getCombatHeros(human, combatType, extraArgs)
		if not combatHeroDB then
			return
		end
	else
		combatHeroDB = CombatPosLogic.getCombatHeroDB(human,combatType)
	end

	HeroBook = HeroBook or require("hero.HeroBook")

	for k,v in ipairs(jibanList) do
		local uuid = v or "0"
		local heroId = jibanHeroIdArr[k] or 0
		if uuid ~= "" and uuid ~= "0" and heroId ~= 0 then
            --检测有没有再阵容上
            -- 允许共鸣英雄同时上阵（包含援军/助战位置），因此不再阻止uuid出现在combatHeroDB.list中的情况
            -- 原逻辑：
            -- for _, combatUuid in ipairs(combatHeroDB.list) do
            --    if uuid == combatUuid then return end
            -- end

			if not posList[k] then return end
			-- local heroGrid = HeroLogic.getHeroGridByUuid(human, uuid)
            -- if not heroGrid then return end

            -- setDB_JibanHeroID(human, k,	heroGrid.id)

			local res = HeroBook.isGetHero(human, heroId)
			if not res or res == HeroBook.LIEZHUAN_REWARD_NO then
				return
			end

			-- setDB_JibanHeroID(human, k,	heroId)
		end
	end

	combatHeroDB.jiban = jibanHeroIdArr

	if combatType == CombatDefine.COMBAT_TYPE36 and extraArgs then
		return query(human, combatType, 0, extraArgs)
	end

    GuideLogic.setDoSpecialGuide(human, GuideLogic.SKIPTYPE_JUMP_JIBAN_GROUP)

    sendQuery(human,combatType, conf.teamType)
end