package http

import (
	"counter/internal/delivery/http/handlers"
	"counter/internal/delivery/http/middleware"
	"counter/internal/infrastructure/config"
	"counter/internal/infrastructure/logging"
	"counter/internal/infrastructure/metrics"
	"counter/internal/infrastructure/security"

	"github.com/gin-contrib/cors"
	"github.com/gin-gonic/gin"
)

// Router sets up all HTTP routes and middleware
type Router struct {
	router         *gin.Engine
	authHandler    *handlers.AuthHandler
	counterHandler *handlers.CounterHandler
	config         *config.Config
	logger         logging.Logger
	metricsService metrics.MetricsService
	jwtService     security.JWTService
}

// NewRouter creates a new router with all dependencies
func NewRouter(
	authHandler *handlers.AuthHandler,
	counterHandler *handlers.CounterHandler,
	cfg *config.Config,
	logger logging.Logger,
	metricsService metrics.MetricsService,
	jwtService security.JWTService,
) *Router {
	// Set Gin mode
	gin.SetMode(cfg.GinMode)

	router := gin.Default()

	return &Router{
		router:         router,
		authHandler:    authHandler,
		counterHandler: counterHandler,
		config:         cfg,
		logger:         logger,
		metricsService: metricsService,
		jwtService:     jwtService,
	}
}

// SetupRoutes configures all routes and middleware
func (r *Router) SetupRoutes() {
	// Configure CORS
	corsConfig := cors.DefaultConfig()
	corsConfig.AllowOrigins = []string{"http://localhost:3000", "http://localhost:5173"} // React dev servers
	corsConfig.AllowMethods = []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"}
	corsConfig.AllowHeaders = []string{"Origin", "Content-Type", "Accept", "Authorization"}
	corsConfig.AllowCredentials = true
	r.router.Use(cors.New(corsConfig))

	// Add middleware
	r.router.Use(middleware.MetricsMiddleware(r.metricsService))
	r.router.Use(middleware.LoggingMiddleware(r.logger, r.config))

	// Health check endpoint
	r.router.GET("/health", func(c *gin.Context) {
		c.JSON(200, gin.H{"status": "ok"})
	})

	// API routes
	api := r.router.Group("/api/v1")
	{
		// Authentication routes
		authGroup := api.Group("/auth")
		{
			authGroup.POST("/register", r.authHandler.Register)
			authGroup.POST("/login", r.authHandler.Login)
			authGroup.GET("/me", middleware.AuthMiddleware(r.jwtService), r.authHandler.GetMe)
		}

		// Counter routes (protected)
		counterGroup := api.Group("/counters")
		counterGroup.Use(middleware.AuthMiddleware(r.jwtService))
		{
			counterGroup.POST("", r.counterHandler.Create)
			counterGroup.GET("", r.counterHandler.List)
			counterGroup.GET("/:id", r.counterHandler.Get)
			counterGroup.PUT("/:id", r.counterHandler.Update)
			counterGroup.DELETE("/:id", r.counterHandler.Delete)
			counterGroup.POST("/:id/increment", r.counterHandler.Increment)
			counterGroup.GET("/:id/entries", r.counterHandler.GetEntries)
			counterGroup.GET("/:id/stats", r.counterHandler.GetStats)
		}
	}

	// Serve static files (React app)
	r.router.Static("/static", "./frontend/build/static")
	r.router.StaticFile("/", "./frontend/build/index.html")
	r.router.NoRoute(func(c *gin.Context) {
		c.File("./frontend/build/index.html")
	})
}

// GetRouter returns the configured Gin router
func (r *Router) GetRouter() *gin.Engine {
	return r.router
}
