package gameapi

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

var Cq9_token 		= "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyaWQiOiI1ZGMyZTg3ZDNlYjNiMzAwMDEwOGY3MGUiLCJhY2NvdW50Ijoia2d5Iiwib3duZXIiOiI1ZGMyZTg3ZDNlYjNiMzAwMDEwOGY3MGUiLCJwYXJlbnQiOiJzZWxmIiwiY3VycmVuY3kiOiJDTlkiLCJqdGkiOiI4MTc1MjEwNDIiLCJpYXQiOjE1NzMwNTQ1ODksImlzcyI6IkN5cHJlc3MiLCJzdWIiOiJTU1Rva2VuIn0.ItZBsdyQRI_pnFf9Iddw0wOBGXE4uJN8SsXcgNKNO2c"
var Cq9_main_url 	= "http://api.cqgame.games"
const (
	cq9_register_uri 		= "/gameboy/player"				//注册
	cq9_login_uri 	 		= "/gameboy/player/login"		//登陆
	cq9_withdraw_uri		= "/gameboy/player/withdraw"	//取款
	cq9_deposit_uri	 	 	= "/gameboy/player/deposit"		//存款
	cq9_query_balance_uri   = "/gameboy/player/balance/"	//查询余额
	cq9_game_uri			= "/gameboy/player/gamelink"	//获取游戏链接
)

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

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

	if len(gameParam) != 1 {
		res.Ec = SYS_GAME_PARAM_ERROR
		return
	}

	cash_ := convertBalanceToCq9(cash) //1:100
	kindId := gameParam[0]
	log.Info("<<< cq9_Enter_game", zap.String("guid", guid), zap.String("gameId", kindId), zap.Float64("money", cash_))

	//1.注册
	ok, reg_back := CQ9_Request(POST, cq9_register_uri, cq9_loadRegister(guid, Md5Encrypt(guid), guid))
	if !ok {
		res.Ec = SYS_REGIST_FAILED
		log.Info("cq9_Enter_game register faild", zap.String("guid", guid), zap.Any("response", reg_back))
		return
	}
	//2.登陆
	ok, login_back := CQ9_Request(POST, cq9_login_uri, cq9_loadLogin(guid, Md5Encrypt(guid)))
	if !ok {
		res.Ec = SYS_LOGIN_FAILED
		log.Info("cq9_Enter_game login faild", zap.String("guid", guid), zap.Any("response", login_back))
		return
	}
	//3.获取游戏链接
	ok, game_back := CQ9_Request(POST, cq9_game_uri, cq9_gameUrl(login_back.Data.Usertoken,"cq9", kindId ,"mobile","zh-cn","Y","N"))
	if !ok {
		res.Ec = SYS_GAME_URL_FAILED
		log.Info("cq9_Enter_game get gameurl faild", zap.String("guid", guid), zap.Any("response", game_back))
		return
	}

	if isReconnect {
		res.Ec = SUCCESS
		res.Url = game_back.Data.Url
		log.Info("cq9_Enter_game Reconnected  success", zap.String("guid", guid), zap.Any("url", res.Url))
		return
	}
	//4.上分
	mtcode, err:= uuid.NewV4()
	if err != nil{
		res.Ec = SYS_OTHER_ERROR
		log.Debug("cq9_Enter_game uuid.NewV4",zap.Error(err))
		return
	}
	ok, deposit_back := CQ9_Request(POST, cq9_deposit_uri, cq9_deposit(guid , mtcode.String(), cash_))
	if !ok {
		res.Ec = SYS_DEPOSIT_FAILED
		log.Info("cq9_Enter_game deposit faild", zap.String("guid", guid), zap.Any("response", deposit_back))
		return
	}

	res.Ec = SUCCESS
	res.Url = game_back.Data.Url
	log.Info("cq9_Enter_game success", zap.String("guid", guid), zap.Any("url", res.Url))
}

func CQ9_Leave_game(guid string, balance *pb.S_Ntf_UserBalance, res *pb.S_LeaveGame) {

	wd_money,ok := CQ9_withdraw(guid)
	if ok {
		balance.Balance = wd_money
		res.Ec = SUCCESS
	}else {
		res.Ec = SYS_WITHDRAW_FAILED
	}
}

func CQ9_querybalance(guid string)(b bool, balance float64){
	ok, res := CQ9_Request(GET, cq9_query_balance_uri + guid, cq9_queryBalance(guid))
	return ok, res.Data.Balance
}

func CQ9_withdraw(guid string)(balance int64,b bool){
	//1.查询余额
	ok, balance_ := CQ9_querybalance(guid)
	if !ok {
		log.Error("CQ9_withdraw 查询余额 faild", zap.String("guid", guid), zap.Any("response", balance_))
		return 0,false
	}

	if balance_ == 0 { //如果已经输光了 就不用下分了
		log.Info("CQ9_withdraw 玩家输光", zap.String("guid", guid))
		return 0,true
	}
	//2.取款
	mtcode, err:= uuid.NewV4()
	if err != nil{
		log.Debug("cq9_Enter_game uuid.NewV4",zap.Error(err))
		return 0,false
	}
	ok, withdraw_back := CQ9_Request(POST, cq9_withdraw_uri, cq9_withdraw(guid, mtcode.String(), balance_))
	if !ok {
		log.Error("CQ9_Leave_game 取款 faild", zap.String("guid", guid))
		return 0,false
	}

	if withdraw_back.Data.Balance == 0{
		backMoney := CQ9_ConvertBalanceToPlatform(balance_)
		log.Info("CQ9_Leave_game 取款 success", zap.String("guid", guid), zap.Int64("balance",backMoney))
		return backMoney,true
	}else{
		log.Info("CQ9_Leave_game 取款 未全部取出", zap.String("guid", guid))
		return 0,false
	}
}
//至尊娱乐换算成平台
func CQ9_ConvertBalanceToPlatform(balance float64) int64 {
	return decimal.NewFromFloat(balance).Mul(decimal.NewFromFloat(100)).IntPart()
}

func CQ9_Request(reqType string,url string ,dst interface{}) (ok bool , back cq9_response){

	var res cq9_response
	log.Debug("CQ9 请求参数",zap.Any("dst",dst))
	formData, err := form.EncodeToString(dst)
	if err != nil {
		return false, res
	}

	req, err := http.NewRequest(reqType, Cq9_main_url + url, strings.NewReader(formData))
	if err != nil{
		log.Debug("CP9_Post http.NewRequest",zap.Error(err))
		return false, res
	}

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

	client := &http.Client{Transport: tr}
	req.Header.Set("Authorization", Cq9_token)
	req.Header.Set("Content-Type","application/x-www-form-urlencoded")
	req.Header.Set("cache-control","no-cache")

	resp,err := client.Do(req)
	defer resp.Body.Close()

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


	if err := json.Unmarshal(body, &res); err != nil{
		log.Debug("CQ9_Post Unmarshal err",zap.Error(err))
		return false, res
	}

	log.Debug("CQ9 响应", zap.Any("res", res), zap.String("body", string(body)))

	if res.Status.Code == "0" || res.Status.Code == "6"  {
		return true, res
	}else{
		return false, res
	}
}

//强制关端  下分、发送离开游戏事件
func CQ9_Cronjob(guid uint64, gameId int64) bool {

	s_guid := strconv.FormatUint(guid,10)
	//1.查询余额
	ok, balance_back := CQ9_Request(GET, cq9_query_balance_uri + s_guid, cq9_queryBalance(s_guid))
	if !ok {
		log.Error("CQ9_Cronjob query balance faild", zap.String("guid", s_guid), zap.Any("response", balance_back))
		return false
	}
	log.Info("balance info", zap.String("guid", s_guid), zap.Any("response", balance_back))
	//2.取款
	if balance_back.Data.Balance > 0 {
		mtcode, err:= uuid.NewV4()
		if err != nil{
			log.Debug("CQ9_Cronjob uuid.NewV4",zap.Error(err))
			return false
		}
		ok, withdraw_back := CQ9_Request(POST, cq9_withdraw_uri, cq9_withdraw(s_guid, mtcode.String() ,balance_back.Data.Balance))
		if !ok {
			log.Error("CQ9_Cronjob withdraw faild", zap.String("guid", s_guid), zap.Any("response", withdraw_back))
			return false
		}
		if withdraw_back.Data.Balance != 0 {
			log.Error("CQ9_Cronjob withdraw faild user not zero", zap.String("guid", s_guid), zap.Any("response", withdraw_back))
			return false
		}
	}

	balance := ConvertBalanceToPlatform(balance_back.Data.Balance)
	//3.给用户加金币
	log.Debug("CQ9_Cronjob redis update balance", zap.Int64("balance", balance))
	new_balance, err := mod.AddUserBalance(guid, balance)
	log.Debug("CQ9_Cronjob new balance", zap.Int64("new_balance", new_balance))
	if err != nil {
		log.Error("CQ9_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("CQ9_Cronjob clean regameinfo err,please check", zap.Uint64("guid", guid))
		}
	}
	//5.通知后台更新玩家金币变更
	Nats_Ntf_Balance(guid, gameId, strconv.FormatInt(new_balance, 10), false)
	log.Debug("CQ9_Cronjob withdraw success", zap.Uint64("guid", guid))
	return true
}

//获取游戏链接
func cq9_gameUrl(usertoken string, gamehall string, gamecode string, gameplat string ,lang string, app string,detect string) interface{}{
	return map[string]interface{}{"usertoken": usertoken,"gamehall":gamehall,"gamecode":gamecode,"gameplat":gameplat,"lang":lang,"app":app,"detect":detect}
}
//查询余额
func cq9_queryBalance(account string) interface{}{
	return map[string]interface{}{"account": account}
}

//取款
func cq9_withdraw(account string, mtcode string, amount float64) interface{}{
	return map[string]interface{}{"account": account, "mtcode": mtcode, "amount":amount}
}

//存款
func cq9_deposit(account string, mtcode string, amount float64) interface{}{
	return map[string]interface{}{"account": account, "mtcode": mtcode, "amount":amount}
}
//装载大厅
func cq9_loadLobby(usertoken string,lang string) interface{} {
	return map[string]interface{}{"usertoken": usertoken, "lang": lang}
}

//装载注册
func cq9_loadRegister(account string,password string,nickname string) interface{} {
	return map[string]interface{}{"account": account, "password": password, "nickname":nickname}
}

//装载登陆
func cq9_loadLogin(account string,password string) interface{} {
	return map[string]interface{}{"account": account, "password": password}
}
