package httpclient

// http request 工具函数
import (
	"crypto/tls"
	"errors"
	"fmt"
	"log"
	"net/url"
	"strings"
	"time"

	"github.com/bytedance/sonic"
	"github.com/valyala/fasthttp"
	"github.com/valyala/fasthttp/fasthttpproxy"
)

var (
	fastHttpClient = &fasthttp.Client{
		Name:                "http",
		MaxConnsPerHost:     10000,
		MaxIdleConnDuration: 30 * time.Second,
		ReadTimeout:         50 * time.Second,
		WriteTimeout:        50 * time.Second,
		TLSConfig:           &tls.Config{InsecureSkipVerify: true},
	}
	socksDialer fasthttp.DialFunc
	proxyUrl    = ""
	proxyScheme = "socks5"
)

func NewHttpRequestWithFasthttp(reqMethod, reqUrl, postData string, headers map[string]string) ([]byte, error) {
	// loghelper.InfoLog("use fasthttp client")
	if len(proxyUrl) > 0 {

		if socksDialer == nil {
			socksDialer = fasthttpproxy.FasthttpSocksDialer(strings.TrimPrefix(proxyUrl, proxyScheme+"://"))
			fastHttpClient.Dial = socksDialer
		}
	}
	req := fasthttp.AcquireRequest()
	resp := fasthttp.AcquireResponse()
	defer func() {
		fasthttp.ReleaseRequest(req)
		fasthttp.ReleaseResponse(resp)
	}()

	for k, v := range headers {
		req.Header.Set(k, v)
	}
	req.Header.SetMethod(reqMethod)
	req.SetRequestURI(reqUrl)
	req.SetBodyString(postData)

	err := fastHttpClient.Do(req, resp)
	if err != nil {
		return nil, err
	}

	if resp.StatusCode() != 200 {
		return nil, errors.New(fmt.Sprintf("HttpStatusCode:%d ,Desc:%s", resp.StatusCode(), string(resp.Body())))
	}
	return resp.Body(), nil
}

func HttpGet(reqUrl string) (map[string]interface{}, error) {
	respData, err := NewHttpRequestWithFasthttp("GET", reqUrl, "", nil)
	if err != nil {
		return nil, err
	}

	var bodyDataMap map[string]interface{}
	err = sonic.Unmarshal(respData, &bodyDataMap)
	if err != nil {
		log.Println(string(respData))
		return nil, err
	}
	return bodyDataMap, nil
}

func HttpGet2(reqUrl string, headers map[string]string) (map[string]interface{}, error) {
	if headers == nil {
		headers = map[string]string{}
	}
	headers["Content-Type"] = "application/x-www-form-urlencoded"
	respData, err := NewHttpRequestWithFasthttp("GET", reqUrl, "", headers)
	if err != nil {
		return nil, err
	}

	var bodyDataMap map[string]interface{}
	err = sonic.Unmarshal(respData, &bodyDataMap)
	if err != nil {
		log.Println("respData", string(respData))
		return nil, err
	}
	return bodyDataMap, nil
}

func HttpGet3(reqUrl string, headers map[string]string) ([]interface{}, error) {
	if headers == nil {
		headers = map[string]string{}
	}
	headers["Content-Type"] = "application/x-www-form-urlencoded"
	respData, err := NewHttpRequestWithFasthttp("GET", reqUrl, "", headers)
	if err != nil {
		return nil, err
	}
	// println(string(respData))
	var bodyDataMap []interface{}
	err = sonic.Unmarshal(respData, &bodyDataMap)
	if err != nil {
		log.Println("respData", string(respData))
		return nil, err
	}
	return bodyDataMap, nil
}

func HttpGet4(reqUrl string, headers map[string]string, result interface{}) error {
	if headers == nil {
		headers = map[string]string{}
	}
	headers["Content-Type"] = "application/x-www-form-urlencoded"
	respData, err := NewHttpRequestWithFasthttp("GET", reqUrl, "", headers)
	if err != nil {
		return err
	}

	err = sonic.Unmarshal(respData, result)
	if err != nil {
		log.Printf("HttpGet4 - jsonhelper.Unmarshal failed : %v, resp %s", err, string(respData))
		return err
	}

	return nil
}

func HttpGet5(reqUrl string, headers map[string]string) ([]byte, error) {
	if headers == nil {
		headers = map[string]string{}
	}
	headers["Content-Type"] = "application/x-www-form-urlencoded"
	respData, err := NewHttpRequestWithFasthttp("GET", reqUrl, "", headers)
	if err != nil {
		return nil, err
	}

	return respData, nil
}

func HttpPostForm(reqUrl string, postData url.Values) ([]byte, error) {
	headers := map[string]string{
		"Content-Type": "application/x-www-form-urlencoded"}
	return NewHttpRequestWithFasthttp("POST", reqUrl, postData.Encode(), headers)
}

func HttpPostForm2(reqUrl string, postData url.Values, headers map[string]string) ([]byte, error) {
	if headers == nil {
		headers = map[string]string{}
	}
	headers["Content-Type"] = "application/x-www-form-urlencoded"
	return NewHttpRequestWithFasthttp("POST", reqUrl, postData.Encode(), headers)
}

func HttpPostForm3(reqUrl string, postData string, headers map[string]string) ([]byte, error) {
	return NewHttpRequestWithFasthttp("POST", reqUrl, postData, headers)
}

func HttpPostForm4(reqUrl string, postData map[string]string, headers map[string]string) ([]byte, error) {
	if headers == nil {
		headers = map[string]string{}
	}
	headers["Content-Type"] = "application/json"
	data, _ := sonic.Marshal(postData)
	return NewHttpRequestWithFasthttp("POST", reqUrl, string(data), headers)
}

func HttpDeleteForm(reqUrl string, postData url.Values, headers map[string]string) ([]byte, error) {
	if headers == nil {
		headers = map[string]string{}
	}
	headers["Content-Type"] = "application/x-www-form-urlencoded"
	return NewHttpRequestWithFasthttp("DELETE", reqUrl, postData.Encode(), headers)
}

func HttpPut(reqUrl string, postData url.Values, headers map[string]string) ([]byte, error) {
	if headers == nil {
		headers = map[string]string{}
	}
	headers["Content-Type"] = "application/x-www-form-urlencoded"
	return NewHttpRequestWithFasthttp("PUT", reqUrl, postData.Encode(), headers)
}
