package util

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

func HttpRequest(url, method string,
	header, params map[string]string,
	body interface{}) (*http.Request, error) {
	var bodyReader io.Reader
	if body != nil {
		bodyBytes, err := json.Marshal(body)
		if err != nil {
			return nil, err
		}

		bodyReader = bytes.NewReader(bodyBytes)
	}

	req, err := http.NewRequest(method, url, bodyReader)
	if err != nil {
		return nil, err
	}

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

	if len(params) != 0 {
		q := req.URL.Query()
		for k, v := range params {
			q.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
	}

	switch d := obj.(type) {
	case *string:
		*d = string(bodyBytes)
	default:
		err = json.Unmarshal(bodyBytes, obj)
		if err != nil {
			log.Println("Do() error resp = ", 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)
	}
}
