local Lang = require("common.Lang")
local Msg = require("core.Msg")
local ObjHuman = require("core.ObjHuman")
local Util = require("common.Util")
local CopyExcel = require("excel.copy")
local Grid = require("bag.Grid")
local RoleDefine = require("role.RoleDefine")
local BagLogic = require("bag.BagLogic")
local CombatDefine = require("combat.CombatDefine")
local CombatLogic = require("combat.CombatLogic")
local DailyTaskLogic = require("dailyTask.DailyTaskLogic")
local ItemDefine = require("bag.ItemDefine")
local Broadcast = require("broadcast.Broadcast")
local Log = require("common.Log")
local RoleSystemLogic = require("roleSystem.RoleSystemLogic")
local ChengjiuLogic = require("chengjiu.ChengjiuLogic")
local VipLogic = require("vip.VipLogic")
local CombatPosLogic = require("combat.CombatPosLogic")
local RoleSystemDefine = require("roleSystem.RoleSystemDefine")
local DragonNestLogic = require("copy.DragonNestLogic")
local MengxinLogic = require("present.MengxinLogic")
local YunYingLogic = require("yunying.YunYingLogic")
local TalismanLogic = require("talisman.TalismanLogic")
-- local RoleStorageBox = require("roleSystem.RoleStorageBox")

COPY_TYPE_JINBI   = 1               --金币挑战
COPY_TYPE_EXP     = 2     			--经验挑战
COPY_TYPE_SUIPIAN = 3               --英雄挑战
COPY_TYPE_MOSHENG = 4               --魔神挑战
COPY_TYPE_FUWEN   = 5               --符文挑战
COPY_TYPE_MAX     = 5

COPY_SAODANG_CAN = 1 				--可扫荡

local SAODANG_COND_LEVEL = 80   -- 女巫副本一键扫荡需要达到的等级

--获取秘宝方面的加成
local function getTalismanAdd(human)
	local jinbiAdd = (TalismanLogic.getTalismanAdd(human, TalismanLogic.OTHER_EFFECT_TBL.NW_JB) or 0) / 100
	local heroExpAdd = (TalismanLogic.getTalismanAdd(human, TalismanLogic.OTHER_EFFECT_TBL.NW_HERO_EXP) or 0) / 100
	local longhunshiAdd = (TalismanLogic.getTalismanAdd(human, TalismanLogic.OTHER_EFFECT_TBL.NW_LHS) or 0) / 100
	local fuwenJinghuaAdd = (TalismanLogic.getTalismanAdd(human, TalismanLogic.OTHER_EFFECT_TBL.NW_FWJH) or 0) / 100
	return jinbiAdd, heroExpAdd, longhunshiAdd, fuwenJinghuaAdd
end

--获取秘宝方面的加成
local function getTalismanChallengeleAdd(human)
	local challengeAdd = TalismanLogic.getTalismanAdd(human, TalismanLogic.OTHER_EFFECT_TBL.NW_CHALLENGE_TIMES) or 0
	return challengeAdd
end


function updateDaily(human)
	DragonNestLogic.updateDaily(human)
	if not human.db.copy then return end
	for i = COPY_TYPE_JINBI , COPY_TYPE_MAX do
		if human.db.copy[i] then
			human.db.copy[i].cnt = 0
			human.db.copy[i].buyCnt = 0
		end
	end
end

-- 挑战查询
function isOpenByType(human,copyType,noSend)
	local copyConfig = CopyExcel.richang[copyType]
	if not copyConfig then return end
	if human.db.lv < copyConfig.lv then
		return
	end
	return true
end

function getMinZDLByType(copyType)
	for _,config in ipairs(CopyExcel.copy ) do
		if config.type == copyType then
			return config.zhandouliNeed
		end
	end
	return 0
end

local function isDotByType(human,copyType)
	if not isOpenByType(human, copyType, true) then
		return
	end

	local copyConfig = CopyExcel.copy[copyType]
	local zhandouli = CombatPosLogic.getCombatHeroZDL(human, CombatDefine.COMBAT_TYPE1)
	local minZDL = getMinZDLByType(copyType)
	if zhandouli < minZDL then
		return
	end

	local leftCnt = getLeftCnt(human, copyType)
	if leftCnt > 0 then
		return true
	end
end

local function getMaxID(human, copyType)
	local copyDB = human.db.copy
	if not copyDB then return 0 end	
	return copyDB[copyType] and copyDB[copyType].maxID or 0
end

local function canSaoDang(human,copyType, id)
	return getMaxID(human, copyType) >= id and COPY_SAODANG_CAN or 0
end


-- 根据副本类型和等级获取copyID
local TYPE_2_COPYLIST = nil
local function getCopyIDByLv(copyType, level)
	if not TYPE_2_COPYLIST then
		TYPE_2_COPYLIST = {}
		for copyID, config in pairs(CopyExcel.copy) do
			if not TYPE_2_COPYLIST[config.type] then
				TYPE_2_COPYLIST[config.type] = {}
			end
			TYPE_2_COPYLIST[config.type][config.level] = copyID
		end
	end
	if not TYPE_2_COPYLIST[copyType] then
		return
	end
	return TYPE_2_COPYLIST[copyType][level]
end

function challengeQuery(human, copyType)
	local config = CopyExcel.richang[copyType]
	if not config then return end

	ObjHuman.updateDaily(human)
	local msgRet = Msg.gc.GC_COPY_CHALLENGE_QUERY
	msgRet.copyType = copyType
	msgRet.leftCnt  = getLeftCnt(human, copyType)
	msgRet.maxCnt   = getCurMaxCnt(human, copyType) 
	msgRet.vipBuy   = getCanBuyCnt(human, copyType)
	msgRet.vipNeed  = config.zuanshi
	msgRet.vipBuyUpLv = VipLogic.getUpPowerNeedLv(human, VipLogic.VIP_POWER13) or 0
	msgRet.redList[0] = #CopyExcel.richang
	msgRet.copyList[0] = #CopyExcel.richang
	for i=1,#CopyExcel.richang do
		msgRet.redList[i] = isDotByType(human,i) and 1 or 0
		msgRet.copyList[i] = CopyExcel.richang[i].lv
	end
	local now = os.time()
	local ts1 = Util.getDayStartTime(now)
	msgRet.nextRefreshTime = 24 * 60 * 60 - (now - ts1)

	--秘宝加成
	local jinbiAdd, heroExpAdd, longhunshiAdd, fuwenJinghuaAdd = getTalismanAdd(human)

	local j = 0  -- 存储相同副本类型的数量
	for i=1, #CopyExcel.copy do
		local copyConfig = CopyExcel.copy[i]
		if copyConfig and copyType == copyConfig.type then
			j = j + 1
			msgRet.list[j].id = i
			msgRet.list[j].level = copyConfig.level
			msgRet.list[j].lvNeed = copyConfig.lvNeed
			msgRet.list[j].zhandouliNeed = copyConfig.zhandouliNeed
			msgRet.list[j].reward[0] = #copyConfig.reward
			msgRet.list[j].saodang = canSaoDang(human,copyType,i) or 0
			for key,value in ipairs (copyConfig.reward) do
				local itemID = value[1]
				local itemCnt = value[2]
				if itemID == ItemDefine.ITEM_JINBI_ID and jinbiAdd > 0 then
					itemCnt = itemCnt + math.ceil(itemCnt * jinbiAdd)
				elseif itemID == ItemDefine.ITEM_GREEN_EXP_ID and heroExpAdd > 0 then
					itemCnt = itemCnt + math.ceil(itemCnt * heroExpAdd)
				elseif itemID == ItemDefine.ITEM_LONGHUNSHI_ID and longhunshiAdd > 0 then
					itemCnt = itemCnt + math.ceil(itemCnt * longhunshiAdd)
				elseif itemID == ItemDefine.ITEM_FUWEN_JINGHUA and fuwenJinghuaAdd > 0 then
					itemCnt = itemCnt + math.ceil(itemCnt * fuwenJinghuaAdd)
				end
				Grid.makeItem(msgRet.list[j].reward[key], itemID, itemCnt)
			end
		end
	end
	msgRet.list[0] = j
	Msg.send(msgRet, human.fd)
	--Msg.trace(msgRet)
end

-- 挑战
function fight(human, args)
	local isok, id, copyConfig = checkCombatPos(human, args)
	if not isok then return end

	-- 调用战斗接口
	CombatLogic.combatBegin(human, copyConfig.mapID, args, CombatDefine.COMBAT_TYPE7, id)
end

-- 获取当前地图ID
function getMapID(human, args)
   local isok, id, copyConfig = checkCombatPos(human, args)
   if not isok then return end
   return copyConfig.mapID
end

function doFightEnd(human,copyID,combatInfo, touch)
	local copyConfig = CopyExcel.copy[copyID]
	if not copyConfig then return end
	
	ObjHuman.updateDaily(human)

	local copyType = copyConfig.type
	
    touch = tonumber(touch or 0)

	--  金币挑战
	if copyType == COPY_TYPE_JINBI then
		--Log.write(Log.LOGID_OSS_BATTLE_GOLD, human.db._id, human.db.account, human.db.name, human.db.lv)
		Log.write(Log.LOGID_OSS_BATTLE_GOLD, human.db._id, human.db.newUniqueTag, human.db.name, human.db.lv)
	end
	
	--  经验挑战
	if copyType == COPY_TYPE_EXP	 then
        --Log.write(Log.LOGID_OSS_BATTLE_EXP, human.db._id, human.db.account, human.db.name, human.db.lv)		
		Log.write(Log.LOGID_OSS_BATTLE_EXP, human.db._id, human.db.newUniqueTag, human.db.name, human.db.lv)
	end
	
	--  碎片挑战
	if copyType == COPY_TYPE_SUIPIAN then
		--Log.write(Log.LOGID_OSS_BATTLE_HERO, human.db._id, human.db.account, human.db.name, human.db.lv)
		Log.write(Log.LOGID_OSS_BATTLE_HERO, human.db._id, human.db.newUniqueTag, human.db.name, human.db.lv)
	end

    local leftCnt = getLeftCnt(human, copyType)
	local canBuy = getCanBuyCnt(human, copyType)

    local fightCnt = touch == 0 and 1 or leftCnt
	
	-- 改db
	human.db.copy = human.db.copy or {}
	human.db.copy[copyType] = human.db.copy[copyType] or {}
	local cnt = human.db.copy[copyType].cnt or 0
	human.db.copy[copyType].cnt = cnt + fightCnt

	local maxCopy = human.db.copy[copyType].maxID or 0
	if copyID > maxCopy then
		human.db.copy[copyType].maxID = copyID --实现成功挑战一次可扫荡逻辑
	end

    local double = RoleSystemLogic.isDouble(human,  RoleSystemDefine.ROLE_SYS_ID_1206)


	--秘宝加成
	local jinbiAdd, heroExpAdd, longhunshiAdd, fuwenJinghuaAdd = getTalismanAdd(human)


	-- 给奖励
	local rewardRate = double and 2 or 1

	local itemList = {}
	for i = 1, #copyConfig.reward do
		local itemID = copyConfig.reward[i][1]
		local itemCnt = copyConfig.reward[i][2]
		local finalCnt = itemCnt * rewardRate * fightCnt
		if itemID == ItemDefine.ITEM_JINBI_ID and jinbiAdd > 0 then
			finalCnt = finalCnt + math.ceil(finalCnt * jinbiAdd)
		elseif itemID == ItemDefine.ITEM_GREEN_EXP_ID and heroExpAdd > 0 then
			finalCnt = finalCnt + math.ceil(finalCnt * heroExpAdd)
		elseif itemID == ItemDefine.ITEM_LONGHUNSHI_ID and longhunshiAdd > 0 then
			finalCnt = finalCnt + math.ceil(finalCnt * longhunshiAdd)
		elseif itemID == ItemDefine.ITEM_FUWEN_JINGHUA and fuwenJinghuaAdd > 0 then
			finalCnt = finalCnt + math.ceil(finalCnt * fuwenJinghuaAdd)
		end

		BagLogic.addItem(human, itemID, finalCnt, "copy_win")
		local index = #itemList+1
		itemList[index] = {}
		itemList[index][1] = itemID
		itemList[index][2] = finalCnt

		if combatInfo and combatInfo.rewardItem then --为nil时是扫荡调用这个方法
			for j = 1, 1 do
				local nowTotalCnt = #combatInfo.rewardItem
				combatInfo.rewardItem[nowTotalCnt + 1] = {}
				combatInfo.rewardItem[nowTotalCnt + 1][1] = itemID
				if itemID == ItemDefine.ITEM_JINBI_ID or itemID == ItemDefine.ITEM_GREEN_EXP_ID
					or itemID == ItemDefine.ITEM_LONGHUNSHI_ID or itemID == ItemDefine.ITEM_FUWEN_JINGHUA then
					combatInfo.rewardItem[nowTotalCnt + 1][2] = finalCnt
				else
					combatInfo.rewardItem[nowTotalCnt + 1][2] = itemCnt * rewardRate * fightCnt
				end
			end
			combatInfo.double = double and 2 or 0
		end
		
	end
	
    DailyTaskLogic.recordDailyTaskFinishCnt(human, DailyTaskLogic.DAILY_TASK_ID_10, fightCnt)
    
    MengxinLogic.onCallBack(human,MengxinLogic.MX_TASK_TYPE_9,1)
	RoleSystemLogic.onDot(human,  RoleSystemDefine.ROLE_SYS_ID_1206)
    RoleSystemLogic.onDot(human,  RoleSystemDefine.ROLE_SYS_ID_1201)

    YunYingLogic.onCallBack(human, "onCopyFight", fightCnt)
    YunYingLogic.onCallBack(human, "onCopyChallenge",fightCnt)

    return itemList
end

-- 挑战结束
function onFightEnd(human, result, combatType, copyID, combatInfo)
	local copyConfig = CopyExcel.copy[copyID]
	if not copyConfig then return end	

	-- todo 太难打了，先改成必定打赢，晚点改回去
	if CombatDefine.RESULT_WIN == result then 
		doFightEnd(human,copyID,combatInfo)
	end	
	local copyTypeConfig = CopyExcel.richang[copyConfig.type]
	if copyTypeConfig then
		combatInfo.defender.name = copyTypeConfig.name 
		combatInfo.panelID = copyTypeConfig.panelID
	end
    YunYingLogic.onCallBack(human, "onCopyChallenge",1)
end

-- 查询购买次数
function buyChallengeQuery(human, copyType)
	do return end 

	--[[
local vipLv = VipLogic.getVipLv(human)
	if vipLv < 1 then
		return Broadcast.sendErr(human, Lang.COPY_BUY_CNT_ERR_VIP)
	end
	
	-- 次数判断
	local leftBuyCnt = getMaxBuyCnt(human) - getCurBuyCnt(human, copyType)
	if leftBuyCnt < 1 then 
		return Broadcast.sendErr(human, Lang.COPY_BUY_CNT_ERR_CNT)
	end
	
    local msgRet = Msg.gc.GC_COPY_BUY_CHALLENGE_QUERY
	msgRet.copyType = copyType
	msgRet.needItemID = ItemDefine.ITEM_ZUANSHI_ID
	msgRet.needItemCnt = CopyExcel.richangDefine[1].zuanshi
	msgRet.curBuyCnt = getCurBuyCnt(human, copyType)
	msgRet.maxBuyCnt = getMaxBuyCnt(human)
	Msg.send(msgRet, human.fd)
	]]
	
end

-- 购买挑战次数
function buyChallengeCnt(human, copyType, buyCnt)

	do return end 

	--[[ 
if buyCnt < 1 then return end
	
	ObjHuman.updateDaily(human)

	-- 条件判断
	local maxBuyCnt = getMaxBuyCnt(human)
	local curBuyCnt = getCurBuyCnt(human, copyType)
		
	-- 最大购买次数判断
	if maxBuyCnt - curBuyCnt < buyCnt then 
		return Broadcast.sendErr(human, Lang.COPY_BUY_CNT_ERR_CNT)
	end
	
	-- 钻石判断
	local needZuanshi = buyCnt * CopyExcel.richangDefine[1].zuanshi
	if not ObjHuman.checkRMB(human, needZuanshi) then
		return
	end
	
	local oldRed = isDotByType(human,copyType)

	-- 扣钻石
	ObjHuman.decZuanshi(human, -needZuanshi, "buy_challenge_cnt")
	
	-- 改db
	human.db.copy = human.db.copy or {}
	human.db.copy[copyType] = human.db.copy[copyType] or {}
	human.db.copy[copyType].buyCnt = curBuyCnt + buyCnt
	
	-- 通知客户端
	local msgRet = Msg.gc.GC_COPY_BUY_CHALLENGE_CNT
	msgRet.copyType = copyType
	msgRet.leftCnt = getLeftCnt(human, copyType)
	msgRet.maxCnt = getMaxCnt(human, copyType) 
	Msg.send(msgRet, human.fd)

	local nowRed = isDotByType(human,copyType)
	if oldRed ~= nowRed then
		refreshRed(human,copyType,nowRed)
	end

	]]
	
end

function getLeftCnt(human, copyType)
	local maxCnt = getMaxCnt(human, copyType)
	local nowCnt = 0
	if human.db.copy and human.db.copy[copyType] then
		nowCnt = human.db.copy[copyType].cnt or 0
	end
	return maxCnt - nowCnt
end

function getCurMaxCnt(human, copyType)
	local challengeCnt = CopyExcel.richang[copyType].challengeCnt
	local buyCnt = getMaxBuyCnt(human, copyType)
	local talismanAdd = getTalismanChallengeleAdd(human)
	local nowCnt = 0
	if human.db.copy and human.db.copy[copyType] then
		nowCnt = human.db.copy[copyType].cnt or 0
	end

	return buyCnt +  challengeCnt + talismanAdd - nowCnt
end

function getMaxCnt(human, copyType)
	local curBuyCnt = getCurBuyCnt(human, copyType)
	local challengeCnt = CopyExcel.richang[copyType].challengeCnt
	local talismanAdd = getTalismanChallengeleAdd(human)
	return challengeCnt + curBuyCnt + talismanAdd
end

function getCanBuyCnt(human, copyType)
	return getMaxBuyCnt(human, copyType) - getCurBuyCnt(human, copyType)
end

function getCurBuyCnt(human, copyType)
	if human.db.copy == nil or human.db.copy[copyType] == nil or 
		human.db.copy[copyType].buyCnt == nil then
		return 0
	end
	
	return human.db.copy[copyType].buyCnt
end

function getMaxBuyCnt(human, copyType)
	return VipLogic.getPowerArgs(human, VipLogic.VIP_POWER13) or 0
end

-- 副本列表日常副本红点
function isDot(human)
	for i=1,#CopyExcel.richang do
		if isOpenByType(human,i,true) and isDotByType(human, i) then
			return true
		end
	end
end

function CG_COPY_CHALLENGE_SAODANG(human,copyID,touch)
	local copyConfig = CopyExcel.copy[copyID]
	if not copyConfig then return end

	local copyType = copyConfig.type
	if not canSaoDang(human,copyType,copyID) then return end

	local oldRed = isDotByType(human,copyType)

    if touch ~= 0 then
       if human.db.lv < SAODANG_COND_LEVEL then return end
    end

	local args = {}
	args[1] = copyID
    args[2] = touch or 0
	local isok, id, copyConfig = checkCombatPos(human, args)
	if not isok then return end

	if args[2] ~= 0 then
		local canBuy = getCanBuyCnt(human, copyType)
		if canBuy >= 1 then
			-- 改db
			human.db.copy = human.db.copy or {}
			human.db.copy[copyType] = human.db.copy[copyType] or {}
			human.db.copy[copyType].buyCnt =  human.db.copy[copyType].buyCnt or 0
			human.db.copy[copyType].buyCnt = human.db.copy[copyType].buyCnt + canBuy
		end
	end


	local itemList = doFightEnd(human,copyID, nil, args[2])	
	local double = RoleSystemLogic.isDouble(human,  RoleSystemDefine.ROLE_SYS_ID_1206)
	local msgRet = Msg.gc.GC_COPY_CHALLENGE_SAODANG
	msgRet.copyType = copyType
	msgRet.copyID = copyID
	msgRet.double = double and 1 or 0
	msgRet.leftCnt = getLeftCnt(human, copyType)
	Msg.send(msgRet,human.fd)

	BagLogic.sendItemGetList(human,itemList, "copy_win")

	local nowRed = isDotByType(human,copyType)
	if oldRed ~= nowRed then
		refreshRed(human,copyType,nowRed)
	end
	challengeQuery(human,  copyType)	
	RoleSystemLogic.onDot(human,  RoleSystemDefine.ROLE_SYS_ID_1206)
    RoleSystemLogic.onDot(human,  RoleSystemDefine.ROLE_SYS_ID_1201)
end

function refreshRed(human,copyType,nowRed)
	local msgRet = Msg.gc.GC_COPY_CHALLENGE_RED
	msgRet.copyType = copyType
	msgRet.isRed = nowRed and 1 or 0
	Msg.send(msgRet,human.fd)
end

--------------------------------------------- combat ----------------------------------------------
function getCombatMonsterOutID(human, side, args)
	if side ~= CombatDefine.DEFEND_SIDE then return end

	local id = tonumber(args[1] or 0)
	local copyConfig = CopyExcel.copy[id]
	if not copyConfig then return end

	return copyConfig.monsterOutID
end

function checkCombatPos(human, args)
	local id = tonumber(args[1] or 0)
    local touch = tonumber(args[2] or 0)
	local copyConfig = CopyExcel.copy[id]
	if not copyConfig then return end

	-- 等级判断
	if human.db.lv < copyConfig.lvNeed then 
		return Broadcast.sendErr(human, Util.format(Lang.COMMON_SYSTEM_OPENTIP, copyConfig.lvNeed))
	end

	--获取全身 最高战力 6人组
	if human.db.zhandouli < copyConfig.zhandouliNeed then 
		return Broadcast.sendErr(human, Util.format(Lang.COMMON_SYSTEM_OPENZHANLI, copyConfig.zhandouliNeed))
	end

	-- 前置副本要先打过
	local preCopyID = getCopyIDByLv(copyConfig.type, copyConfig.level - 1)
	if preCopyID and getMaxID(human, copyConfig.type) < preCopyID then
		return Broadcast.sendErr(human, Lang.COPY_FIGHT_ERR_PREID)
	end

	ObjHuman.updateDaily(human)
	local copyType =  copyConfig.type
	local leftCnt = getLeftCnt(human, copyType)

    if touch == 0 then
	    if leftCnt < 1 then
	    	local canBuy = getCanBuyCnt(human, copyType)
	    	if canBuy < 1 then
	    		return Broadcast.sendErr(human, Lang.COPY_FIGHT_ERR_NO_CNT) 
	    	end
        
	    	-- 钻石判断
	    	local needZuanshi = CopyExcel.richang[copyType].zuanshi
	    	if not ObjHuman.checkRMB(human, needZuanshi) then
	    		return  Broadcast.sendErr(human, Lang.COMMON_NO_ZUANSHI) 
	    	end
	    	-- 扣钻石
	    	ObjHuman.decZuanshi(human, -needZuanshi, "buy_challenge_cnt")
        
	    	-- 改db
	    	human.db.copy = human.db.copy or {}
	    	human.db.copy[copyType] = human.db.copy[copyType] or {}
	    	human.db.copy[copyType].buyCnt =  human.db.copy[copyType].buyCnt or 0
	    	human.db.copy[copyType].buyCnt = human.db.copy[copyType].buyCnt + 1
	    end
    else
		--if leftCnt < 1 then
			local canBuy = getCanBuyCnt(human, copyType)
			if canBuy < 1 then
				return Broadcast.sendErr(human, Lang.COPY_FIGHT_ERR_NO_CNT) 
			end
			-- 钻石判断
			local needZuanshi = CopyExcel.richang[copyType].zuanshi * canBuy
			if not ObjHuman.checkRMB(human, needZuanshi) then
				return  Broadcast.sendErr(human, Lang.COMMON_NO_ZUANSHI) 
			end
			-- 扣钻石
			ObjHuman.decZuanshi(human, -needZuanshi, "buy_challenge_cnt")

			-- 改db
			human.db.copy = human.db.copy or {}
			human.db.copy[copyType] = human.db.copy[copyType] or {}
			human.db.copy[copyType].buyCnt =  human.db.copy[copyType].buyCnt or 0
			human.db.copy[copyType].buyCnt = human.db.copy[copyType].buyCnt + canBuy
		--end
    end

	return true, id, copyConfig
end

function onUpdatePos(human)
	RoleSystemLogic.onDot(human,  RoleSystemDefine.ROLE_SYS_ID_1206)
    RoleSystemLogic.onDot(human,  RoleSystemDefine.ROLE_SYS_ID_1201)
end
