-------------------------------------------------------
-- 英雄分解
-------------------------------------------------------

local HeroExcel = require("excel.hero")
local UpNeedExcel = require("excel.upNeed")
local EquipExcel = require("excel.equip")
local Lang = require("common.Lang")
local Util = require("common.Util")
local Msg = require("core.Msg")
local HeroLogic = require("hero.HeroLogic")
local BagLogic = require("bag.BagLogic")
local ItemDefine = require("bag.ItemDefine")
local Grid = require("bag.Grid")
local HeroGrid = require("hero.HeroGrid")
local HeroBook = require("hero.HeroBook")
local ChengjiuLogic = require("chengjiu.ChengjiuLogic")
local Broadcast = require("broadcast.Broadcast")
local HechengLogic = require("hecheng.HechengLogic")
local FuwenLogic = require("fuwen.FuwenLogic")
local SuipianLogic = require("bag.SuipianLogic")
local CombatPosLogic = require("combat.CombatPosLogic")
local HeroDefine = require("hero.HeroDefine")
local EquipLogic = require("equip.EquipLogic")
local BingshuLogic = require("fuwen.BingshuLogic")
local FuwenExcel = require("excel.fuwen")
local WinnerRelicLogic = require("winnerRelic.WinnerRelicLogic")

FENJIE_QUERY = 1		--分解查询
FENJIE_DO = 2			--祭坛分解
FENJIE_DO_HECHENG = 3	--合成导致的分解
FENJIE_DO_JUEXING = 4	--觉醒导致的分解
FENJIE_DO_SHELTER = 5   --庇护所导致的分解
FENJIE_DO_TENSTAR  = 7  --十星置换导致分解
FENJIE_DO_MERGE  = 7  --融合导致分解

-------------------------------------------------------------------------------------

local FENJIE_OUTITEMS = {}
local FENJIE_FUWEN_LIST = {}
local FENJIE_EQUIP_LIST = {}
local SUIJI_CNT = 0

-- 重置产出信息
local function cleanOutItems()
	for k in pairs(FENJIE_OUTITEMS) do
		FENJIE_OUTITEMS[k] = nil
	end
	for k in pairs(FENJIE_FUWEN_LIST) do
		FENJIE_FUWEN_LIST[k] = nil
	end
    for k in pairs(FENJIE_EQUIP_LIST) do
		FENJIE_EQUIP_LIST[k] = nil
	end
	SUIJI_CNT = 0
end

-- 添加产出道具
local function addOutItem(itemID, itemCnt)
	if itemCnt < 1 then return end
	FENJIE_OUTITEMS[itemID] = FENJIE_OUTITEMS[itemID] or 0
	FENJIE_OUTITEMS[itemID] = FENJIE_OUTITEMS[itemID] + itemCnt
end

local function cleanOutItem(itemID)
	FENJIE_OUTITEMS[itemID] = nil
end

-- 添加产出符文
local function addOutFuwen(fuwenGrid)
	FENJIE_FUWEN_LIST[#FENJIE_FUWEN_LIST + 1] = fuwenGrid
end

-- 添加产出符文
local function addOutEquip(equipGrid)
    equipGrid.putUuid = nil  -- 重置装备穿戴属性
	FENJIE_EQUIP_LIST[#FENJIE_EQUIP_LIST + 1] = equipGrid
end

-- 材料打折
local function solveOutItem(itemID, rate, value, isFloor)
	FENJIE_OUTITEMS[itemID] = FENJIE_OUTITEMS[itemID] or 0
	FENJIE_OUTITEMS[itemID] = FENJIE_OUTITEMS[itemID] * rate + value
	if isFloor then
		FENJIE_OUTITEMS[itemID] = math.floor(FENJIE_OUTITEMS[itemID])
	else
		FENJIE_OUTITEMS[itemID] = math.ceil(FENJIE_OUTITEMS[itemID])
	end
	if FENJIE_OUTITEMS[itemID] <= 0 then 
		FENJIE_OUTITEMS[itemID] = nil
	end
end


--返还宝石
local function returnGem(gemData)
    if not gemData then
        return
    end

	local calCnt = function(level)
		local cnt = 0
		for i=level, 1, -1 do
			cnt = cnt + math.ceil(i/3)
		end
		return cnt
	end

    local num = 0
    for _, v in pairs(gemData) do
        num = num + calCnt(v.lv)
    end
    return  num
end

----------------------------------------------------------------------------------------

-- 判断能否分解
local function checkCanFenjie(human, heroIDList, heroIndexList)
	if heroIDList[0] < 0 then return end
	if heroIDList[0] ~= heroIndexList[0] then return end	
    local indexTable = {}
	for i = 1, heroIDList[0] do
		local heroID = heroIDList[i]
		local heroIndex = heroIndexList[i]
		local heroGrid = HeroLogic.getHeroGrid(human, heroID, heroIndex)	
		if not heroGrid then
			return  -- 信息不一致
		end
		-- 服务器不判断是否上锁，因为分解还有其它地方用到
		if indexTable[heroIndex] then
			return -- 重复index
		end		
		indexTable[heroIndex] = true	

        if CombatPosLogic.isLastInCombat(human, heroGrid.uuid) then
            return
        end

        -- 检查英雄装备
	end	

    
    
	return true	
end


-- 判断碎片能否费解
local function checkCanFenjieChip(human, itemIdList, itemIdCntList)
	if itemIdList[0] < 0 then return end
	if itemIdList[0] ~= itemIdCntList[0] then return end	
    local indexTable = {}
	for i = 1, itemIdList[0] do
		local itemID = itemIdList[i]
		local itemIDCnt = itemIdCntList[i]
        
		-- 判定道具类型
	    local itemConfig = ItemDefine.getConfig(itemID)
	    if not itemConfig then return end
        
		-- 是否是英雄碎片
        if itemConfig.get[2] ~= SuipianLogic.SUMMON_SUBTYPE_HERO then
		   return
	    end 	
		
		local cnt = BagLogic.getItemCnt(human, itemID)	
		if cnt < itemIDCnt then
			return  
		end
		
        -- 服务器不判断是否上锁，因为分解还有其它地方用到
		if indexTable[itemID] then
		   return -- 重复index
		end	
	
		indexTable[itemID] = true	
	end	
	return true	
end


-- 给予玩家道具返还
local function giveItems(human, outItems, fuwenList, equipList, logType)
	local itemList = {}
	for itemID, itemCnt in pairs(outItems) do
		BagLogic.addItem(human, itemID, itemCnt, logType)
		itemList[itemID] = itemList[itemID] or 0
		itemList[itemID] = itemList[itemID] + itemCnt
	end

	for _, fuwenGrid in ipairs(fuwenList) do
		FuwenLogic.addByGrid(human, fuwenGrid, logType)
	end
    for _, equipGrid in ipairs(equipList) do
		EquipLogic.addByEquipGrid(human, equipGrid, logType)
	end
end

-- 统计单个英雄产出
local function calcHeroOut(heroGrid, mainType)
	local heroConfig = HeroExcel.hero[heroGrid.id]	
	if not heroConfig then return end

	-- 等级返还
	local upLvTempConfig = UpNeedExcel.upLv
    local lv = heroGrid.lv
	if heroGrid.oldLV then
		lv = heroGrid.oldLV
	end

	for i = 1, lv do
		local upcf = UpNeedExcel.upLv[i]
		if not upcf then break end
		addOutItem(ItemDefine.ITEM_GREEN_EXP_ID, upcf.soul)
		addOutItem(ItemDefine.ITEM_JINBI_ID, upcf.money)
	end

	local quality = heroGrid.quality
	if heroGrid.oldQuality then
		quality = heroGrid.oldQuality
	end
	
	for i = 1, quality do
		local qcf = UpNeedExcel.upQuality[i]
		if not qcf then break end
		addOutItem(ItemDefine.ITEM_HERO_UPGRADE_ID, qcf.jinjieshi)
		addOutItem(ItemDefine.ITEM_JINBI_ID, qcf.money)
	end

	-- 魔法之尘消耗
	if heroGrid.equip and heroGrid.equip[ItemDefine.EQUIP_SUBTYPE_SHUIJIN] then 
		local equipTempID = heroGrid.equip[ItemDefine.EQUIP_SUBTYPE_SHUIJIN]
		local shuijinMoney = 0
		for j = 1, 10000 do
			if equipTempID == 0 then
				break
			end
			local shuijingUpNeedConfig = EquipExcel.shuijingUpNeed[equipTempID]
			addOutItem(ItemDefine.ITEM_SHUIJING_UPLEVEL_ID, shuijingUpNeedConfig.jinghua)
			addOutItem(ItemDefine.ITEM_JINBI_ID, shuijingUpNeedConfig.money)
			equipTempID = shuijingUpNeedConfig.prevID
		end		
		SUIJI_CNT = SUIJI_CNT + 1
	end
		
	-- 返还装备
	for i = 1, ItemDefine.EQUIP_MAX_CNT do
		if i ~= ItemDefine.EQUIP_SUBTYPE_SHUIJIN and 
			heroGrid.equip and heroGrid.equip[i] then
			local equipGrid = heroGrid.equip[i]
            if equipGrid then
			   addOutEquip(equipGrid)
            end
		end
	end

	-- 返还符文
	for i = 1, 2 do
		local fuwenGrid = heroGrid.fuwen and heroGrid.fuwen[i]
		if fuwenGrid and fuwenGrid.id then
			addOutFuwen(fuwenGrid)
		end
	end

	-- 返还战意  策划说 当战意遗忘处理
	for index = 1, 3 do
		local grid = BingshuLogic.getBingshuGrid(heroGrid, index)
		if grid then 
			local config = FuwenExcel.skill[grid.skillID]
			if config then
				for i = 1,  #config.bingshuForgetReturn do
					local itemID = config.bingshuForgetReturn[i][1]
					local itemCnt = config.bingshuForgetReturn[i][2]
					addOutItem(itemID, itemCnt)
				end
			end
		end		
	end

	
	--返还宝石
	local gemCnt = returnGem(heroGrid.gem)
	if gemCnt and gemCnt > 0 then
		local gemId = HeroDefine.HEROJOBTOGEM[heroConfig.job]
		addOutItem(gemId, gemCnt)
	end
	
end

-- 计算打折
local function calcSolveOuts(mainType)
	solveOutItem(ItemDefine.ITEM_GREEN_EXP_ID, 1, 0, true)
	solveOutItem(ItemDefine.ITEM_HERO_UPGRADE_ID, 1, 0)
	--solveOutItem(ItemDefine.ITEM_SHUIJING_UPLEVEL_ID, 0.6, 3*SUIJI_CNT)
	solveOutItem(ItemDefine.ITEM_JINBI_ID, 1, 120*SUIJI_CNT)
end

-- 计算英雄自身产出
local function calcHeroSelfOut(heroGrid)		
	local baseValueConfig = HeroExcel.baseValue[heroGrid.star]
	for _, item in ipairs(baseValueConfig.items) do
		addOutItem(item[1], item[2])
	end	
	addOutItem(ItemDefine.ITEM_GREEN_EXP_ID, baseValueConfig.soul)
	addOutItem(ItemDefine.ITEM_HERO_UPGRADE_ID, baseValueConfig.jinjieshi)
	addOutItem(ItemDefine.ITEM_SOUL_SUIPIAN_ID, baseValueConfig.suipian)

	--英雄身上的宝石返还
end

local function calcHeroOuts(human, mainType, heroIDList, heroIndexList)
	cleanOutItems() -- 重置产出信息

	for i = 1, heroIDList[0] do
		local heroID = heroIDList[i]
		local heroIndex = heroIndexList[i]
		local heroGrid = HeroLogic.getHeroGrid(human, heroID, heroIndex)	
		calcHeroOut(heroGrid, mainType)

		-- 处理遗物
		if heroGrid and heroGrid.relic then
			WinnerRelicLogic.WinnerRelic_CancelWinner(human, heroGrid, heroIndex)
			heroGrid.relic = {}
		end
	end

	-- 材料打折
	calcSolveOuts(mainType)

	-- 英雄本身价值基数 与 碎片：不打折
	if mainType ~= FENJIE_DO_JUEXING then
		for i = 1, heroIDList[0] do
			local heroID = heroIDList[i]		
		    local heroIndex = heroIndexList[i]
		    local heroGrid = HeroLogic.getHeroGrid(human, heroID, heroIndex)		
			calcHeroSelfOut(heroGrid)
		end
	end
	
	if mainType ~= FENJIE_DO and mainType ~= FENJIE_QUERY then
		cleanOutItem(ItemDefine.ITEM_SOUL_SUIPIAN_ID)
	end
end

-- 发送分解列表
function sendFenjieQuery(human, mainType)
	local msgRet = Msg.gc.GC_FENJIE
	msgRet.type = mainType
	msgRet.itemList[0] = 0

	for itemID, itemCnt in Util.pairsByKeys(FENJIE_OUTITEMS) do
		msgRet.itemList[0] = msgRet.itemList[0] + 1
		Grid.makeItem(msgRet.itemList[msgRet.itemList[0]], itemID, itemCnt)
	end
	for _, fuwenGrid in ipairs(FENJIE_FUWEN_LIST) do
        msgRet.itemList[0] = msgRet.itemList[0] + 1
        Grid.makeItem(msgRet.itemList[msgRet.itemList[0]], fuwenGrid.id, 1, nil, fuwenGrid)
	end

    for _, equipGrid in ipairs(FENJIE_EQUIP_LIST) do
        msgRet.itemList[0] = msgRet.itemList[0] + 1
        Grid.makeItem(msgRet.itemList[msgRet.itemList[0]], equipGrid.id, 1, nil, equipGrid)
	end
	--Msg.trace(msgRet)
	Msg.send(msgRet, human.fd)
end

-- 分解
function fenjie(human, mainType, heroIDList, heroIndexList, sendNotify, logType)
	if not checkCanFenjie(human, heroIDList, heroIndexList) then
		return
	end

    calcHeroOuts(human, mainType, heroIDList, heroIndexList)

	-- 给东西
	local cnt = 0
	if mainType ~= FENJIE_QUERY then
		logType = logType or "hero_fenjie"

		-- 删除英雄
		for i = 1, heroIndexList[0] do
			local heroIndex = heroIndexList[i]

			HeroLogic.delHeroByIndex(human, heroIndex, logType)

			cnt = cnt + 1
		end

		-- 给东西
		giveItems(human, FENJIE_OUTITEMS, FENJIE_FUWEN_LIST, FENJIE_EQUIP_LIST, logType)	
	end
	
	-- 通知客户端
	if sendNotify then
		sendFenjieQuery(human, mainType)
	end
	

	return FENJIE_OUTITEMS
end


-- 分解碎片
function fenjieChip(human, mainType, itemIdList, itemIdCntList, sendNotify, logType)
	if not checkCanFenjieChip(human, itemIdList, itemIdCntList) then
		return
	end
	
	-- 重置
    cleanOutItems()
	
	-- 结算返还材料
	for i = 1, itemIdList[0] do
		local itemID = itemIdList[i]
		local itemCnt = itemIdCntList[i]
		local itemConfig = ItemDefine.getConfig(itemID)
		
	    if itemConfig then 
			for k, v in ipairs(itemConfig.material) do
				addOutItem(v[1], v[2] * itemCnt)
			end                
        end
	end	
	
	-- 给东西
	if mainType ~= FENJIE_QUERY then
		logType = logType or "ship_fenjie"

		-- 删除英雄
		for i = 1, itemIdList[0] do
			local itemID = itemIdList[i]
			local itemCnt = itemIdCntList[i]
			BagLogic.delItem(human, itemID, itemCnt, logType)
		end

		-- 给东西
		giveItems(human, FENJIE_OUTITEMS, FENJIE_FUWEN_LIST, FENJIE_EQUIP_LIST, logType)
	end
	
	-- 通知客户端
	if sendNotify then
		sendFenjieQuery(human, mainType)
	end

	return FENJIE_OUTITEMS
end

-- 自动分解三星以下英雄
function autoFenjie(human, heroID, heroCnt, logType)
	local heroConfig = HeroExcel.hero[heroID]	
	if not heroConfig then return end
	if heroConfig.star > 3 then return end -- 只有三星以下自动分解

	local heroGrid = HeroGrid.getCacheHeroGrid(heroID)
	if not heroGrid then return end 

	cleanOutItems() -- 重置产出信息
	calcHeroOut(heroGrid, FENJIE_DO)
	calcSolveOuts(FENJIE_DO)
	calcHeroSelfOut(heroGrid)

	for itemID, itemCnt in pairs(FENJIE_OUTITEMS) do
		FENJIE_OUTITEMS[itemID] = FENJIE_OUTITEMS[itemID] * heroCnt
	end
	-- 给东西
	giveItems(human, FENJIE_OUTITEMS, FENJIE_FUWEN_LIST, FENJIE_EQUIP_LIST, logType)	
	
	HeroBook.onAddHero(human, heroID, heroGrid.star)
	
	return true, FENJIE_OUTITEMS
end








