package wechat

import (
	"encoding/json"
	"fmt"
	"net/http"

	"bindbox-game/internal/pkg/httpclient"
)

// SchemeRequest 获取小程序 Scheme 码请求参数
type SchemeRequest struct {
	JumpWxa        JumpWxa `json:"jump_wxa,omitempty"`
	IsExpire       bool    `json:"is_expire,omitempty"`       // false：永久有效，true：到期失效
	ExpireTime     int64   `json:"expire_time,omitempty"`     // 到期失效的 scheme 码的失效时间，为 Unix 时间戳
	ExpireType     int     `json:"expire_type,omitempty"`     // 失效时间类型，0-失效时间，1-失效间隔天数
	ExpireInterval int     `json:"expire_interval,omitempty"` // 失效间隔天数
}

type JumpWxa struct {
	Path       string `json:"path"`
	Query      string `json:"query"`
	EnvVersion string `json:"env_version,omitempty"` // release, trial, develop
}

// SchemeResponse 获取小程序 Scheme 码响应
type SchemeResponse struct {
	OpenLink string `json:"openlink"`
	ErrCode  int    `json:"errcode"`
	ErrMsg   string `json:"errmsg"`
}

// GenerateScheme 获取小程序 Scheme 码
// path: 页面路径，如 "pages/index/index"
// query: 参数，如 "id=1" (可为空)
// envVersion: 要打开的小程序版本，默认 release
func GenerateScheme(accessToken string, path string, query string, envVersion string) (string, error) {
	if accessToken == "" {
		return "", fmt.Errorf("access_token 不能为空")
	}

	url := fmt.Sprintf("https://api.weixin.qq.com/wxa/generatescheme?access_token=%s", accessToken)

	if envVersion == "" {
		envVersion = "release"
	}

	reqBody := SchemeRequest{
		JumpWxa: JumpWxa{
			Path:       path,
			Query:      query,
			EnvVersion: envVersion,
		},
		IsExpire: false, // 默认生成永久有效的（注意：永久有效每天有上限，短期有效无上限但需设置过期）
		// 如果需要生成短期，可以改为 true 并设置 ExpireInterval/ExpireTime
	}

	// 强制使用短期有效以避免消耗额度（如果需要）？
	// 官方文档：永久有效 Scheme 每天上限 50w，短期无上限。
	// 为了稳健，默认使用短期（30天）？或者让调用者决定。
	// 这里先简单实现为默认短期（30天），避免额度问题。
	reqBody.IsExpire = true
	reqBody.ExpireType = 1
	reqBody.ExpireInterval = 30

	requestBody, err := json.Marshal(reqBody)
	if err != nil {
		return "", fmt.Errorf("序列化请求参数失败: %v", err)
	}

	resp, err := httpclient.GetHttpClient().R().
		SetHeader("Content-Type", "application/json").
		SetBody(requestBody).
		Post(url)

	if err != nil {
		return "", fmt.Errorf("发送HTTP请求失败: %v", err)
	}

	if resp.StatusCode() != http.StatusOK {
		return "", fmt.Errorf("HTTP请求失败，状态码: %d", resp.StatusCode())
	}

	var sResp SchemeResponse
	if err := json.Unmarshal(resp.Body(), &sResp); err != nil {
		return "", fmt.Errorf("解析响应失败: %v", err)
	}

	if sResp.ErrCode != 0 {
		return "", fmt.Errorf("获取Scheme失败: errcode=%d, errmsg=%s", sResp.ErrCode, sResp.ErrMsg)
	}

	return sResp.OpenLink, nil
}
