package routers

import (
	"fmt"
	"net/http"
	"path"

	"github.com/go-chi/chi/v5"
	api "github.com/tech/sendico/pkg/api/http"
	"github.com/tech/sendico/pkg/mservice"
	"github.com/tech/sendico/server/interface/api/sresponse"
	"go.uber.org/zap"
)

func (er *HttpEndpointRouter) chooseMethod(method api.HTTPMethod) RegistratorT {
	switch method {
	case api.Get:
		return func(r chi.Router, p string, h http.HandlerFunc) { r.Get(p, h) }
	case api.Post:
		return func(r chi.Router, p string, h http.HandlerFunc) { r.Post(p, h) }
	case api.Put:
		return func(r chi.Router, p string, h http.HandlerFunc) { r.Put(p, h) }
	case api.Delete:
		return func(r chi.Router, p string, h http.HandlerFunc) { r.Delete(p, h) }
	case api.Patch:
		return func(r chi.Router, p string, h http.HandlerFunc) { r.Patch(p, h) }
	case api.Options:
		return func(r chi.Router, p string, h http.HandlerFunc) { r.Options(p, h) }
	case api.Head:
		return func(r chi.Router, p string, h http.HandlerFunc) { r.Head(p, h) }
	default:
	}
	er.logger.Error("Unknown method provided", zap.String("method", api.HTTPMethod2String(method)))
	panic(fmt.Sprintf("Unknown method provided: %d", method))
}

func (er *HttpEndpointRouter) endpoint(service mservice.Type, handler string) string {
	return path.Join(er.apiEndpoint, service, handler)
}

func (er *HttpEndpointRouter) InstallHandler(service mservice.Type, endpoint string, method api.HTTPMethod, handler sresponse.HandlerFunc) {
	ep := er.endpoint(service, endpoint)
	hm := er.chooseMethod(method)
	hndlr := func(w http.ResponseWriter, r *http.Request) {
		res := handler(r)
		res(w, r)
	}
	hm(er.router, ep, hndlr)
	er.logger.Info("Handler installed", zap.String("endpoint", ep), zap.String("method", api.HTTPMethod2String(method)))
}
