local Lang  = require("common.Lang")
local Msg = require("core.Msg")
local ObjHuman = require("core.ObjHuman")
local ZhuanpanExcel = require("excel.zhuanpan")
local ItemDefine = require("bag.ItemDefine")
local BagLogic = require("bag.BagLogic")
local Grid = require("bag.Grid")
local Broadcast = require("broadcast.Broadcast")
local RoleSystemLogic = require("roleSystem.RoleSystemLogic")
local RoleSystemDefine = require("roleSystem.RoleSystemDefine")
local ItemExcel = require("excel.item").item
local Util = require("common.Util")
local HeroExcel = require("excel.hero").hero
local ChatPaoMaLogic = require("chat.ChatPaoMaLogic")
local VipLogic = require("vip.VipLogic")
local EquipLogic = require("equip.EquipLogic")

DEFAULT_ZHUANPAN_TYPE_NORMAL 		= 1     -- 基础转盘
DEFAULT_ZHUANPAN_TYPE_GAOJI  		= 2     -- 高级转盘

DEFAULT_BUY_ZHUANPAN_CNT     		= 50    -- 购买许愿珠所需钻石
DEFAULT_FREE_REFRESH_TIME    		= 10800 -- 免费刷新的时间

ZHUAN_PAN_ITEM_KIND_CNT 			= 8 -- 转盘种类数量

DEFAULT_MAX_LUCK = 1000


REWARD_RECORD = { index={}, order={} }
REWARD_RECORD_CNT = 15

function getLuckConfig(mainType)
	local config = nil
	if mainType == DEFAULT_ZHUANPAN_TYPE_NORMAL then
	   config = ZhuanpanExcel.luck1
	elseif mainType == DEFAULT_ZHUANPAN_TYPE_GAOJI then
	   config = ZhuanpanExcel.luck2
	end
	
	return config
end


function red(human, type)
    if not human.db.zhuanpan then return end
    local zhuanpan = human.db.zhuanpan[type]
    local config = getLuckConfig(type)
    if zhuanpan then
       local luckStatus = zhuanpan.luckStatus
       for k, v in pairs(config) do
           if zhuanpan.luck >= k then
              if luckStatus[k] == 1 then		
	       		    return true
	       		 end
           end 	
       end
    end
    if zhuanpan.free == 1 then
        return true
    end
end

-- 转盘查询
function query(human, mainType)
	local zhuanpanConfig = ZhuanpanExcel[mainType]
	if not zhuanpanConfig then return end

	-- 高级转盘判断等级
    local roleConfig = nil
    local flag, roleConfig = RoleSystemLogic.isOpen(human,RoleSystemDefine.ROLE_SYS_ID_501)
	if mainType == DEFAULT_ZHUANPAN_TYPE_GAOJI then
		if flag ~= true then
			return Broadcast.sendErr(human, Lang.ZHUANPAN_GAIJI_NEED_LV)
		end
	end

	local oldCnt = getCntByType(human, mainType)
	-- 更新 
	update(human, mainType)
	
	-- 初始化
	initDB(human, mainType, oldCnt)

    local zuanpan = human.db.zhuanpan[mainType]	
	
	local config = ZhuanpanExcel.define[mainType]
	local msgRet = Msg.gc.GC_ZHUANPAN_QUERY
	msgRet.type = mainType
    msgRet.isFirst = zuanpan.free == 1 and 1 or 0
	local now = os.time()
	local ts1 = now - zuanpan.ts1
	msgRet.refreshTime = 24 * 60 * 60 - ts1
	msgRet.freeRefreshTime = DEFAULT_FREE_REFRESH_TIME - (now - zuanpan.ts2)
	if msgRet.freeRefreshTime < 0 then
		msgRet.freeRefreshTime = 0
	end

	Grid.makeItem(msgRet.itemID, config.useItemID , 1)
	msgRet.itemCnt[0] = 2
	msgRet.itemCnt[1] = config.useItemCnt1
	msgRet.itemCnt[2] = config.useItemCnt2
	msgRet.drawCnt = config.drawCnt2
    Grid.makeItem(msgRet.zuanshiNeed, config.refreshCost[1][1], config.refreshCost[1][2])
    msgRet.needLv = config and config.lv or 0
    if mainType == DEFAULT_ZHUANPAN_TYPE_NORMAL then
       msgRet.needLv = ZhuanpanExcel.define[DEFAULT_ZHUANPAN_TYPE_GAOJI].lv
    elseif mainType == DEFAULT_ZHUANPAN_TYPE_GAOJI then
       msgRet.needLv = ZhuanpanExcel.define[DEFAULT_ZHUANPAN_TYPE_NORMAL].lv
    end
	msgRet.needVipLv = VipLogic.getPowerNeedLv(VipLogic.VIP_POWER15)
	
	for i = 1, ZHUAN_PAN_ITEM_KIND_CNT do
		local data = zuanpan[i]
		
		local dataID = data.id
		local tempConfig = zhuanpanConfig[dataID]
		Grid.makeItem(msgRet.list[i].item, data.itemID, data.itemCnt)
		msgRet.list[i].id = dataID
		msgRet.list[i].chance = tempConfig.chance
		msgRet.list[i].maxCnt = tempConfig.getCnt
		msgRet.list[i].getCnt = 0
		if data.getCnt then 
			msgRet.list[i].getCnt = data.getCnt
		end
	end
	
    local luckConfig = getLuckConfig(mainType)	
	
	msgRet.luck = zuanpan.luck or 0
	local len = 0
	for k, v in pairs(luckConfig) do
	   len = len + 1
	   local net = msgRet.luckList[len]
	   net.id = k
	   net.status = zuanpan.luckStatus[k] or 0
	   Grid.makeItem(net.item, v.reward[1] , v.reward[2])
	end
	msgRet.luckList[0] = len
	
    len = 0
    if REWARD_RECORD[mainType] then 
	   for k, v in ipairs(REWARD_RECORD[mainType]) do
	      len = len + 1
	      local net = msgRet.record[len]
	      net.id = k
          net.tips = v.tips
	      net.timer = v.timer
          net.order = v.order
	   end
    end
	msgRet.record[0] = len
    msgRet.list[0] = ZHUAN_PAN_ITEM_KIND_CNT

    len = 0
    local totalWeight = 0
    local chanceList = {}
	for k, v in pairs(zhuanpanConfig) do
	   totalWeight = totalWeight + v.chance
       chanceList[k] = chanceList[k] or {}
       local rewardWeight = 0
       for a, b in ipairs(v.rewardID) do
          rewardWeight = rewardWeight + b[3]
       end
       chanceList[k].totalWeight = rewardWeight
	end
    
    -- 大全重占比
    local temp = {}
    for k, v in pairs(zhuanpanConfig) do
        local chance = chanceList[k]
        local scale = v.chance / totalWeight
        for a, b in ipairs(v.rewardID) do
           local itemID = b[1]
           if not temp[itemID] then
               local weight = b[3] / chance.totalWeight
               len = len + 1
               local net = msgRet.chanceList[len]
               local itemConfig = ItemDefine.getConfig(itemID)
               if not itemConfig then
                  print(itemID)
               end
               net.tips = itemConfig and itemConfig.name or ""
               net.chance = weight * scale * 100
               temp[itemID] = 1
           end
        end 
    end
    
	msgRet.chanceList[0] = len
      
    local red1 = red(human, DEFAULT_ZHUANPAN_TYPE_NORMAL)
    msgRet.red1 = red1 == true and 1 or 0
  
    local red2 = red(human, DEFAULT_ZHUANPAN_TYPE_GAOJI)
    msgRet.red2 = red2 == true and 1 or 0

	Msg.send(msgRet, human.fd)
end

function refresh(human, mainType, needTime)
	if not ZhuanpanExcel[mainType] then
		return
	end	
	
    local oldCnt = getCntByType(human, mainType)
	
    -- 更新 
	update(human, mainType)
	
	-- 初始化
	initDB(human, mainType, oldCnt)
	
	-- 判断是否免费
    if needTime then
	    local config = ZhuanpanExcel.define[mainType]
	    local needCost = 0
        local now = os.time()
	    local ts2 = now - human.db.zhuanpan[mainType].ts2
	    local leftTime = DEFAULT_FREE_REFRESH_TIME - ts2
	    if leftTime > 0 then
	    	needCost = config.refreshCost[1][2]
	    end
	    
	    -- 判断消耗
	    local cnt = BagLogic.getItemCnt(human, config.refreshCost[1][1])
	    if cnt < needCost then
            return
        end
	    -- 扣消耗
	    if needCost > 0 then
            BagLogic.delItem(human, config.refreshCost[1][1], needCost, "zhuanpan_refresh")
	    end
	    
	    -- 改db
        local dayStartTime = Util.getDayStartTime(now)
	    human.db.zhuanpan[mainType].ts2 = now
	    human.db.zhuanpan[mainType].ts1 = dayStartTime
    end

	addRandomReward(human, mainType)
	
	-- 通知客户端
    if needTime then
	    query(human, mainType)
    end
end

-- 刷新数据
function updateDaily(human)
	refresh(human, DEFAULT_ZHUANPAN_TYPE_NORMAL)
    refresh(human, DEFAULT_ZHUANPAN_TYPE_GAOJI)

    human.db.zhuanpan[DEFAULT_ZHUANPAN_TYPE_NORMAL].free = 1
    human.db.zhuanpan[DEFAULT_ZHUANPAN_TYPE_NORMAL].freeCnt = 0
end


-- 抽奖
function getReward(human, mainType, cnt)
	local config = ZhuanpanExcel.define[mainType]
	if not ZhuanpanExcel[mainType] then
		return
	end	
	local needItemID = config.useItemID
	local needItemCnt = nil

	if cnt == 1 then
		needItemCnt = config.useItemCnt1
	elseif cnt == config.drawCnt2 then
		needItemCnt = config.useItemCnt2
		-- 多次抽奖需要达到指定vip等级
		--[[local needVipLv = VipLogic.getPowerNeedLv(VipLogic.VIP_POWER15)
		if VipLogic.getVipLv(human) < needVipLv then
			return Broadcast.sendErr(human, Util.format(Lang.ROLE_VIP_ERROR2, needVipLv))
		end]]
	end
	if needItemCnt == nil then
		return
	end
	
	local oldCnt = getCntByType(human, mainType)
	-- 更新 
	update(human, mainType)
	
	-- 初始化
	initDB(human, mainType, oldCnt)
	
	local zhuanpan = human.db.zhuanpan[mainType]
	if not BagLogic.checkItemCnt(human, needItemID, needItemCnt) then
		return
	end	
	-- 扣消耗
	BagLogic.delItem(human, needItemID, needItemCnt, "zhuanpan_get")
	
	local msgRet = Msg.gc.GC_ZHUANPAN_GET_REWARD
	msgRet.type = mainType
	msgRet.list[0] = cnt
    local len = 0
	for i = 1, cnt do
		local result = getLuckDrawSingle(human, mainType)
		if result == nil then
			assert(nil)
		end
		
		-- 改db
		local data = zhuanpan[result]
		local zhuanpanConfig = ZhuanpanExcel[mainType]
		local tempConfig = zhuanpanConfig[data.id]
		local nowGetCnt = data.getCnt or 0
		local maxGetCnt = tempConfig.getCnt
		if maxGetCnt ~= 0 then
			data.getCnt = nowGetCnt + 1
		end

		-- 加道具
		local itemID = data.itemID
		local itemCnt = data.itemCnt
		BagLogic.addItem(human, itemID, itemCnt, "zhuanpan_get")

		local itemConfig = ItemExcel[itemID]
		local heroConfig = HeroExcel[itemID]
		-- 存在部分 英雄配表里面的id 和装备配表重合了
		if itemConfig and itemConfig.subType == ItemDefine.ITEM_SUBTYPE_SUIPIAN and heroConfig and heroConfig.star == 5 then
			if mainType == DEFAULT_ZHUANPAN_TYPE_GAOJI then
				ChatPaoMaLogic.broadcast(human, ChatPaoMaLogic.PAOMA_TYPE_BROAD_TYPE11, tempConfig.grade, itemID)
			else
				ChatPaoMaLogic.broadcast(human, ChatPaoMaLogic.PAOMA_TYPE_BROAD_TYPE10, tempConfig.grade, itemID)
			end
		end


		if tempConfig.getCnt > 0 then
            if not REWARD_RECORD[mainType] then
               REWARD_RECORD[mainType] = {}
            end

            local record = REWARD_RECORD[mainType]
            local index = REWARD_RECORD.index[mainType] or 1
            local order = REWARD_RECORD.order[mainType] or 1
		    record[index] = record[index] or {}
            record[index].tips = Util.format(Lang.ZHUANPAN_RECORD_TWO,  human.db.name, ItemDefine.getValue(itemID,"name"), itemCnt)
	        record[index].timer = os.time()
            record[index].order = order

			index = index + 1
	        if index > REWARD_RECORD_CNT then
	           index = 1
	        end
            REWARD_RECORD.order[mainType] = order + 1
            REWARD_RECORD.index[mainType] = index
		end
	    
		msgRet.list[i] = data.id

        len = len + 1
        if not ItemDefine.isEquip(itemID) then
           Grid.makeItem(msgRet.item[len], itemID, itemCnt)
        else
           EquipLogic.makeEquipItemOne(human, msgRet.item[len])
        end
	end
	msgRet.item[0] = len
  
    
	-- 增加积分	
	local itemID  = ItemDefine.ITEM_LUCK_ID
	local itemCnt = cnt * 10
	BagLogic.addItem(human, itemID, itemCnt, "zhuanpan_back")
    msgRet.luckItem[0] = 1
    Grid.makeItem(msgRet.luckItem[1], itemID, itemCnt)
 
	zhuanpan.cnt = zhuanpan.cnt or 0
	zhuanpan.cnt = zhuanpan.cnt + cnt
	
	zhuanpan.luck = zhuanpan.luck or 0
	zhuanpan.luck = zhuanpan.luck + cnt * 10	
	zhuanpan.luckStatus = zhuanpan.luckStatus or {}
	
	local luckConfig = getLuckConfig(mainType)
	-- 集火幸运值 奖励
    local luckStatus = zhuanpan.luckStatus
    for k, v in pairs(luckConfig) do
        if zhuanpan.luck >= k then
            if luckStatus[k] == nil then		
			   luckStatus[k] = 1
			end
        end 	
	end

    Msg.send(msgRet, human.fd)


    query(human, mainType)
end

-- 购买许愿珠
function buyCnt(human, mainType, cnt)
	if cnt < 1 then return end
	
	if mainType ~= DEFAULT_ZHUANPAN_TYPE_NORMAL then
		return
	end
	
	local needZuanshi = 50 * cnt
	
	-- 判断消耗
	if not ObjHuman.checkRMB(human, needZuanshi) then
		return
	end
	
	-- 扣消耗
	ObjHuman.decZuanshi(human, -needZuanshi, "zhuanpan_buy_cnt", ItemDefine.ITEM_BASE_QIYUANZHU_ID, cnt)

	-- 增加物品
	BagLogic.addItem(human, ItemDefine.ITEM_BASE_QIYUANZHU_ID, cnt, "zhuanpan_buy_cnt")
	
	-- 通知客户端
	local msgRet = Msg.gc.GC_BUY_ZHUANPAN_CNT
	Msg.send(msgRet, human.fd)
end

------------------------------功能函数--------------------------------------
function addRandomReward(human, mainType)
	local zhuanpanConfig = ZhuanpanExcel[mainType]
	if not zhuanpanConfig then return end
	local nowLv = human.db.lv
	local itemID = nil
	local itemCnt = nil
	local cntIndex = 0
	for i = 1, #zhuanpanConfig do 
		local tempConfig = zhuanpanConfig[i]
		if not tempConfig then return end
		if mainType == DEFAULT_ZHUANPAN_TYPE_NORMAL then 
			if nowLv >= tempConfig.minLv and nowLv <= tempConfig.maxLv then 
				itemID, itemCnt = getRandomItem(human, tempConfig)
                if itemID and itemCnt then
				   cntIndex = cntIndex + 1
				   human.db.zhuanpan[mainType][cntIndex] = {}
				   human.db.zhuanpan[mainType][cntIndex].id = i
				   human.db.zhuanpan[mainType][cntIndex].itemID = itemID
				   human.db.zhuanpan[mainType][cntIndex].itemCnt = itemCnt
                end
			end
		elseif mainType == DEFAULT_ZHUANPAN_TYPE_GAOJI then 
			itemID, itemCnt = getRandomItem(human, tempConfig)
            if itemID and itemCnt then
			   cntIndex = cntIndex + 1
			   human.db.zhuanpan[mainType][cntIndex] = {}
			   human.db.zhuanpan[mainType][cntIndex].id = i
			   human.db.zhuanpan[mainType][cntIndex].itemID = itemID
			   human.db.zhuanpan[mainType][cntIndex].itemCnt = itemCnt
            end
		end
	end
end

function getLuckDrawSingle(human, mainType)
	local zhuanpanConfig = ZhuanpanExcel[mainType]
	if not zhuanpanConfig then return end
	local totalWeight = 0
	local recordData = nil
	
	for i = 1, ZHUAN_PAN_ITEM_KIND_CNT do
		local data = human.db.zhuanpan[mainType][i]
		local drawID = data.id
		local tempConfig = zhuanpanConfig[drawID]
		local nowGetCnt = data.getCnt or 0
		local maxGetCnt = tempConfig.getCnt
		if maxGetCnt == 0 or maxGetCnt > nowGetCnt then
			totalWeight = totalWeight + tempConfig.chance
		end
	end
	
	local randNum = math.random(1,totalWeight)
	for i = 1, ZHUAN_PAN_ITEM_KIND_CNT do
		local data = human.db.zhuanpan[mainType][i]
		local drawID = data.id
		local tempConfig = zhuanpanConfig[drawID]
		local nowGetCnt = data.getCnt or 0
		local maxGetCnt = tempConfig.getCnt
		if maxGetCnt == 0 or maxGetCnt > nowGetCnt then
			local tempWeight = tempConfig.chance
			if randNum <= tempWeight then
				return i
			end
			randNum = randNum - tempWeight
		end
	end	
end

function initDB(human, mainType, cnt)
	if human.db.zhuanpan ~= nil and 
       human.db.zhuanpan[mainType] ~= nil then 
		return 
	end 
    local now = os.time()
	human.db.zhuanpan = human.db.zhuanpan or {}
	human.db.zhuanpan[mainType] = {}
    local dayStartTime = Util.getDayStartTime(now)
	human.db.zhuanpan[mainType].ts1 = dayStartTime
	human.db.zhuanpan[mainType].ts2 = now - DEFAULT_FREE_REFRESH_TIME
	human.db.zhuanpan[mainType].cnt = cnt
	human.db.zhuanpan[mainType].luck = 0
	human.db.zhuanpan[mainType].free = 1
	human.db.zhuanpan[mainType].luckStatus = {}
	addRandomReward(human, mainType)
end

function update(human, mainType) 
	if human.db.zhuanpan == nil or human.db.zhuanpan[mainType] == nil then 
		return 
	end
	if human.db.zhuanpan[mainType].ts1 then 
		-- 防止前端 在结束倒计时结束 发送查询 , 这边还没有结束 返回一样的数据
		local now = os.time() + 1
		local ts1 = now - human.db.zhuanpan[mainType].ts1
		local leftTime = 24 * 60 * 60 - ts1
		if leftTime <= 0 then 
			human.db.zhuanpan[mainType] = nil
		end
	end
end

function getRandomItem(human, tempConfig)
    local totalWeight = 0
    for k, v in ipairs(tempConfig.rewardID) do
       totalWeight = totalWeight + v[3]
    end

    local random = math.random(1, totalWeight)
    for k, v in ipairs(tempConfig.rewardID) do
       local weight = v[3]
       local itemID = v[1]
	   local itemCnt = v[2]
       if random <= weight then
          return itemID, itemCnt
       end
       random = random - weight
    end	
end

function zhuanpanByGm(human,mainType,val)
	if not mainType and not val then
		return
	end
	if mainType == 0 or mainType > 2 or val < 5 then
		return
	end
	if human.db.zhuanpan[mainType] then
		local now = os.time()
		human.db.zhuanpan[mainType].ts1 = now - 24 * 60 * 60  + val
	end
end

function getCntByType(human, mainType)
	local num = 0
	if	human.db.zhuanpan and human.db.zhuanpan[mainType] then
		human.db.zhuanpan[mainType].cnt = human.db.zhuanpan[mainType].cnt or 0
		num = human.db.zhuanpan[mainType].cnt
	end
	return num
end

function getLuck(human, msg)
	local mainType = msg.type
    local config = getLuckConfig(mainType)
	if not config then
		return
	end	
	
	local zhuanpan = human.db.zhuanpan[mainType]
	if zhuanpan == nil then
	   return
	end
	
	if zhuanpan.luck <= 0 then
        return
    end
	
	local luckStatus = zhuanpan.luckStatus
	if luckStatus == nil or luckStatus[msg.id] ~= 1 then
	   return
	end
	luckStatus[msg.id] = 2
	
	BagLogic.addItem(human, config[msg.id].reward[1], config[msg.id].reward[2], "zhuanpan_back")
	
    local itemList = {[1] = {config[msg.id].reward[1],config[msg.id].reward[2]}}
	BagLogic.sendItemGetList(human,itemList, "zhuanpan_back")
	
    --计算是否需要重新扣除幸运值 重新激活奖励
	local luck = zhuanpan.luck
	local calc = true
    for k, v in pairs(config) do
        if luckStatus[k] == nil or luckStatus[k] ~= 2 then
		   calc = false
		end
    end
	
	if calc == true then
	   zhuanpan.luckStatus = {}	
	   luck = luck - DEFAULT_MAX_LUCK
	   luck = luck < 0 and 0 or luck
	   zhuanpan.luck = luck
	   
	    -- 集火幸运值 奖励
        local luckStatus = zhuanpan.luckStatus
        for k, v in pairs(config) do
            if zhuanpan.luck >= k then
                if luckStatus[k] == nil then		
	    		   luckStatus[k] = 1
	    		end
            end 	
	    end
	end
	
	
	query(human, msg.type)
end

function isDot(human)

   local red1 = red(human, DEFAULT_ZHUANPAN_TYPE_NORMAL)
   if red1 then return true end

   --local red2 = red(human, DEFAULT_ZHUANPAN_TYPE_GAOJI)
   --if red2 then return true end
 
   return false
end

function getFree(human)
    initDB(human,DEFAULT_ZHUANPAN_TYPE_NORMAL)
    if human.db.zhuanpan[DEFAULT_ZHUANPAN_TYPE_NORMAL].free ~= 1 then
        return
    end

    human.db.zhuanpan[DEFAULT_ZHUANPAN_TYPE_NORMAL].free = 0
    local zhuanpanConfig = ZhuanpanExcel.define[DEFAULT_ZHUANPAN_TYPE_NORMAL]

    local len = #zhuanpanConfig.freeCnt
    local totalWeight = 0
    for i = 1,len do
        totalWeight = totalWeight + zhuanpanConfig.freeCnt[i][2]
    end

    local itemCnt = nil
    local randomWeight = math.random(1,totalWeight)
    for i = 1,len do
        if randomWeight < zhuanpanConfig.freeCnt[i][2] then
            itemCnt = zhuanpanConfig.freeCnt[i][1]
            break
        else
            randomWeight = randomWeight - zhuanpanConfig.freeCnt[i][2]
        end
    end
    if itemCnt then
        local item = {}
        item[1] = {zhuanpanConfig.useItemID,itemCnt}
        item[2] = zhuanpanConfig.freeitem[1]
        BagLogic.addItemList(human, item, "zhuanpan_get")
    else
        assert()
    end
end