package router

import (
	"net/http"
	"time"

	"github.com/go-chi/chi/v5"
	"github.com/go-chi/chi/v5/middleware"
	"github.com/go-chi/cors"
	"go.uber.org/zap"
	"golang.org/x/time/rate"

	"gitea.miguelmuniz.com/rogueking/junk2jive-server/internal/limiter"
	"gitea.miguelmuniz.com/rogueking/junk2jive-server/internal/logger"
	"gitea.miguelmuniz.com/rogueking/junk2jive-server/internal/ollama"
	"gitea.miguelmuniz.com/rogueking/junk2jive-server/internal/response"
	"gitea.miguelmuniz.com/rogueking/junk2jive-server/internal/roboflow"
)

// Router encapsulates the Chi router and its dependencies
type Router struct {
	router      *chi.Mux
	logger      *zap.Logger
	rateLimiter *limiter.RateLimiter
}

// NewRouter creates and configures a new Router instance
func NewRouter() *Router {
	return &Router{
		router: chi.NewRouter(),
	}
}

func SetupRouter(origins []string) *Router {
	router := chi.NewRouter()

	router.Use(cors.Handler(cors.Options{
		AllowedOrigins:   origins,
		AllowedMethods:   []string{"GET", "POST", "OPTIONS"},
		AllowedHeaders:   []string{"Content-Type", "X-CSRF-Token"},
		AllowCredentials: true,
		MaxAge:           300,
	}))

	zlogger, _ := zap.NewProduction()
	defer zlogger.Sync()

	rl := limiter.New()

	router.Use(middleware.RequestID)
	router.Use(middleware.RealIP)
	router.Use(middleware.Logger)
	router.Use(middleware.Recoverer)
	router.Use(middleware.Timeout(60 * time.Second))

	router.Use(logger.Middleware(zlogger))

	r := Router{
		router:      router,
		logger:      zlogger,
		rateLimiter: rl,
	}

	r.router.Route("/v1/api", func(apiRouter chi.Router) {
		apiRouter.Group(func(subRouter chi.Router) {
			subRouter.Use(r.rateLimiter.Middleware(rate.Every(1*time.Second), 30))

			subRouter.Get("/coffee", func(w http.ResponseWriter, r *http.Request) {
				response.RespondWithJSON(w, http.StatusTeapot, map[string]string{"error": "I'm A Teapot!"})
			})

			subRouter.Post("/text", ollama.OllamaRequest)
			subRouter.Post("/visual", roboflow.HandleImageRequest)
		})
	})
	return &r

}

func (r *Router) GetRouter() *chi.Mux {
	return r.router
}
