package wechat

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"sundynix-go/global"

	"go.uber.org/zap"
)

// WeChatCommonResponse 微信通用响应
type WeChatCommonResponse struct {
	Errcode int    `json:"errcode"`
	Errmsg  string `json:"errmsg"`
}

// MsgSecCheckDetail 文本检测结果详情
type MsgSecCheckDetail struct {
	Strategy string `json:"strategy"`
	Errcode  int    `json:"errcode"`
	Suggest  string `json:"suggest"`
	Label    int    `json:"label"`
	Prob     int    `json:"prob"`
}

// MsgSecCheckResult 文本检测结果
type MsgSecCheckResult struct {
	Suggest string `json:"suggest"`
	Label   int    `json:"label"`
}

// MsgSecCheckResponse 文本检测响应
type MsgSecCheckResponse struct {
	WeChatCommonResponse
	Result MsgSecCheckResult   `json:"result"`
	Detail []MsgSecCheckDetail `json:"detail"`
}

// MediaCheckAsyncResponse 媒体检测异步响应
type MediaCheckAsyncResponse struct {
	WeChatCommonResponse
	TraceId string `json:"trace_id"`
}

// MsgSecCheck 文本内容安全识别
// content: 需检测的文本内容
// openid: 用户的openid（用户需在近两小时访问过小程序）
// return: true-通过, false-不通过
func MsgSecCheck(content string, openid string) bool {
	// 2024-05-15: 微信api调整
	// https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/sec-center/sec-check/msgSecCheck.html
	accessToken := GetMiniAccessToken()
	url := "https://api.weixin.qq.com/wxa/msg_sec_check?access_token=" + accessToken

	payload := map[string]interface{}{
		"version": 2,
		"openid":  openid,
		"scene":   2, // 2-资料说明
		"content": content,
	}

	jsonData, err := json.Marshal(payload)
	if err != nil {
		global.Logger.Error("MsgSecCheck json marshal error", zap.Error(err))
		return false
	}

	resp, err := http.Post(url, "application/json", bytes.NewBuffer(jsonData))
	if err != nil {
		global.Logger.Error("MsgSecCheck http post error", zap.Error(err))
		return false
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		global.Logger.Error("MsgSecCheck read body error", zap.Error(err))
		return false
	}

	var response MsgSecCheckResponse
	if err := json.Unmarshal(body, &response); err != nil {
		global.Logger.Error("MsgSecCheck json unmarshal error", zap.Error(err))
		return false
	}

	if response.Errcode != 0 {
		global.Logger.Error("MsgSecCheck api error", zap.Int("errcode", response.Errcode), zap.String("errmsg", response.Errmsg))
		return false
	}

	// 检查 result.suggest
	if response.Result.Suggest == "pass" {
		return true
	}

	global.Logger.Warn("MsgSecCheck risky content",
		zap.String("content", content),
		zap.String("suggest", response.Result.Suggest),
		zap.Int("label", response.Result.Label),
	)
	return false
}

// MediaCheckAsync 多媒体内容安全识别（异步）
// mediaUrl: 需检测的多媒体url
// mediaType: 1:音频; 2:图片
// openid: 用户的openid
// return: trace_id, error
func MediaCheckAsync(mediaUrl string, mediaType int, openid string) (string, error) {
	accessToken := GetMiniAccessToken()
	url := "https://api.weixin.qq.com/wxa/media_check_async?access_token=" + accessToken

	payload := map[string]interface{}{
		"media_url":  mediaUrl,
		"media_type": mediaType,
		"version":    2,
		"openid":     openid,
		"scene":      2,
	}

	jsonData, err := json.Marshal(payload)
	if err != nil {
		return "", err
	}

	resp, err := http.Post(url, "application/json", bytes.NewBuffer(jsonData))
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}

	var response MediaCheckAsyncResponse
	if err := json.Unmarshal(body, &response); err != nil {
		return "", err
	}

	if response.Errcode != 0 {
		global.Logger.Error("MediaCheckAsync api error", zap.Int("errcode", response.Errcode), zap.String("errmsg", response.Errmsg))
		return "", fmt.Errorf("errcode: %d, errmsg: %s", response.Errcode, response.Errmsg)
	}

	if response.TraceId != "" {
		return response.TraceId, nil
	}

	return "", fmt.Errorf("no trace_id returned")
}
