package gameapi

import (
	"../log"
	"../mod"
	pb "../protos"
	"bytes"
	"crypto/tls"
	"encoding/json"
	"github.com/shopspring/decimal"
	"go.uber.org/zap"
	"io/ioutil"
	"net/http"
	"strconv"
)

/*
	ig电子  ig-lmg视讯 ig彩票
*/

var Ig_key             = "kgdls_49b0539f-10fc-45e6-b1b6-e6b136"						//key
var Ig_dz_addr         = "http://slotssw.iasia99.com/igapiyfslotssw/app/api.do"     //电子游戏
var Ig_ctc_addr        = "http://lotterysw.iasia99.com/igapiyflotterysw/app/api.do" //传统彩
var Ig_live_addr       = "http://livesw.iasia99.com/igapiyflivesw/app/api.do"       //视讯 gameType 参数
var Ig_aboutMoney_addr = "http://igcqkapi.ig885.com/ig2apiyftrade/app/api.do"     //上分 余额 下分

const (
	LOGIN_COMMAND       = "LOGIN"       //登陆
	DEPOSIT_COMMAND     = "DEPOSIT"     //上分
	WITHDRAW_COMMAND    = "WITHDRAW"    //下分
	GET_BALANCE_COMMAND = "GET_BALANCE" //获取余额

	LMG_LIVE = "LMG_LIVE"
	DZ_BS  = "SLOTS_LUCKY_BS"
	DZ_MG  = "SLOTS_LUCKY_MG"
	DZ_NE  = "SLOTS_LUCKY_NE"
	DZ_NG  = "SLOTS_LUCKY_NG"
	DZ_PT  = "SLOTS_LUCKY_PT"
	//CURRENCY = "TEST"
	CURRENCY = "CNY"
)

func IG_Enter_Game(guid string, gameParam []string, cash int64, isReconnect bool, res *pb.S_EnterGame, category int){

	log.Debug("IG_Enter_Game params",zap.String("guid",guid), zap.Any("gameParam", gameParam), zap.Int("category",category))

	var response ig_response_header
	var ig_addr  string	//请求地址
	var inner_param interface{} //内部参数

	switch category {

	case IG_LMG:
		if len(gameParam) != 1{
			res.Ec = SYS_GAME_PARAM_ERROR
			log.Debug("IG_Enter_Game IG_LMG len(gameParam) wrong",zap.Int("len",len(gameParam)))
			return
		}
		ig_addr = Ig_live_addr
		inner_param = &ig_login_LMG{guid,Md5Encrypt(guid),CURRENCY,guid,"CN",LMG_LIVE,"1",gameParam[0],"NO"}

	case IG_LOTTERY:
		ig_addr = Ig_ctc_addr
		inner_param = &ig_login_lottery{guid,Md5Encrypt(guid),CURRENCY,guid,"CN","HALL", "A","A","A","A","A","CLOSE","0",""}

	case IG_DZ:
		if len(gameParam) != 2{
			res.Ec = SYS_GAME_PARAM_ERROR
			log.Debug("IG_Enter_Game IG_DZ len(gameParam) wrong",zap.Int("len",len(gameParam)))
			return
		}
			ig_addr = Ig_dz_addr
			inner_param = &ig_login_dz{guid,Md5Encrypt(guid),CURRENCY,guid,"CN",
				gameParam[0],"1",gameParam[1]}
	}

	//1.登陆
	req_param := &ig_post_header{Ig_key,LOGIN_COMMAND,inner_param}
	if ig_request(ig_addr, req_param, &response){

		cash_ := IG_convertBalance(cash)
		ref := GetFormatDate() + guid
		params1 := ig_addMoney{guid,Md5Encrypt(guid),ref,"",strconv.FormatFloat(cash_,'f',-1,64)}
		addMoney := &ig_post_header{Ig_key,DEPOSIT_COMMAND,params1}
		if isReconnect {
			res.Url = response.Params.Link
			res.Ec = SUCCESS
			log.Debug("IG_Enter_Game Login SUCCESS",zap.String("Url", res.Url))
			return
		}
		//2.上分
		if ig_request(Ig_aboutMoney_addr, addMoney, &response){
			res.Url = response.Params.Link
			res.Ec = SUCCESS
			log.Debug("IG_Enter_Game addMoney SUCCESS", zap.String("Url", res.Url))
		}else{
			res.Ec = SYS_DEPOSIT_FAILED
			log.Debug("IG_Enter_Game addMoney FAILED")
		}
	} else {
		res.Ec = SYS_LOGIN_FAILED
		log.Debug("IG_Enter_Game Login FAILED")
	}
}

//平台金币换算成至尊娱乐
func IG_convertBalance(balance int64) float64 {
	return float64(balance) / 100
}

func IG_Leave_Game(guid string, p_b *pb.S_Ntf_UserBalance, p_r *pb.S_LeaveGame){

	//p_r.Ec = SUCCESS
	//p_b.Balance = 10000
	//return
	wd_money, ok:= IG_withdraw(guid)
	if ok {
		p_r.Ec = SUCCESS
		p_b.Balance = wd_money
	}else{
		p_r.Ec = SYS_WITHDRAW_FAILED
	}
}

func IG_query_balance(guid string)(b bool, balance string){
	var balance_ ig_balance_header
	params2 := ig_balance{guid,Md5Encrypt(guid)}
	q_balance := &ig_post_header{Ig_key,GET_BALANCE_COMMAND,params2}
	//1.获取余额
	if ig_query_balance(Ig_aboutMoney_addr, q_balance, &balance_){
		return true, balance_.Params.Balance
	}else{
		return false, ""
	}
}

func IG_withdraw(guid string) (balance int64, b bool){

	var response ig_response_header
	//1.获取余额
	ok,balance_ := IG_query_balance(guid)
	if ok {
		balance_int,err := strconv.ParseFloat(balance_,64)
		if err != nil {
			log.Debug("IG_withdraw strconv.ParseFloat err",zap.Error(err))
			return 0,false
		}
		if balance_int == 0 {
			log.Info("IG_withdraw 玩家输光",zap.String("guid",guid))
			return 0 ,true
		}

		ref := GetFormatDate() + guid
		params3 := ig_deductMoney{guid,Md5Encrypt(guid),ref,balance_}
		balance_req := &ig_post_header{Ig_key,WITHDRAW_COMMAND,params3}
		//2.下分
		if ig_request(Ig_aboutMoney_addr, balance_req, &response){
			newba,err := strconv.ParseFloat(balance_,64)
			if err != nil{
				log.Debug("IG_withdraw strconv.ParseFloat FAILED", zap.Error(err))
			}
			backMoeny := ig_ConvertBalanceToPlatform(newba)
			log.Info("IG_withdraw 取款 SUCCESS",zap.String("guid", guid),zap.Int64("Balance", backMoeny))
			return backMoeny,true
		}else{
			log.Debug("IG_withdraw 取款 FAILED")
			return 0,false
		}

	}else{
		log.Debug("IG_withdraw 查询余额 FAILED")
		return 0,false
	}
}
func ig_ConvertBalanceToPlatform(balance float64) int64 {
	return decimal.NewFromFloat(balance).Mul(decimal.NewFromFloat(100)).IntPart()
}

func ig_request(url string, param interface{}, header *ig_response_header) bool {

	bytesData, err := json.Marshal(param)
	if err != nil {
		log.Debug("igdz_request json.Marshal", zap.Error(err))
		return false
	}

	reader := bytes.NewReader(bytesData)
	log.Debug(url)
	log.Debug("ig_request 请求", zap.String("data", string(bytesData)))

	req, err := http.NewRequest("POST", url, reader)
	if err != nil {
		log.Error("igdz_request http.NewRequest", zap.Error(err))
		return false
	}

	tr := &http.Transport{
		TLSClientConfig: &tls.Config{
			InsecureSkipVerify: true,
		},
	}

	client := &http.Client{Transport: tr}
	req.Header.Set("Content-Type", "application/json")
	resp, err := client.Do(req)
	if err != nil {
		log.Error("igdz_request client.Do", zap.Error(err))
		return false
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Error("igdz_request ioutil.ReadAll", zap.Error(err))
		return false
	}

	if err := json.Unmarshal(body, header); err != nil {
		log.Debug(err.Error())
		return false
	}

	log.Debug("igdz_request 响应", zap.String("data", string(body)))
	if header.ErrorCode == 0{
		return true
	}

	return false
}

func ig_query_balance(url string, param interface{}, header *ig_balance_header) bool {

	bytesData, err := json.Marshal(param)
	if err != nil {
		log.Debug("igdz_request json.Marshal", zap.Error(err))
		return false
	}

	reader := bytes.NewReader(bytesData)

	log.Debug("请求参数: ", zap.String("url",url),zap.String("data", string(bytesData)))
	req, err := http.NewRequest("POST", url, reader)
	if err != nil {
		log.Error("igdz_request http.NewRequest", zap.Error(err))
		return false
	}

	tr := &http.Transport{
		TLSClientConfig: &tls.Config{
			InsecureSkipVerify: true,
		},
	}

	client := &http.Client{Transport: tr}
	req.Header.Set("Content-Type", "application/json")
	resp, err := client.Do(req)
	if err != nil {
		log.Error("igdz_request client.Do", zap.Error(err))
		return false
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Error("igdz_request ioutil.ReadAll", zap.Error(err))
		return false
	}

	if err := json.Unmarshal(body, header); err != nil {
		log.Debug(err.Error())
		return false
	}

	log.Debug("IG 响应", zap.String("data", string(body)))
	if header.ErrorCode == 0{
		return true
	}

	return false
}

//强制关端  下分、发送离开游戏事件
func IG_Cronjob(guid uint64, gameId int64) bool {
	s_guid := strconv.FormatUint(guid,10)
	var response ig_response_header
	var balance_ ig_balance_header
	params2 := ig_balance{s_guid,Md5Encrypt(s_guid)}
	q_balance := &ig_post_header{Ig_key,GET_BALANCE_COMMAND,params2}
	//1.获取余额
	if ig_query_balance(Ig_aboutMoney_addr, q_balance, &balance_){
		ref := GetFormatDate() + s_guid
		params3 := ig_deductMoney{s_guid,Md5Encrypt(s_guid),ref,balance_.Params.Balance}
		balance_req := &ig_post_header{Ig_key,WITHDRAW_COMMAND,params3}
		//2.下分
		if ig_request(Ig_aboutMoney_addr, balance_req, &response){
			newba,err := strconv.ParseFloat(balance_.Params.Balance,64)
			if err != nil{
				log.Debug("IG_Cronjob strconv.ParseFloat FAILED", zap.Error(err))
			}
			balance := ig_ConvertBalanceToPlatform(newba)
			//3.给用户加金币
			log.Debug("IG_Cronjob redis update balance", zap.Int64("balance", balance))
			new_balance, err := mod.AddUserBalance(guid, balance)
			log.Debug("IG_Cronjob new balance", zap.Int64("new_balance", new_balance))
			if err != nil {
				log.Error("IG_Cronjob falild", zap.Error(err), zap.Uint64("guid", guid), zap.Int64("balance", balance))
			}
			if new_balance >= 0 {
				//4, 断开游戏连接3分钟以后就不走断线重连,下分成功直接进大厅
				if err := mod.UpdateUserAttr(guid, "regameinfo", ""); err != nil {
					log.Error("IG_Cronjob clean regameinfo err,please check", zap.Uint64("guid", guid))
				}
			}
			//5.通知后台更新玩家金币变更
			Nats_Ntf_Balance(guid, gameId, strconv.FormatInt(new_balance, 10), false)
			log.Debug("IG_Cronjob withdraw success", zap.Uint64("guid", guid))
			return true
		}else{

			log.Debug("IG_Cronjob withdraw FAILED")
			return false
		}

	}else{
		log.Debug("IG_Cronjob query balance FAILED")
		return false
	}

}
