local Msg = require("core.Msg")
local ObjHuman = require("core.ObjHuman")
local Define = require("platform.Define")
local Broadcast = require("broadcast.Broadcast")
local Lang = require("common.Lang")
Json = Json or require("common.Json")
local BuyLogic = require("topup.BuyLogic")
local ApiLogic = require("platform.ApiLogic")
local BuyExcel = require("excel.buy").buy

OP_KT = "kt"
OP_BUY = "buy"
local TOKEN_DATA = TOKEN_DATA or {}
TOKEN_DATA[OP_KT] = TOKEN_DATA[OP_KT] or {}
TOKEN_DATA[OP_BUY] = TOKEN_DATA[OP_BUY] or {}
local TIME_OUT = 2 * 60 * 60
local s2aParam = {}



local function addToken(op,token,account)
    TOKEN_DATA[op][token] = {account,os.time()+TIME_OUT}
end

local function rmToken(op,token)
    TOKEN_DATA[op][token] = nil
end

function getKTToken(human,type,actType)
    local pf_info = human.pf_info
    if (pf_info == nil) then
        return
    end
    for k in pairs(s2aParam) do
        s2aParam[k] = nil
    end

   -- 构造参数
    local callback_general_param = {}
    callback_general_param.account = human.db.account
    callback_general_param.name = human.db.name
    callback_general_param.type = type
    s2aParam.callback_general_param = callback_general_param

    local api_param = Define.MakeTencentCommonParam(pf_info)
    api_param.tokentype = 1
    if actType == 1 then
        api_param.discountid = Define.YELLOW_DISCOUNT_ID
    elseif actType == 2 then
        api_param.discountid = Define.BLUE_DISCOUNT_ID
    else
        return
    end
    
    s2aParam.callback_general_param.discountid = api_param.discountid
    
    api_param.ts = os.time()
    api_param.version = "v3" 
    api_param.zoneid = pf_info.zoneid
    s2aParam.api_param = api_param
    
    s2aParam.api_url = "/v3/pay/get_token"
    s2aParam.api_cbMethod = "OnTokenReturnForOpenVip"
    

    _G.thread_http.send(Define.ADMIN_QQAPI_URL,Json.Encode(s2aParam))
end
--开通黄钻蓝钻的token
function OnTokenReturnForKT(result_json)
    local respond = {}
    respond.ret = 0
    respond.msg = "fail"
    local tencent_ret = result_json.tencent_ret
    local general_param = result_json.callback_general_param
    local token = tencent_ret.token
    if not token then
        respond.msg = "fail：token should not be null"
        return Json.Encode(respond) 
    end

    local account = general_param.account
    if (account == nil) then
        respond.msg = "fail：Callback param's name should not be null"
        return Json.Encode(respond)
    end

    local human = ObjHuman.onlineAccount[account]
    if (human == nil) then
        respond.msg = "fail：Human offlined"
        return  Json.Encode(respond)
    end

    if (tencent_ret.ret ~= 0) then
        if tencent_ret.ret == 1002 then
            Broadcast.sendErr(human, Lang.QQAPI_ERR_TIMEOUT)
        end
        respond.msg = "fail：OPENKEY EXPIRE"
        return Json.Encode(respond)
    end
    
    local msgRet = Msg.gc.GC_KT_TOKEN
    msgRet.token = tencent_ret.token
    msgRet.discountid = general_param.discountid
    msgRet.type = general_param.type
    Msg.send(msgRet, human.fd)
    
    addToken(OP_KT,token,account)
    respond.ret = 1
    respond.msg = "success"
    return  Json.Encode(respond)
end


function onDeliverReturnForKT(result_json)
    local respond = {}
    respond.ret = 0
    
    local token = result_json.token
    if token == nil then
        respond.msg = "token is nil"
        return  Json.Encode(respond)
    end 

    local account = TOKEN_DATA[OP_KT][token][1]

    if account == nil or account == "" then
        respond.msg = "account is nil"
        return  Json.Encode(respond)
    end
    
    local human = ObjHuman.onlineAccount[account]
    if (human == nil) then
        respond.msg = "fail：Human offlined"
        return Json.Encode(respond) 
    end 
    
    local itemInfo = Split(result_json.payitem, "*")
    local item_id
    local price
    local item_cnt
    local item_name
    if itemInfo then
        item_id = tonumber(itemInfo[1])
        price = tonumber(itemInfo[2])
        item_cnt = tonumber(itemInfo[3])
    end
    
    local discountid = result_json.discountid
    if discountid == Define.BLUE_DISCOUNT_ID then
        local grid = Grid.create(item_id,item_cnt)
        BagLogic.addItemByGrid(human,grid,"kt_blue")
    end
    
    rmToken(OP_KT,token)
    --加道具 todo
    respond.ret = 1
    respond.msg = "OK"
    return  Json.Encode(respond)
end

function getBuyToken(human, buyID, appmode)
    local buyConfig = BuyExcel[buyID]
    if not buyConfig then
        return
    end
    local name = buyConfig.name
    local desc = buyConfig.desc == "" and name or buyConfig.desc
    local price = buyConfig[human.region]
    local cnt = 1
    local icon = buyConfig.icon

    local pf_info = human.pf_info
    if (pf_info == nil) then
        assert(nil)
        return
    end
    for k in pairs(s2aParam) do
        s2aParam[k] = nil
    end
    -- 构造参数
    local callback_general_param = {}
    callback_general_param.account = human.db.account
    callback_general_param.name = human.db.name
    s2aParam.callback_general_param = callback_general_param
    
    local api_param = Define.MakeTencentCommonParam(pf_info)
    api_param.ts = os.time()
    api_param.payitem = string.format("%s*%d*%d", human.db.account .. "." .. buyID, price * 10, cnt)
    api_param.goodsmeta = string.format("%s*%s", name, desc)
    api_param.goodsurl = Define.QQ_GOOD_URL --.. icon .. ".png"
    api_param.zoneid = pf_info.zoneid
    api_param.appmode = appmode or 2

    s2aParam.api_url = "/v3/pay/buy_goods"
    s2aParam.api_cbMethod = "OnTokenReturnForBuy"
    --end
    s2aParam.api_param = api_param

    _G.thread_http.send(Define.ADMIN_QQAPI_URL,Json.Encode(s2aParam))
end

function OnTokenReturnForBuy(result_json)

    local respond = {}
    respond.ret = 0

    local tencent_ret = result_json.tencent_ret
    local general_param = result_json.callback_general_param

    local account = general_param.account
    if (account == nil) then
        respond.msg = "fail：Callback param's account should not be null"
        return Json.Encode(respond) 
    end

    local human = ObjHuman.onlineAccount[account]
    if (human == nil) then
        respond.msg = "fail：Human offlined"
        return Json.Encode(respond) 
    end
    
    if (tencent_ret.ret ~= 0) then
        if tencent_ret.ret == 1002 then
            Broadcast.sendErr(human, Lang.QQAPI_ERR_TIMEOUT)
        end
        respond.msg = "fail：OPENKEY expire"
        return Json.Encode(respond)
    end

    local token = tencent_ret.token
    local url_params = tencent_ret.url_params
    local msgRet = Msg.gc.GC_BUY_TOKEN
    msgRet.token = token
    msgRet.url = tencent_ret.url_params
    Msg.send(msgRet, human.fd)   
    
    addToken(OP_BUY,token,account)
    respond.ret = 1
    respond.msg = "ok"
    return Json.Encode(respond)
end

-- 腾讯发货回调返回码
local kTencentDeliverRetSuccess         = 0
local kTencentDeliverRetTokenNotExists  = 3
local kTencentDeliverRetParamError      = 4
local kTencentDeliverRetUserOffline     = 5
local kTencentDeliverRetHandlerFailed   = 6

BUY_CONFIRM_LIST = BUY_CONFIRM_LIST or {}
function confirmDeliver(key,human,result_json)
    s2aParam = {}
    local now = os.time()

    local callback_general_param = {}
    s2aParam.callback_general_param = callback_general_param
    
    s2aParam.api_url = "/v3/pay/confirm_delivery"
    s2aParam.api_cbMethod = ""
    local confirm_param = {}
    local pf_info = human.pf_info
    confirm_param["openid"] = pf_info.openid
    confirm_param["openkey"] = pf_info.openkey
    confirm_param["pfkey"] = pf_info.pfkey
    confirm_param["pf"] = pf_info.pf
    confirm_param["billno"] = result_json.billno
    confirm_param["payitem"] = result_json.payitem
    confirm_param["zoneid"] = result_json.zoneid
    confirm_param["amt"] = result_json.amt
    confirm_param["payamt_coins"] = result_json.payamt_coins
    confirm_param["token_id"] = result_json.token
    confirm_param["provide_errno"] = 0
    confirm_param["userip"] = human.db.ip
    confirm_param["worldid"] = pf_info.serverid
    confirm_param["pubacct_payamt_coins"] = result_json.pubacct_payamt_coins    
    confirm_param["ts"] = os.time()
    s2aParam.api_param = confirm_param
    s2aParam.userip = confirm_param.userip
    s2aParam.worldid = confirm_param.worldid

    _G.thread_http.send(Define.ADMIN_QQAPI_URL,Json.Encode(s2aParam))
    BUY_CONFIRM_LIST[key] = nil
end

function onDeliverReturnForBuy(result_json)
    local respond = {}
    respond.result = 0
    respond.account = ""
    local token = result_json.token
    if token == nil then
        respond.result = kTencentDeliverRetTokenNotExists  
        respond.msg = "token is nil"
        return  respond
    end 

    if not TOKEN_DATA[OP_BUY][token] then
        respond.result = 7  
        respond.msg = "token is invaild"
        return  respond 
    end

    local account = TOKEN_DATA[OP_BUY][token][1]

    if account == nil or account == "" then
        account = result_json.accountName
        if account == nil or account == "" then
            respond.result = kTencentDeliverRetParamError  
            respond.msg = "account is nil"
            return  respond
        end
    end
    respond.account = account
    local human = ObjHuman.onlineAccount[account]
    if (human == nil) then
        respond.result = kTencentDeliverRetUserOffline
        respond.msg = "fail：Human offlined"
        return respond
    end 
   
    local payitem = result_json.items or result_json.payitem
    local itemInfo = Define.Split(payitem, "*")
    local buyID
    local price
    local cnt
    local name
    if itemInfo then
        buyID = tonumber(itemInfo[1])
        price = tonumber(itemInfo[2])/10
        cnt = tonumber(itemInfo[3])
    end

    if not BuyLogic.isArgOK(human,buyID,human.region,price) then
        respond.result = kTencentDeliverRetParamError
        respond.msg = "fail：param err"
        return respond
    end 
    local input = {}
    input.account = account
    input.order = "zone_"..token
    input.region = "CN"
    input.gold = 0
    input.money = price
    input.buyID = buyID
	if result_json.amt then
		local amt = tonumber(result_json.amt)
		if amt > 0 then
			input.amt = amt / 100
		end
	end

    local ret = {}
    ApiLogic.charge(input,ret)
    --加道具 end
    if ret.result ~= 1 then
        respond.result = kTencentDeliverRetHandlerFailed
        respond.msg = "ApiLogic.charge err:"..ret.result.."-"..ret.err
        return respond
    end
    rmToken(OP_BUY,token)
    BUY_CONFIRM_LIST[result_json.billno] = {human,result_json}
    respond.result = kTencentDeliverRetSuccess
    respond.msg = "OK"
    return  respond   
end

--[[
--实名注册
function realNameRegister(human, idnumber, name)
    local pf_info = human.pf_info
    if (pf_info == nil) then
        assert(nil)
        return
    end

    for k in pairs(s2aParam) do
        s2aParam[k] = nil
    end

    -- 构造参数
    local callback_general_param = {}
    callback_general_param.account = human.db.account
    s2aParam.callback_general_param = callback_general_param

    local api_param = {}
    api_param.openid = pf_info.openid
    api_param.openkey = pf_info.openkey
    api_param.idnumber = idnumber
    api_param.name = name

    s2aParam.api_url = "/v3/user/gameapi_real_name_register"
    s2aParam.api_cbMethod = "OnRealNameRegister"

    s2aParam.api_param = api_param

    _G.thread_http.send(Define.ADMIN_QQAPI_REAL_NAME_REGISTER,Json.Encode(s2aParam))
end

function OnRealNameRegister(result_json)
    local respond = {}
    respond.ret = 0
    respond.msg = "fail"

    local general_param = result_json.callback_general_param
    local account = general_param.account
    if (account == nil) then
        respond.msg = "fail：Callback param's name should not be null"
        return Json.Encode(respond)
    end

    local human = ObjHuman.onlineAccount[account]
    if (human == nil) then
        respond.msg = "fail：Human offlined"
        return  Json.Encode(respond)
    end

    local msgRet = Msg.gc.GC_REAL_NAME_REGISTER
    msgRet.ret = 0
    msgRet.msg = "success"

    local tencent_ret = result_json.tencent_ret
    if tencent_ret.ret ~= 0 or tencent_ret.reg_result ~= 0 then
        msgRet.ret = tencent_ret.ret
        msgRet.msg = tencent_ret.msg
    end
    Msg.send(msgRet, human.fd)    

    respond.ret = 1
    respond.msg = "success"
    return  Json.Encode(respond)
end--]]

function onTimer()
    for k,v in pairs(BUY_CONFIRM_LIST) do
        confirmDeliver(k,v[1],v[2])
        return
    end
end