local Config = require("Config")
Json = Json or require("common.Json")
local Util = require("common.Util")
local ObjHuman = require("core.ObjHuman")
local Broadcast = require("broadcast.Broadcast")
local Lang = require("common.Lang")
local Msg = require("core.Msg")
local MailManager = require("mail.MailManager")
local CdkFixExcel = require("excel.cdkFix")
local ProjectLogic = require("platform.ProjectLogic")
local BagLogic = require("bag.BagLogic")
local CDKLogic = require("common.CDK")

--1 getCDKInfo/getCDKInfoRet 参数 code ts account
--返回 ret（1成功）  code ts account id item endDate type limitCnt serverIndexs projectName
--2 setCDKUse/setCDKUseRet 参数 code ts account
--返回 ret （1成功） code ts account id item

--ret
--1：成功
--2：激活码已使用
--3：激活码长度不对
--4：没有这个激活码
--5：账号有误
--6：请求失效
--7：更新数据失败
--8：未知错误
--9：SIGN_ERROR

local s2aParam = {}
local CODE_PHP = "/api/cdk.php?a="

function initAfterHot()
	Lang = require("common.Lang")
	CdkFixExcel = require("excel.cdkFix")
end

function isOpen(human)
	return true
end

function CG_CDK(human,msg)
	local code = msg.code

	if cdkFixDo(human,code) then
		return
	end
	cdkDo(human,code)
	--getCDKInfo(human, code)
end

function getCDKInfo(human, code)
	local now = os.time()
    s2aParam.code = code
    s2aParam.ts = now
    s2aParam.account = human.db.account
    s2aParam.action = "getCDKInfo"
	s2aParam.api_cbMethod = "getCDKInfoRet"
	_G.thread_http.send(CODE_PHP,Json.Encode(s2aParam))
end

function getCDKInfoRet(oJsonInput)
	--print("getCDKInfoRet begin")
	--require("common.Util").printTable(oJsonInput)

	local code = oJsonInput.code 		 -- string
	local ts = tonumber(oJsonInput.ts)   -- number
	local account = oJsonInput.account   -- string
	local ret = tonumber(oJsonInput.ret) -- number
	local id = tonumber(oJsonInput.id)   -- number 
	local endDate = nil -- table
	if oJsonInput.endDate and oJsonInput.endDate ~= "" then
		endDate = oJsonInput.endDate
	end
	local typeTemp = tonumber(oJsonInput.type) or 0         -- 0一个cdk只能用一次a玩家用了b玩家就不能再用这个key了 1一个cdk可以让多个玩家反复使用
	local limitCnt = tonumber(oJsonInput.limitCnt) or 0 -- 这个id的礼包同一个玩家可以领取的次数 0表示无限次
	local serverIndexs = nil -- table 
	if oJsonInput.serverIndexs and oJsonInput.serverIndexs ~= "" then
		serverIndexs = oJsonInput.serverIndexs
	end
	local projectName = oJsonInput.projectName or ""

	local human = ObjHuman.onlineAccount[account]
	if not human then
		return
	end

	if ret == 2 then
		return Broadcast.sendErr(human, Lang.CDK_ERR4)
	end

	if ret ~= 1 then
		return Broadcast.sendErr(human, Lang.CDK_ERR1)
	end

	if serverIndexs and (not Util.tableIsEmpty(serverIndexs)) then
		local canUse = false
		for k,v in ipairs(serverIndexs) do
			if Config.SVR_INDEX >= v[1] and Config.SVR_INDEX <= v[2] then
				canUse = true
				break
			end
		end
		if not canUse then
			return Broadcast.sendErr(human, Lang.CDK_ERR1)
		end
	end
	
	if endDate then
		local now = os.time()
		local endTime = os.time(endDate) + 12 * 3600
		if now > endTime then
			--过期
			return Broadcast.sendErr(human, Lang.CDK_ERR2)
		end
	end
	
	local useCnt = human.db.cdk and human.db.cdk[id] or 0
	if typeTemp ~= 0 then
		limitCnt = 1  -- 一对多的礼包一定限制1次，防止刷！
	end
	if limitCnt > 0 and useCnt >= limitCnt then
		return Broadcast.sendErr(human, Lang.CDK_ERR3)
	end

	if typeTemp == 0 then 
		setCDKUse(human, code)
	else
		local item = oJsonInput.item         -- table
		if item == nil or type(item) ~= "table" then
			assert(nil, "getCDKInfoRet item nil" .. code)
		end

		human.db.cdk = human.db.cdk or {}
		human.db.cdk[id] = 1		
		MailManager.add(MailManager.SYSTEM, human.db._id, Lang.CDK_TITLE, Lang.CDK_CONTENT, item, Lang.CDK_TITLE)
		Broadcast.sendErr(human, Lang.CDK_SUCC)
		local msgRet = Msg.gc.GC_CDK
		Msg.send(msgRet, human.fd)
	end
end 

function setCDKUse(human, code)
	local s2aParam = {}
	local now = os.time()
	s2aParam.code = code
	s2aParam.ts = now
	s2aParam.account = human.db.account
	s2aParam.action = "setCDKUse"
    s2aParam.api_cbMethod = "setCDKUseRet"
    _G.thread_http.send(CODE_PHP,Json.Encode(s2aParam))
end

function setCDKUseRet(oJsonInput)
	--print("setCDKUseRet")
	--require("common.Util").printTable(oJsonInput)

	local code = oJsonInput.code         -- string
	local ts = tonumber(oJsonInput.ts)   -- number
	local account = oJsonInput.account   -- string
	local ret = tonumber(oJsonInput.ret) -- number
	local id = tonumber(oJsonInput.id)   -- number
		
	local human = ObjHuman.onlineAccount[account]
	if human == nil then
		return
	end
	
	if ret == 2 then
		return Broadcast.sendErr(human, Lang.CDK_ERR4)
	end

	if ret ~= 1 then
		return Broadcast.sendErr(human, Lang.CDK_ERR1)
	end
	
	local item = oJsonInput.item or ""   -- table
	if item == nil or type(item) ~= "table"then
		assert(nil, "setCDKUseRet item nil" .. code)
	end

	human.db.cdk = human.db.cdk or {}
	human.db.cdk[id] = (human.db.cdk[id] or 0) + 1
	--MailManager.add(MailManager.SYSTEM, human.db._id, Lang.CDK_TITLE, Lang.CDK_CONTENT, item, Lang.CDK_TITLE)	
    BagLogic.addItemList(human, item , "cdk")
	local msgRet = Msg.gc.GC_CDK
	Msg.send(msgRet,human.fd)
end

local function getCdkFixID(code)
	for id,data in pairs(CdkFixExcel.cdkFix) do
		if data.code == code then
			return id,data
		end
	end
end

local function transTime(date) 
	date.hour = 0
	date.min = 0
	date.sec = 0
	return os.time(date)
end

function cdkDo(human,msg)
	--[[local err,cdkBatchData = CDKLogic.checkCDK(code)
	if err then
		Broadcast.sendErr(human,err)
		return
	end
	
    local cdkCfg = CdkFixExcel.cdkFix[cdkBatchData.info]
    if not cdkCfg then 
        Broadcast.sendErr(human,Lang.CDK_INVALID_ERR)
        return
    end
    local nowTime = os.time()
    if nowTime > transTime(cdkCfg.endDate) then 
        --print("cdk over time")
		Broadcast.sendErr(human,Lang.CDK_ERR2)
        return
    end
	if next(cdkCfg.serverIndexs) then
		local canUse = false
		for k,v in ipairs(cdkCfg.serverIndexs) do
			if Config.SVR_INDEX >= v[1] and Config.SVR_INDEX <= v[2] then
				canUse = true
				break
			end
		end
		if not canUse then
			return
		end
	end
	cdkInfo = cdkInfo + 1
	]]
	if msg.err == "invalid code" then 
		Broadcast.sendErr(human,Lang.CDK_INVALID_ERR)
		return 
	end
	local cdkInfo = human.db.cdk[msg.batch] or 0
    if cdkInfo >= msg.useCnt then 
        Broadcast.sendErr(human,Lang.CDK_ERR3)
        return
    end
	human.db.cdk[msg.batch] = cdkInfo + 1
	-- 存储
	BagLogic.addItemList(human, msg.itemList , "cdk")
	Msg.send(Msg.gc.GC_CDK, human.fd)
end

function cdkDoV2(human,msg)
	BagLogic.addItemList(human, msg.itemList , "cdk")
	Msg.send(Msg.gc.GC_CDK, human.fd)
end

function cdkFixDo(human,code)
	local id,conf = getCdkFixID(code)
	if not id or #conf.code <= 0 then
		Broadcast.sendErr(human, Lang.CDK_INVALID_ERR)
        return
    end

	--使用过
	if human.db.cdkFix and human.db.cdkFix[id] then
		Broadcast.sendErr(human, Lang.CDK_ERR4)
        return true
	end

	--项目
	if not ProjectLogic.inProjectName(conf.projectName) then
		return
	end

	--服务器范围
	if next(conf.serverIndexs) then
		local canUse = false
		for k,v in ipairs(conf.serverIndexs) do
			if Config.SVR_INDEX >= v[1] and Config.SVR_INDEX <= v[2] then
				canUse = true
				break
			end
		end
		if not canUse then
			return
		end
	end

	--期限
	if next(conf.endDate) then
		local now = os.time()
		local endTime = os.time(conf.endDate) + 12 * 3600
		if now > endTime then
			--过期
			return
		end
	end

	human.db.cdkFix = human.db.cdkFix or {}
	human.db.cdkFix[id] = 1
    
    BagLogic.addItemList(human, conf.item , "cdk")

	Msg.send(Msg.gc.GC_CDK, human.fd)

	return true
end