package platformPay

import (
	"crypto/tls"
	"errors"
	"fmt"
	"net"
	"net/http"
	"os"
	"strconv"
	"time"

	"github.com/nahid/gohttp"
)

type ResponseAccessToken struct {
	Data struct {
		AccessToken string `json:"access_token"`
		ExpiresIn   int64  `json:"expired_at"`
	} `json:"data"`
	ErrCode int    `json:"code"`
	ErrMsg  string `json:"msg"`
}

const WxPlat int = 1
const DyPlat int = 2

func GetAdminPlatform() int {
	adminPlatform := os.Getenv("ADMIN_PLATFORM")
	switch adminPlatform {
	case "wechat":
		return WxPlat
	case "dy":
		return DyPlat
	default:
		return WxPlat
	}
}

func NewHttpRequest() *gohttp.Request {
	tr := &http.Transport{
		TLSClientConfig:   &tls.Config{InsecureSkipVerify: true},
		DisableKeepAlives: true,
		Dial: func(netw, addr string) (net.Conn, error) {
			deadline := time.Now().Add(10 * time.Second)
			c, err := net.DialTimeout(netw, addr, time.Second*1)
			if err != nil {
				return nil, err
			}
			c.SetDeadline(deadline)
			return c, nil
		},
	}

	a1 := gohttp.SetTransport(tr)
	req := gohttp.NewRequest(a1)
	return req
}

func QueryBalanceAndCheck(plat int, openid string) (*ResponseGetBalance, error) {
	if plat == int(WxPlat) {
		return WxQueryBalanceAndCheck(openid)
	} else if plat == int(DyPlat) {
		return DyQueryBalanceAndCheck(openid)
	}
	return nil, fmt.Errorf("not plat %v", plat)
}

func PayAndCheck(platform int, openid string, billNo string, amt int) (*ResponsePay, error) {

	if platform == int(WxPlat) {
		return WxPayAndCheck(openid, billNo, amt)
	} else if platform == DyPlat {
		return DyPayAndCheck(openid, billNo, amt)
	}
	return nil, errors.New("未知平台")
}

func QueryAccessToken(plat int, oldExpired int64) (token string, expired int64, err error) {

	req := NewHttpRequest()

	requestData := make(map[string]string)
	requestData["epr"] = strconv.FormatInt(oldExpired, 10)

	var url string
	if plat == int(WxPlat) {
		url = "https://gravepay.mg.xhgame.com/wx/queryAccessToken/"
	} else if plat == int(DyPlat) {
		url = "https://gravedypay.mg.xhgame.com/dy/queryAccessToken/"
	} else {
		//err = fmt.Errorf("not plat %v", plat)
		return "", 0, fmt.Errorf("not plat %v", plat)
	}

	resp, err := req.Query(requestData).Get(url)
	if err != nil {
		return "", 0, err
	}
	defer func() {
		if resp.GetBody() != nil {
			resp.GetBody().Close()
		}
	}()

	rt := new(ResponseAccessToken)
	err = resp.UnmarshalBody(rt)
	if err != nil {
		return "", 0, err
	}
	if len(rt.Data.AccessToken) == 0 || rt.Data.ExpiresIn == 0 {
		return "", 0, errors.New("no found AccessToken")
	}
	token = rt.Data.AccessToken
	expired = rt.Data.ExpiresIn
	return
}
