package lxhttp

import (
	"bytes"
	"crypto/tls"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/http/cookiejar"
	"net/url"
	"strings"
	"time"

	login_js "git.listensoft.net/tool/jspkit/common/login-js"
	"git.listensoft.net/tool/jspkit/logger"
	"git.listensoft.net/tool/jspkit/taxerr"
	"github.com/tidwall/gjson"
	"go.uber.org/zap"
	"golang.org/x/net/publicsuffix"
)

// PostByteReader PostReader 不规则参数 直接传字符串
func PostByteReader(client *http.Client, uri string, bytesData []byte, headers map[string]string, Cookies []*http.Cookie) ([]byte, error) {
	f := 0
	var ck []*http.Cookie
beggin:
	if len(ck) != 0 {
		Cookies = append(Cookies, ck...)
	}
	request, err := http.NewRequest("POST", uri, bytes.NewReader(bytesData))
	if err != nil {
		return nil, err
	}
	if strings.Contains(uri, "mhzx/api/mh/mhsy/getUserInfo") {
		request, err = http.NewRequest("GET", uri, bytes.NewReader(bytesData))
		if err != nil {
			return nil, err
		}
	}
	request.Header.Add("Content-Type", "application/json")
	request.Header.Add("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_0_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36")
	for k, v := range headers {
		request.Header.Set(k, v)
	}
	// 瑞数加密
	for _, v := range Cookies {
		request.AddCookie(v)
	}
	resp, err := client.Do(request)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	if !strings.Contains(uri, "api/login") {
		if resp.StatusCode == 412 && f < 3 && NeedRsvmpAPi(uri) {
			ck, uri = Rsvmp(uri)
			f++
			goto beggin
		}
		if resp.StatusCode != 200 {
			logger.Info("resp", zap.String("uri", uri), zap.Int("code", resp.StatusCode))
			body1, _ := io.ReadAll(resp.Body)
			return body1, taxerr.NewWebStuckTitle(true)
		}
	}
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	if strings.Contains(resp.Header.Get(`Content-Encoding`), "gzip") {
		return GZIPDecode(body)
	}
	if strings.Contains(string(body), "目前暂不支持查看该申报表的申报明细") {
		return nil, taxerr.NewSystemV3("税局提示:目前暂不支持查看该申报表的申报明细", "请核实")
	}
	if strings.Contains(uri, "pdf") || strings.Contains(uri, "download") || strings.Contains(uri, "Pdf") || strings.Contains(uri, "exportSbmxxqcx") || strings.Contains(uri, `previewPdfData`) || strings.Contains(uri, "DescribeSbmxxqcx") {
		logger.Info("xx", zap.String("uri", uri), zap.Int("pdf字节changed", len(body)))
	} else {
		logger.Info("xx", zap.String("uri", uri), zap.Int("body", len(body)))
	}
	return body, nil
}

func NewHttpClientForNoRedirects(proxy, auth string) (client *http.Client) {
	// 禁止重定向
	client = &http.Client{
		CheckRedirect: func(req *http.Request, via []*http.Request) error {
			// 返回错误以阻止重定向
			return http.ErrUseLastResponse
		},
		Timeout: 10 * time.Second,
	}
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, //忽略证书校验
	}
	if proxy != "" {
		u, _ := url.Parse(proxy)
		tr.Proxy = http.ProxyURL(u)
	}
	if auth != "" {
		tr.ProxyConnectHeader = http.Header{
			"Proxy-Authorization": []string{"Basic " + base64.StdEncoding.EncodeToString([]byte(auth))},
		}
	}
	client.Transport = tr
	options := cookiejar.Options{
		PublicSuffixList: publicsuffix.List,
	}
	curCookieJar, _ := cookiejar.New(&options)
	client.Jar = curCookieJar
	return
}

func AutoHttp(client *http.Client, uri string, Method string, bytesData []byte, headers map[string]string) (body []byte, err error) {
	var Cookies []*http.Cookie
	for range "..." {
		request, err := http.NewRequest(Method, uri, bytes.NewReader(bytesData))
		if err != nil {
			continue
		}
		for k, v := range headers {
			request.Header.Add(k, v)
		}
		// 瑞数加密
		for _, v := range Cookies {
			request.AddCookie(v)
		}
		resp, err := client.Do(request)
		if err != nil {
			continue
		}
		if resp.StatusCode == 412 {
			logger.Info("需要瑞数加密了：", zap.Int("code", resp.StatusCode))
			Cookies, _ = Rsvmp(uri)
			logger.Info("加密完成")
			logger.Info("ck", zap.Any("ck", Cookies))
			continue
		}
		defer resp.Body.Close()
		body, err = io.ReadAll(resp.Body)
		if err != nil {
			continue
		}
		break
	}
	return
}

func Get_etax_clientId_redirectUri(C *http.Client, Api string, fuc func(url string) (ck []*http.Cookie, uri string)) map[string]any {
	Location := ""
	f := 0
begin:
	var ck []*http.Cookie
	ck, Api = fuc(Api)
	if len(ck) != 0 {
		u, _ := url.Parse(Api)
		C.Jar.SetCookies(u, ck)
	}
	// 创建一个新的 HTTP 请求
	req, err := http.NewRequest("GET", Api, nil)
	if err != nil {
		fmt.Println("Error creating request:", err)

	}
	req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36")
	req.Header.Set("Accept", "application/json, text/plain, */*")
	if strings.Contains(Api, "invoice-query/invoice-query") {
		req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7")
		req.Header.Set("Accept-Encoding", "gzip, deflate, br, zstd")
		req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9")
		//req.Header.Set("Referer", "https://etax.hebei.chinatax.gov.cn:8443/")
		//req.Header.Set("Host", "dppt.hebei.chinatax.gov.cn:8443")
	}
	nn := 0
n:
	// 发送请求
	resp, err := C.Do(req)
	if err != nil {
		logger.Info("Error sending request:" + err.Error())
		if nn < 6 {
			nn++
			goto n
		}
		return nil
	}
	defer resp.Body.Close()
	body, _ := io.ReadAll(resp.Body)
	fmt.Println(string(body))
	Location = resp.Header.Get(`Location`)
	fmt.Println("Location:", Location)
	if Location == "" {
		return nil
	}
	if f == 0 {
		Api = Location
		f++
		goto begin
	}
	res := login_js.Js("clientId", Location)
	return res.(map[string]any)
}

func VerifyLogin(c *http.Client, area, BaseIndex string, client_id, redirect_uri, new_key16 string, header map[string]string, fuc func(url string) (ck []*http.Cookie, uri string)) string {
	var jsonAny []byte
	var err error
	uri := fmt.Sprintf("https://tpass.%s.chinatax.gov.cn:8443/sys-api/v1.0/auth/user/verifyLogin", area)
	ck, _ := fuc(uri)
	if len(ck) > 0 {
		u, _ := url.Parse(uri)
		c.Jar.SetCookies(u, ck)
	}
	n := map[string]any{
		"data": map[string]string{
			"client_id":    client_id,
			"redirect_uri": redirect_uri,
		},
		"url":    "/auth/user/verifyLogin",
		"method": "post",
	}
	param_datas := login_js.Js("signature", n, new_key16)
	for range ".........." {
		jsonAny, err = POSTJsonAny(c, uri, param_datas, header)
		if err != nil {
			continue
		} else {
			break
		}
	}
	/// {"code" : 1000,"msg" : "处理成功！","zipCode" : "0","encryptCode" : "2","datagram" : "610695f2eb65a0eb961cf80c3a69f9777b8282c41fbecf238500d3c670fb8d5298fdcd4929f62c6c601d1a4c07563073","signtype" : "HMacSHA256", "signature" : "8B0CF4EE45C7FF0398BDB0D3946D91960E26017448DC91BE928256DC417307E8","timestamp" : "20241004114508","requestId" : "f551b69773a75535"}
	var jsonAny2 map[string]any
	json.Unmarshal([]byte(jsonAny), &jsonAny2)
	responseJson := login_js.Js("responseParse", jsonAny2, new_key16)
	//{"code":"","datagram":"{\"code\":\"3D384374310C458E8DFF9B979E3D8FFB\"}","encryptCode":"2","msg":"处理成功！","requestId":"86ba5db97beff424","signature":"DE3ECA4D94F8C293CDB1695E5648904CACCABCBF998AD2F6188DF2988F67F4D9","signtype":"HMacSHA256","timestamp":"20241004120553","zipCode":"0"}
	responseJson2 := responseJson.(map[string]any)
	return gjson.Get(responseJson2["datagram"].(string), "code").String()
}
