package requestUtil

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"log"
	"net/http"
	"strconv"
	"strings"
	"time"
	_type "xianyv/type"
	"xianyv/utils/md5Util"
)

// MakeAPIRequest 通用API请求函数
func MakeAPIRequest(appId int, appSecret, domain, path string, requestData interface{}) ([]byte, error) {
	// json格式化
	bytesData, err := json.Marshal(requestData)
	if err != nil {
		return nil, fmt.Errorf("JSON序列化错误: %v", err)
	}
	// 发起请求时的时间戳（秒）
	timestamp := time.Now().Unix()
	// 获取签名
	sign := md5Util.GenSign(appId, appSecret, timestamp, bytesData)

	fmt.Printf("sign: %v \n", sign)
	// 请求url
	url := fmt.Sprintf("%v%v?appid=%v&timestamp=%v&sign=%v", domain, path, appId, timestamp, sign)
	fmt.Printf("请求url: %v \n", url)
	// 发起请求，使用带超时的 client 并限制可读取的响应大小，防止对端返回过大内容导致 OOM
	client := &http.Client{Timeout: 30 * time.Second}

	resp, err := client.Post(url, "application/json", bytes.NewReader(bytesData))
	if err != nil {
		req := _type.ErrResponse{
			Code: 0,
			Msg:  fmt.Errorf("HTTP请求错误: %v", err).Error(),
			Data: nil,
		}
		response, _ := json.Marshal(req)
		return response, err
	}
	fmt.Printf("响应: %v \n", resp)
	defer resp.Body.Close()

	// 限制最大可读响应大小，例如 10MB（视实际需求调整）
	const maxRespBytes = 10 * 1024 * 1024 // 10MB
	limitedReader := io.LimitReader(resp.Body, maxRespBytes+1)

	body, err := io.ReadAll(limitedReader)
	if err != nil {
		req := _type.ErrResponse{
			Code: 0,
			Msg:  fmt.Errorf("读取响应错误: %v", err).Error(),
			Data: nil,
		}
		response, _ := json.Marshal(req)
		return response, err
	}

	// 如果响应超过限制，返回错误
	if int64(len(body)) > 10*1024*1024 {
		req := _type.ErrResponse{
			Code: 0,
			Msg:  fmt.Errorf("响应大小超过限制: %d bytes", len(body)).Error(),
			Data: nil,
		}
		response, _ := json.Marshal(req)
		return response, fmt.Errorf("response too large: %d bytes", len(body))
	}

	return body, nil
}

// RequestParams 解析请求参数
func RequestParams(r *http.Request) (_type.Body, error) {
	var body _type.Body
	var err error

	// 转换各个字段
	appIdStr := r.FormValue("appId")
	body.AppSecret = r.FormValue("appSecret")
	body.OuterId = r.FormValue("token")
	body.Token = r.FormValue("token")
	apiShopIdStr := r.FormValue("apiShopId")
	typePlatformStr := r.FormValue("typePlatform")
	shopIdStr := r.FormValue("shopId")
	body.ShopToken = r.FormValue("shopToken")
	body.ShopName = r.FormValue("shopName")
	provinceStr := r.FormValue("province")
	cityStr := r.FormValue("city")
	districtStr := r.FormValue("district")
	body.TypeClass = r.FormValue("typeClass")
	body.TypeGoods = r.FormValue("typeGoods")
	body.CatIds = r.FormValue("catIds")
	shopStr := r.FormValue("shop[]")
	stuffStatusStr := r.FormValue("stuffStatus")
	bookDataStr := r.FormValue("bookData[]")
	body.ItemKey = r.FormValue("itemKey")
	body.OuterId = r.FormValue("outerId")

	// 转换数值参数
	body.AppId, _ = strconv.Atoi(appIdStr)
	body.ApiShopId, _ = strconv.Atoi(apiShopIdStr)
	body.TypePlatform, _ = strconv.Atoi(typePlatformStr)
	body.ShopId, _ = strconv.Atoi(shopIdStr)
	if i, err := strconv.ParseInt(provinceStr, 10, 32); err == nil {
		body.Province = int32(i)
	} else {
		body.Province = 0
	}
	if i, err := strconv.ParseInt(cityStr, 10, 32); err == nil {
		body.City = int32(i)
	} else {
		body.City = 0
	}
	if i, err := strconv.ParseInt(districtStr, 10, 32); err == nil {
		body.District = int32(i)
	} else {
		body.District = 0
	}
	body.StuffStatus, _ = strconv.Atoi(stuffStatusStr)

	// shop非空校验,修复字符编码问题
	if shopStr != "" {

		// 清理可能的非法字符
		shopStr = strings.TrimSpace(shopStr)
		shopStr = strings.Trim(shopStr, `"'`)

		// 移除BOM标记
		if strings.HasPrefix(shopStr, "\uFEFF") {
			shopStr = strings.TrimPrefix(shopStr, "\uFEFF")
		}

		err = json.Unmarshal([]byte(shopStr), &body.Shop)
		if err != nil {
			log.Printf("JSON格式错误，Shop: %v", err)
			log.Printf("错误数据内容: %s", shopStr)
			return body, fmt.Errorf("JSON格式错误，Shop: %v", err)
		}
	} else {
		log.Println("Shop不应为空")
		return body, errors.New("Shop不应为空")
	}

	// bookData非空校验,修复字符编码问题
	if bookDataStr != "" {

		bookDataStr = strings.TrimSpace(bookDataStr)
		bookDataStr = strings.Trim(bookDataStr, `"'`)

		if strings.HasPrefix(bookDataStr, "\uFEFF") {
			bookDataStr = strings.TrimPrefix(bookDataStr, "\uFEFF")
		}

		err = json.Unmarshal([]byte(bookDataStr), &body.BookData)
		if err != nil {
			log.Printf("JSON格式错误，解析bookData: %v", err)
			return body, fmt.Errorf("JSON格式错误，解析bookData: %v", err)
		}
	} else {
		log.Printf("bookData不应为空")
		return body, errors.New("bookData不应为空")
	}

	return body, err
}
