package weixin

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/spf13/cast"
	"github.com/tidwall/gjson"
	"io"
	"net/http"
)

type MpSdk struct {
	BaseSdk
}

func NewMpSdk(appid, secret string) *MpSdk {
	return &MpSdk{
		BaseSdk{
			appid:  appid,
			secret: secret,
		},
	}
}

func (o *MpSdk) GetUserInfoByJsCode(code string) (*UserInfo, error) {
	url := fmt.Sprintf("%s?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code",
		jscode2SessionUrl, o.appid, o.secret, code)
	res, err := http.Get(url)
	if err != nil {
		return nil, err
	}
	defer res.Body.Close()
	body, err := io.ReadAll(res.Body)
	if err != nil {
		return nil, err
	}
	userInfo := new(UserInfo)

	g := gjson.ParseBytes(body)
	userInfo.Openid = g.Get("openid").String()
	userInfo.Unionid = g.Get("unionid").String()
	return userInfo, nil
}

func (o *MpSdk) GetPhone(code string) (string, error) {
	accessToken, err := o.getAccessToken()
	if err != nil {
		return "", err
	}
	reqUrl := fmt.Sprintf("%s?access_token=%s", userPhoneNumberUrl, accessToken)
	res, err := http.Post(reqUrl, "application/json", bytes.NewBuffer([]byte(fmt.Sprintf(`{"code":"%s"}`, code))))
	if err != nil {
		return "", err
	}
	defer res.Body.Close()
	body, err := io.ReadAll(res.Body)
	if err != nil {
		return "", err
	}

	g := gjson.ParseBytes(body)
	errcode := g.Get("errcode").Int()
	if errcode != 0 {
		return "", fmt.Errorf("%d:%s", errcode, g.Get("errmsg"))
	}

	return g.Get("phone_info.phoneNumber").String(), nil
}

func (o *MpSdk) GetUnlimitedQRCode(params map[string]interface{}) ([]byte, error) {
	if _, ok := params["scene"]; !ok {
		return nil, errors.New("scene参数缺失")
	}

	if _, ok := params["width"]; !ok {
		params["width"] = 280
	}
	if _, ok := params["env_version"]; !ok {
		params["env_version"] = "release"
	}
	if _, ok := params["check_path"]; !ok {
		params["check_path"] = false
	}
	if _, ok := params["page"]; !ok {
		params["page"] = "pages/index/index"
	}

	marshal, _ := json.Marshal(params)
	accessToken, err := o.getAccessToken()
	if err != nil {
		return nil, err
	}
	url := fmt.Sprintf("%s?access_token=%s", getWxACodeUnLimitUrl, accessToken)
	res, _ := http.Post(url, "application/json", bytes.NewBuffer(marshal))
	body, err := io.ReadAll(res.Body)
	defer res.Body.Close()

	if err != nil {
		return nil, err
	}
	mp := make(map[string]interface{})
	err = json.Unmarshal(body, &mp)
	if err == nil {
		return nil, fmt.Errorf("%d:%s", cast.ToInt64(mp["errcode"]), cast.ToString(mp["errmsg"]))
	}

	return body, nil
}