package proxy

import (
	"log"
	"net/http"
	"net/http/httputil"
	"net/url"
	"strings"

	"github.com/gorilla/mux"
	"github.com/zeevdiukman/zprox/internal/auth"
	"github.com/zeevdiukman/zprox/internal/config"
)

//	func reverseProxypHandler(config *Config, epmr map[string]*mux.Router, rp *httputil.ReverseProxy, data *Router) func(string, string) http.HandlerFunc {
//		return func(service string, prefix string) http.HandlerFunc {
//			return Matcher(config, epmr, data, rp, service)
//		}
//	}
func ReverseProxypHandler(epr *mux.Router, rp *httputil.ReverseProxy, routerData *config.Router) func(string, string) http.HandlerFunc {
	return func(service string, prefix string) http.HandlerFunc {
		return Matcher(epr, routerData, rp, service)
	}
}

func reWrite(serviceURL string, prefix string, rp *httputil.ReverseProxy, routerData *config.Router) {
	u, err := url.Parse(serviceURL)
	if err != nil {
		log.Println(err.Error())
	}
	rp.Rewrite = func(pr *httputil.ProxyRequest) {
		pr.SetURL(u)

		if routerData.StripPrefix {
			pr.Out.URL.Path = strings.TrimPrefix(pr.Out.URL.Path, prefix)
		}
		// pr.SetXForwarded()
	}
}

func Matcher(epr *mux.Router, routerData *config.Router, rp *httputil.ReverseProxy, serviceURL string) http.HandlerFunc {

	return func(w http.ResponseWriter, r *http.Request) {
		authEnabled := routerData.Auth.Enabled
		match := &mux.RouteMatch{}
		if epr.Match(r, match) {
			matchID := match.Route.GetName()
			pathPrefix := routerData.Routes[matchID].Rule["PathPrefix"]
			route := routerData.GetRouteByID(matchID)
			reWrite(serviceURL, pathPrefix, rp, routerData)

			if authEnabled {
				auth.Middleware(routerData, route.ID, w, r, rp)
			} else {
				rp.ServeHTTP(w, r)
			}
		} else {
			w.WriteHeader(http.StatusNotFound)
		}
	}
}

// func Matcher(epr *mux.Router, routerData *config.Router, rp *httputil.ReverseProxy, serviceURL string) http.HandlerFunc {

// 	return func(w http.ResponseWriter, req *http.Request) {

// 		// if _, ok := config.Data.AuthMap[routerData.Auth.Provider]; ok {
// 		// 	authPrefix := config.Data.AuthMap[routerData.Auth.Provider].Paths.Prefix
// 		// 	if strings.HasPrefix(req.URL.Path, authPrefix) {
// 		// 		dump.P("HasPrefix !")

// 		// 		rp.ServeHTTP(w, req)
// 		// 	}
// 		// 	return
// 		// }
// 		authEnabled := routerData.Auth.Enabled
// 		match := &mux.RouteMatch{}
// 		// dump.P(strings.HasPrefix(req.URL.Path, authPrefix), req.URL.Path, authPrefix)
// 		if epr.Match(req, match) {
// 			matchID := match.Route.GetName()
// 			pathPrefix := routerData.Routes[matchID].Rule["PathPrefix"]

// 			route := routerData.GetRouteByID(matchID)
// 			// IsProtectedRoute := ""
// 			// if v, ok := route.Rule["Auth"]; ok {
// 			// 	IsProtectedRoute = v
// 			// } else {
// 			// 	IsProtectedRoute = "true"
// 			// }
// 			// protected := true
// 			// if !authEnabled {
// 			// 	protected = false
// 			// } else {
// 			// 	if IsProtectedRoute == "false" {
// 			// 		protected = false
// 			// 	}
// 			// 	if IsProtectedRoute == "true" {
// 			// 		protected = true
// 			// 	}
// 			// }
// 			reWrite(serviceURL, pathPrefix, rp, routerData)
// 			dump.P(matchID)

// 			if authEnabled {
// 				// if protected {
// 				// if protected && !strings.HasPrefix(req.URL.Path, "/auth/") {

// 				auth.Middleware(routerData, route.ID)(rp, w, req)

// 			} else {

// 				rp.ServeHTTP(w, req)
// 			}
// 		} else {
// 			w.WriteHeader(http.StatusNotFound)
// 		}
// 	}
// }
