package pkg

import (
	"encoding/json"
	"io"
	"log"
	"net/http"
	"net/http/httputil"
	"net/url"
	"reflect"
)

func PostRequest(url string, body io.Reader, header map[string]string) (*http.Request, error) {
	req, err := http.NewRequest(http.MethodPost, url, body)
	if err != nil {
		return nil, err
	}

	for k, v := range header {
		req.Header.Add(k, v)
	}
	return req, err
}

func GetRequest(url string, params map[string]string, body io.Reader, header map[string]string) (*http.Request, error) {
	req, err := http.NewRequest(http.MethodGet, url, body)
	if err != nil {
		return nil, err
	}

	q := req.URL.Query()
	for k, v := range params {
		q.Add(k, v)
	}

	for k, v := range header {
		req.Header.Add(k, v)
	}

	req.URL.RawQuery = q.Encode()
	return req, err
}

func Do(req *http.Request, obj interface{}) error {
	cli := http.DefaultClient
	resp, err := cli.Do(req)
	if err != nil {
		return err
	}

	defer resp.Body.Close()
	bodyBytes, err := io.ReadAll(resp.Body)
	if err != nil {
		return err
	}

	if obj == nil {
		log.Println(string(bodyBytes))
		return nil
	}

	if reflect.TypeOf(obj).Elem().Kind() == reflect.String {
		reflect.ValueOf(obj).Elem().Set(reflect.ValueOf(string(bodyBytes)))
		return nil
	}

	err = json.Unmarshal(bodyBytes, obj)
	if err != nil {
		log.Println("resp body: ", string(bodyBytes))
	}
	return err
}

func ReversProxy(targetHost string) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		proxyUrl, _ := url.Parse(targetHost)
		proxy := httputil.NewSingleHostReverseProxy(proxyUrl)
		r.URL.Host = proxyUrl.Host
		r.Header.Set("X-Forwarded-Host", r.Header.Get("Host"))
		r.Host = proxyUrl.Host
		proxy.ServeHTTP(w, r)
	}
}
