package api

import (
	"fmt"
	"git.notitek.com.tr/common/notgo/napi"
	"git.notitek.com.tr/common/notgo/nauth"
	"net/http"
	"os"
	"path"
	"path/filepath"
	"strings"

	"git.makki.io/makki/libgo/enums"
	"git.makki.io/makki/libgo/svc"
	"github.com/go-chi/chi/v5"
	"github.com/go-chi/chi/v5/middleware"
	"github.com/go-chi/cors"
	"github.com/go-chi/jwtauth/v5"
)

func HttpHandler(re enums.TRunEnv) http.Handler {
	mux := chi.NewRouter()

	// Gerekli middleware stack
	mux.Use(middleware.RequestID)
	mux.Use(middleware.RealIP)
	mux.Use(middleware.Logger)

	// Eğer trace middleware'ı kullanırsak buna gerek kalmayacak sanırım kontrol etmeli
	// https://github.com/go-chi/httptracer
	mux.Use(middleware.Recoverer)
	acors := cors.New(cors.Options{
		// AllowedOrigins: []string{"https://foo.com"}, // Use this to allow specific origin hosts
		AllowedOrigins: []string{"*"},
		// AllowOriginFunc:  func(r *http.Request, origin string) bool { return true },
		AllowedMethods:   []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
		AllowedHeaders:   []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token"},
		ExposedHeaders:   []string{"Link"},
		AllowCredentials: true,
		MaxAge:           300, // Maximum value not ignored by any of major browsers
	})

	mux.Use(acors.Handler)

	// Set a timeout value on the request context (ctx), that will signal
	// through ctx.Done() that the request has timed out and further
	// processing should be stopped.
	// todo: bu belki endpoint bazında özelleştirlebilinir...
	// mux.Use(middleware.Timeout(2500 * time.Millisecond))

	mux.Route("/api", func(mr chi.Router) {
		// Public Route endpoints
		mr.Post("/login", napi.Login)

		//protected end points
		mr.Group(func(r chi.Router) {
			// Seek, verify and validate JWT tokens
			r.Use(jwtauth.Verifier(svc.S.JWT))

			// Handle valid / invalid tokens.
			r.Use(nauth.CheckTokenValidity)

			// sy routes
			r.Get("/sy/companies", napi.CompanyList)

			// company routes
			r.Get("/company/{id:[0-9]+}", companyGet)
			r.Get("/company", companyList)
			r.Put("/company", companyUpdate)
			r.Post("/company", companyCreate)
			r.Delete("/company/{id:[0-9]+}", companyDelete)

			r.Post("/tmpl/{companyID:[0-9]+}", tmplPost)
			r.Get("/tmpl/{companyID:[0-9]+}", tmplGet)

		})
	})

	// Handle Websocket
	// mux.HandleFunc("/ws", ws.Handle)

	// SPA Routes
	mux.Group(func(r chi.Router) {
		r.NotFound(index)
		r.Get("/", index)
	})

	return mux
}

func index(w http.ResponseWriter, r *http.Request) {
	p := r.URL.Path
	if !strings.HasPrefix(p, "/") {
		p = "/" + p
		r.URL.Path = p
	}
	p = path.Clean(p)

	if strings.HasPrefix(p, "/api") {
		http.NotFound(w, r)
		return
	}

	uiPath := "./ui"
	if svc.S.RunEnv() == enums.RunEnvLocal {
		uiPath = "../../ui/dist/spa"
	}

	name := path.Join(uiPath, filepath.FromSlash(p))

	f, err := os.Open(name)
	if err != nil {
		if os.IsNotExist(err) {
			http.ServeFile(w, r, fmt.Sprintf("%s/index.html", uiPath))
			return
		}
	}
	defer f.Close()
	http.ServeFile(w, r, name)
}
