package http

import (
	"context"
	"fmt"
	"net/http"

	"go.uber.org/zap"

	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/config"
	httpmw "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/http/middleware"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/interface/http/handler/admin"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/interface/http/handler/gateway"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/interface/http/handler/healthcheck"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/interface/http/handler/plugin"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/interface/http/handler/site"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/interface/http/handler/tenant"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/interface/http/handler/user"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/interface/http/middleware"
)

// Server represents the HTTP server
type Server struct {
	server                    *http.Server
	logger                    *zap.Logger
	jwtMiddleware             *httpmw.JWTMiddleware
	apikeyMiddleware          *httpmw.APIKeyMiddleware
	rateLimitMiddlewares      *httpmw.RateLimitMiddlewares // CWE-770: Registration and auth endpoints rate limiting
	securityHeadersMiddleware *httpmw.SecurityHeadersMiddleware
	requestSizeLimitMw        *httpmw.RequestSizeLimitMiddleware
	config                    *config.Config
	healthHandler             *healthcheck.Handler
	registerHandler           *gateway.RegisterHandler
	loginHandler              *gateway.LoginHandler
	refreshTokenHandler       *gateway.RefreshTokenHandler
	helloHandler              *gateway.HelloHandler
	meHandler                 *gateway.MeHandler
	createTenantHandler       *tenant.CreateHandler
	getTenantHandler          *tenant.GetHandler
	createUserHandler         *user.CreateHandler
	getUserHandler            *user.GetHandler
	createSiteHandler         *site.CreateHandler
	getSiteHandler            *site.GetHandler
	listSitesHandler          *site.ListHandler
	deleteSiteHandler         *site.DeleteHandler
	rotateSiteAPIKeyHandler   *site.RotateAPIKeyHandler
	verifySiteHandler         *site.VerifySiteHandler
	pluginStatusHandler       *plugin.StatusHandler
	pluginVerifyHandler       *plugin.PluginVerifyHandler
	pluginVersionHandler      *plugin.VersionHandler
	syncPagesHandler          *plugin.SyncPagesHandler
	searchPagesHandler        *plugin.SearchPagesHandler
	deletePagesHandler        *plugin.DeletePagesHandler
	syncStatusHandler         *plugin.SyncStatusHandler
	unlockAccountHandler      *admin.UnlockAccountHandler
	accountStatusHandler      *admin.AccountStatusHandler
}

// ProvideServer creates a new HTTP server
func ProvideServer(
	cfg *config.Config,
	logger *zap.Logger,
	jwtMiddleware *httpmw.JWTMiddleware,
	apikeyMiddleware *httpmw.APIKeyMiddleware,
	rateLimitMiddlewares *httpmw.RateLimitMiddlewares,
	securityHeadersMiddleware *httpmw.SecurityHeadersMiddleware,
	requestSizeLimitMw *httpmw.RequestSizeLimitMiddleware,
	healthHandler *healthcheck.Handler,
	registerHandler *gateway.RegisterHandler,
	loginHandler *gateway.LoginHandler,
	refreshTokenHandler *gateway.RefreshTokenHandler,
	helloHandler *gateway.HelloHandler,
	meHandler *gateway.MeHandler,
	createTenantHandler *tenant.CreateHandler,
	getTenantHandler *tenant.GetHandler,
	createUserHandler *user.CreateHandler,
	getUserHandler *user.GetHandler,
	createSiteHandler *site.CreateHandler,
	getSiteHandler *site.GetHandler,
	listSitesHandler *site.ListHandler,
	deleteSiteHandler *site.DeleteHandler,
	rotateSiteAPIKeyHandler *site.RotateAPIKeyHandler,
	verifySiteHandler *site.VerifySiteHandler,
	pluginStatusHandler *plugin.StatusHandler,
	pluginVerifyHandler *plugin.PluginVerifyHandler,
	pluginVersionHandler *plugin.VersionHandler,
	syncPagesHandler *plugin.SyncPagesHandler,
	searchPagesHandler *plugin.SearchPagesHandler,
	deletePagesHandler *plugin.DeletePagesHandler,
	syncStatusHandler *plugin.SyncStatusHandler,
	unlockAccountHandler *admin.UnlockAccountHandler,
	accountStatusHandler *admin.AccountStatusHandler,
) *Server {
	mux := http.NewServeMux()

	s := &Server{
		logger:                    logger,
		jwtMiddleware:             jwtMiddleware,
		apikeyMiddleware:          apikeyMiddleware,
		rateLimitMiddlewares:      rateLimitMiddlewares,
		securityHeadersMiddleware: securityHeadersMiddleware,
		requestSizeLimitMw:        requestSizeLimitMw,
		config:                    cfg,
		healthHandler:             healthHandler,
		registerHandler:           registerHandler,
		loginHandler:              loginHandler,
		refreshTokenHandler:       refreshTokenHandler,
		helloHandler:              helloHandler,
		meHandler:                 meHandler,
		createTenantHandler:       createTenantHandler,
		getTenantHandler:          getTenantHandler,
		createUserHandler:         createUserHandler,
		getUserHandler:            getUserHandler,
		createSiteHandler:         createSiteHandler,
		getSiteHandler:            getSiteHandler,
		listSitesHandler:          listSitesHandler,
		deleteSiteHandler:         deleteSiteHandler,
		rotateSiteAPIKeyHandler:   rotateSiteAPIKeyHandler,
		verifySiteHandler:         verifySiteHandler,
		pluginStatusHandler:       pluginStatusHandler,
		pluginVerifyHandler:       pluginVerifyHandler,
		pluginVersionHandler:      pluginVersionHandler,
		syncPagesHandler:          syncPagesHandler,
		searchPagesHandler:        searchPagesHandler,
		deletePagesHandler:        deletePagesHandler,
		syncStatusHandler:         syncStatusHandler,
		unlockAccountHandler:      unlockAccountHandler,
		accountStatusHandler:      accountStatusHandler,
	}

	// Register routes
	s.registerRoutes(mux)

	// Create HTTP server
	// CWE-770: Configure timeouts to prevent resource exhaustion
	s.server = &http.Server{
		Addr:         fmt.Sprintf("%s:%d", cfg.Server.Host, cfg.Server.Port),
		Handler:      s.applyMiddleware(mux),
		ReadTimeout:  cfg.HTTP.ReadTimeout,
		WriteTimeout: cfg.HTTP.WriteTimeout,
		IdleTimeout:  cfg.HTTP.IdleTimeout,
	}

	logger.Info("✓ HTTP server configured",
		zap.String("address", s.server.Addr),
		zap.Duration("read_timeout", cfg.HTTP.ReadTimeout),
		zap.Duration("write_timeout", cfg.HTTP.WriteTimeout),
		zap.Int64("max_body_size", cfg.HTTP.MaxRequestBodySize))

	return s
}

// registerRoutes registers all HTTP routes
func (s *Server) registerRoutes(mux *http.ServeMux) {
	// ===== PUBLIC ROUTES (No authentication, no tenant) =====
	// Health check
	mux.HandleFunc("GET /health", s.healthHandler.Handle)

	// Version endpoint - public API for checking backend version
	mux.HandleFunc("GET /api/v1/version", s.pluginVersionHandler.Handle)

	// Public gateway routes (registration, login, etc.)
	// CWE-770: Apply request size limits and rate limiting
	// Apply small size limit (1MB) for registration/login endpoints
	if s.config.RateLimit.RegistrationEnabled {
		mux.HandleFunc("POST /api/v1/register",
			s.requestSizeLimitMw.LimitSmall()(
				http.HandlerFunc(s.applyRegistrationRateLimit(s.registerHandler.Handle)),
			).ServeHTTP)
	} else {
		mux.HandleFunc("POST /api/v1/register",
			s.requestSizeLimitMw.LimitSmall()(
				http.HandlerFunc(s.registerHandler.Handle),
			).ServeHTTP)
	}
	mux.HandleFunc("POST /api/v1/login",
		s.requestSizeLimitMw.LimitSmall()(
			http.HandlerFunc(s.loginHandler.Handle),
		).ServeHTTP)
	mux.HandleFunc("POST /api/v1/refresh",
		s.requestSizeLimitMw.LimitSmall()(
			http.HandlerFunc(s.refreshTokenHandler.Handle),
		).ServeHTTP)

	// ===== AUTHENTICATED ROUTES (JWT only, no tenant context) =====
	// Gateway routes
	// CWE-770: Apply small size limit (1MB) and generic rate limiting for hello endpoint
	if s.config.RateLimit.GenericEnabled {
		mux.HandleFunc("POST /api/v1/hello",
			s.requestSizeLimitMw.LimitSmall()(
				http.HandlerFunc(s.applyAuthOnlyWithGenericRateLimit(s.helloHandler.Handle)),
			).ServeHTTP)
	} else {
		mux.HandleFunc("POST /api/v1/hello",
			s.requestSizeLimitMw.LimitSmall()(
				http.HandlerFunc(s.applyAuthOnly(s.helloHandler.Handle)),
			).ServeHTTP)
	}

	// CWE-770: Apply generic rate limiting to /me endpoint to prevent profile enumeration and DoS
	if s.config.RateLimit.GenericEnabled {
		mux.HandleFunc("GET /api/v1/me",
			s.applyAuthOnlyWithGenericRateLimit(s.meHandler.Handle))
	} else {
		mux.HandleFunc("GET /api/v1/me", s.applyAuthOnly(s.meHandler.Handle))
	}

	// Tenant management routes - these operate at system/admin level
	// CWE-770: Apply small size limit (1MB) and generic rate limiting for tenant creation
	if s.config.RateLimit.GenericEnabled {
		mux.HandleFunc("POST /api/v1/tenants",
			s.requestSizeLimitMw.LimitSmall()(
				http.HandlerFunc(s.applyAuthOnlyWithGenericRateLimit(s.createTenantHandler.Handle)),
			).ServeHTTP)
		mux.HandleFunc("GET /api/v1/tenants/{id}", s.applyAuthOnlyWithGenericRateLimit(s.getTenantHandler.HandleByID))
		mux.HandleFunc("GET /api/v1/tenants/slug/{slug}", s.applyAuthOnlyWithGenericRateLimit(s.getTenantHandler.HandleBySlug))
	} else {
		mux.HandleFunc("POST /api/v1/tenants",
			s.requestSizeLimitMw.LimitSmall()(
				http.HandlerFunc(s.applyAuthOnly(s.createTenantHandler.Handle)),
			).ServeHTTP)
		mux.HandleFunc("GET /api/v1/tenants/{id}", s.applyAuthOnly(s.getTenantHandler.HandleByID))
		mux.HandleFunc("GET /api/v1/tenants/slug/{slug}", s.applyAuthOnly(s.getTenantHandler.HandleBySlug))
	}

	// ===== TENANT-SCOPED ROUTES (JWT + Tenant context) =====
	// User routes - these operate within a tenant context
	// CWE-770: Apply small size limit (1MB) and generic rate limiting for user creation
	if s.config.RateLimit.GenericEnabled {
		mux.HandleFunc("POST /api/v1/users",
			s.requestSizeLimitMw.LimitSmall()(
				http.HandlerFunc(s.applyAuthAndTenantWithGenericRateLimit(s.createUserHandler.Handle)),
			).ServeHTTP)
		mux.HandleFunc("GET /api/v1/users/{id}", s.applyAuthAndTenantWithGenericRateLimit(s.getUserHandler.Handle))
	} else {
		mux.HandleFunc("POST /api/v1/users",
			s.requestSizeLimitMw.LimitSmall()(
				http.HandlerFunc(s.applyAuthAndTenant(s.createUserHandler.Handle)),
			).ServeHTTP)
		mux.HandleFunc("GET /api/v1/users/{id}", s.applyAuthAndTenant(s.getUserHandler.Handle))
	}

	// Site management routes - JWT authenticated, tenant-scoped
	// CWE-770: Apply small size limit (1MB) and generic rate limiting for site management
	if s.config.RateLimit.GenericEnabled {
		mux.HandleFunc("POST /api/v1/sites",
			s.requestSizeLimitMw.LimitSmall()(
				http.HandlerFunc(s.applyAuthAndTenantWithGenericRateLimit(s.createSiteHandler.Handle)),
			).ServeHTTP)
		mux.HandleFunc("GET /api/v1/sites", s.applyAuthAndTenantWithGenericRateLimit(s.listSitesHandler.Handle))
		mux.HandleFunc("GET /api/v1/sites/{id}", s.applyAuthAndTenantWithGenericRateLimit(s.getSiteHandler.Handle))
		mux.HandleFunc("DELETE /api/v1/sites/{id}", s.applyAuthAndTenantWithGenericRateLimit(s.deleteSiteHandler.Handle))
		mux.HandleFunc("POST /api/v1/sites/{id}/rotate-api-key",
			s.requestSizeLimitMw.LimitSmall()(
				http.HandlerFunc(s.applyAuthAndTenantWithGenericRateLimit(s.rotateSiteAPIKeyHandler.Handle)),
			).ServeHTTP)
		mux.HandleFunc("POST /api/v1/sites/{id}/verify",
			s.requestSizeLimitMw.LimitSmall()(
				http.HandlerFunc(s.applyAuthAndTenantWithGenericRateLimit(s.verifySiteHandler.Handle)),
			).ServeHTTP)
	} else {
		mux.HandleFunc("POST /api/v1/sites",
			s.requestSizeLimitMw.LimitSmall()(
				http.HandlerFunc(s.applyAuthAndTenant(s.createSiteHandler.Handle)),
			).ServeHTTP)
		mux.HandleFunc("GET /api/v1/sites", s.applyAuthAndTenant(s.listSitesHandler.Handle))
		mux.HandleFunc("GET /api/v1/sites/{id}", s.applyAuthAndTenant(s.getSiteHandler.Handle))
		mux.HandleFunc("DELETE /api/v1/sites/{id}", s.applyAuthAndTenant(s.deleteSiteHandler.Handle))
		mux.HandleFunc("POST /api/v1/sites/{id}/rotate-api-key",
			s.requestSizeLimitMw.LimitSmall()(
				http.HandlerFunc(s.applyAuthAndTenant(s.rotateSiteAPIKeyHandler.Handle)),
			).ServeHTTP)
		mux.HandleFunc("POST /api/v1/sites/{id}/verify",
			s.requestSizeLimitMw.LimitSmall()(
				http.HandlerFunc(s.applyAuthAndTenant(s.verifySiteHandler.Handle)),
			).ServeHTTP)
	}

	// ===== ADMIN ROUTES (JWT authenticated) =====
	// CWE-307: Admin endpoints for account lockout management
	// CWE-770: Apply small size limit (1MB) and generic rate limiting for admin endpoints
	if s.config.RateLimit.GenericEnabled {
		mux.HandleFunc("POST /api/v1/admin/unlock-account",
			s.requestSizeLimitMw.LimitSmall()(
				http.HandlerFunc(s.applyAuthOnlyWithGenericRateLimit(s.unlockAccountHandler.Handle)),
			).ServeHTTP)
		mux.HandleFunc("GET /api/v1/admin/account-status", s.applyAuthOnlyWithGenericRateLimit(s.accountStatusHandler.Handle))
	} else {
		mux.HandleFunc("POST /api/v1/admin/unlock-account",
			s.requestSizeLimitMw.LimitSmall()(
				http.HandlerFunc(s.applyAuthOnly(s.unlockAccountHandler.Handle)),
			).ServeHTTP)
		mux.HandleFunc("GET /api/v1/admin/account-status", s.applyAuthOnly(s.accountStatusHandler.Handle))
	}

	// ===== WORDPRESS PLUGIN API ROUTES (API Key authentication) =====
	// CWE-770: Apply lenient site-based rate limiting to protect core business endpoints
	// Default: 1000 requests/hour per site (very lenient for high-volume legitimate traffic)

	if s.config.RateLimit.PluginAPIEnabled {
		// Plugin status/verification - with rate limiting
		mux.HandleFunc("GET /api/v1/plugin/status", s.applyAPIKeyAuthWithPluginRateLimit(s.pluginStatusHandler.Handle))

		// Plugin domain verification endpoint
		mux.HandleFunc("POST /api/v1/plugin/verify",
			s.requestSizeLimitMw.LimitSmall()(
				http.HandlerFunc(s.applyAPIKeyAuthWithPluginRateLimit(s.pluginVerifyHandler.Handle)),
			).ServeHTTP)

		// Page sync and search routes
		// CWE-770: Apply larger size limit (50MB) for page sync (bulk operations) + rate limiting
		mux.HandleFunc("POST /api/v1/plugin/pages/sync",
			s.requestSizeLimitMw.LimitLarge()(
				http.HandlerFunc(s.applyAPIKeyAuthWithPluginRateLimit(s.syncPagesHandler.Handle)),
			).ServeHTTP)
		// Apply medium limit (5MB) for search and delete operations + rate limiting
		mux.HandleFunc("POST /api/v1/plugin/pages/search",
			s.requestSizeLimitMw.LimitMedium()(
				http.HandlerFunc(s.applyAPIKeyAuthWithPluginRateLimit(s.searchPagesHandler.Handle)),
			).ServeHTTP)
		mux.HandleFunc("DELETE /api/v1/plugin/pages",
			s.requestSizeLimitMw.LimitMedium()(
				http.HandlerFunc(s.applyAPIKeyAuthWithPluginRateLimit(s.deletePagesHandler.Handle)),
			).ServeHTTP)
		mux.HandleFunc("DELETE /api/v1/plugin/pages/all", s.applyAPIKeyAuthWithPluginRateLimit(s.deletePagesHandler.HandleDeleteAll))
		mux.HandleFunc("GET /api/v1/plugin/pages/status", s.applyAPIKeyAuthWithPluginRateLimit(s.syncStatusHandler.Handle))
		mux.HandleFunc("GET /api/v1/plugin/pages/{page_id}", s.applyAPIKeyAuthWithPluginRateLimit(s.syncStatusHandler.HandleGetPageDetails))
	} else {
		// Plugin endpoints without rate limiting (not recommended for production)
		mux.HandleFunc("GET /api/v1/plugin/status", s.applyAPIKeyAuth(s.pluginStatusHandler.Handle))

		// Plugin domain verification endpoint
		mux.HandleFunc("POST /api/v1/plugin/verify",
			s.requestSizeLimitMw.LimitSmall()(
				http.HandlerFunc(s.applyAPIKeyAuth(s.pluginVerifyHandler.Handle)),
			).ServeHTTP)

		mux.HandleFunc("POST /api/v1/plugin/pages/sync",
			s.requestSizeLimitMw.LimitLarge()(
				http.HandlerFunc(s.applyAPIKeyAuth(s.syncPagesHandler.Handle)),
			).ServeHTTP)
		mux.HandleFunc("POST /api/v1/plugin/pages/search",
			s.requestSizeLimitMw.LimitMedium()(
				http.HandlerFunc(s.applyAPIKeyAuth(s.searchPagesHandler.Handle)),
			).ServeHTTP)
		mux.HandleFunc("DELETE /api/v1/plugin/pages",
			s.requestSizeLimitMw.LimitMedium()(
				http.HandlerFunc(s.applyAPIKeyAuth(s.deletePagesHandler.Handle)),
			).ServeHTTP)
		mux.HandleFunc("DELETE /api/v1/plugin/pages/all", s.applyAPIKeyAuth(s.deletePagesHandler.HandleDeleteAll))
		mux.HandleFunc("GET /api/v1/plugin/pages/status", s.applyAPIKeyAuth(s.syncStatusHandler.Handle))
		mux.HandleFunc("GET /api/v1/plugin/pages/{page_id}", s.applyAPIKeyAuth(s.syncStatusHandler.HandleGetPageDetails))
	}
}

// applyMiddleware applies global middleware to all routes
func (s *Server) applyMiddleware(handler http.Handler) http.Handler {
	// Apply middleware in order (innermost to outermost)
	// 1. Logger middleware (logging)
	// 2. Security headers middleware (CWE-693: Protection Mechanism Failure)
	handler = middleware.LoggerMiddleware(s.logger)(handler)
	handler = s.securityHeadersMiddleware.Handler(handler)
	return handler
}

// applyAuthOnly applies only JWT authentication middleware (no tenant)
func (s *Server) applyAuthOnly(handler http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		// Chain: JWT validation -> Auth check -> Handler
		s.jwtMiddleware.Handler(
			s.jwtMiddleware.RequireAuth(
				http.HandlerFunc(handler),
			),
		).ServeHTTP(w, r)
	}
}

// applyAuthOnlyWithGenericRateLimit applies JWT authentication + generic rate limiting (CWE-770)
// Used for authenticated CRUD endpoints (tenant/user/site management, admin, /me, /hello)
// Applies user-based rate limiting (extracted from JWT context)
func (s *Server) applyAuthOnlyWithGenericRateLimit(handler http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		// Chain: JWT validation -> Auth check -> Generic rate limit (user-based) -> Handler
		s.jwtMiddleware.Handler(
			s.jwtMiddleware.RequireAuth(
				s.rateLimitMiddlewares.Generic.HandlerWithUserKey(
					http.HandlerFunc(handler),
				),
			),
		).ServeHTTP(w, r)
	}
}

// applyAuthAndTenant applies JWT authentication + tenant middleware
func (s *Server) applyAuthAndTenant(handler http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		// Chain: JWT validation -> Auth check -> Tenant -> Handler
		s.jwtMiddleware.Handler(
			s.jwtMiddleware.RequireAuth(
				middleware.TenantMiddleware()(
					http.HandlerFunc(handler),
				),
			),
		).ServeHTTP(w, r)
	}
}

// applyAuthAndTenantWithGenericRateLimit applies JWT authentication + tenant + generic rate limiting (CWE-770)
// Used for tenant-scoped CRUD endpoints (user/site management)
// Applies user-based rate limiting (extracted from JWT context)
func (s *Server) applyAuthAndTenantWithGenericRateLimit(handler http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		// Chain: JWT validation -> Auth check -> Tenant -> Generic rate limit (user-based) -> Handler
		s.jwtMiddleware.Handler(
			s.jwtMiddleware.RequireAuth(
				middleware.TenantMiddleware()(
					s.rateLimitMiddlewares.Generic.HandlerWithUserKey(
						http.HandlerFunc(handler),
					),
				),
			),
		).ServeHTTP(w, r)
	}
}

// applyAPIKeyAuth applies API key authentication middleware (for WordPress plugin)
func (s *Server) applyAPIKeyAuth(handler http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		// Chain: API key validation -> Require API key -> Handler
		s.apikeyMiddleware.Handler(
			s.apikeyMiddleware.RequireAPIKey(
				http.HandlerFunc(handler),
			),
		).ServeHTTP(w, r)
	}
}

// applyAPIKeyAuthWithPluginRateLimit applies API key authentication + plugin API rate limiting (CWE-770)
// Used for WordPress Plugin API endpoints (core business endpoints)
// Applies site-based rate limiting (extracted from API key context)
func (s *Server) applyAPIKeyAuthWithPluginRateLimit(handler http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		// Chain: API key validation -> Require API key -> Plugin rate limit (site-based) -> Handler
		s.apikeyMiddleware.Handler(
			s.apikeyMiddleware.RequireAPIKey(
				s.rateLimitMiddlewares.PluginAPI.HandlerWithSiteKey(
					http.HandlerFunc(handler),
				),
			),
		).ServeHTTP(w, r)
	}
}

// applyRegistrationRateLimit applies rate limiting middleware for registration (CWE-770)
func (s *Server) applyRegistrationRateLimit(handler http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		// Chain: Rate limit check -> Handler
		s.rateLimitMiddlewares.Registration.Handler(
			http.HandlerFunc(handler),
		).ServeHTTP(w, r)
	}
}

// Start starts the HTTP server
func (s *Server) Start() error {
	s.logger.Info("")
	s.logger.Info("🚀 MaplePress Backend is ready!")
	s.logger.Info("",
		zap.String("address", s.server.Addr),
		zap.String("url", fmt.Sprintf("http://localhost:%s", s.server.Addr[len(s.server.Addr)-4:])))
	s.logger.Info("")

	if err := s.server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
		return fmt.Errorf("failed to start server: %w", err)
	}

	return nil
}

// Shutdown gracefully shuts down the HTTP server
func (s *Server) Shutdown(ctx context.Context) error {
	s.logger.Info("shutting down HTTP server")

	if err := s.server.Shutdown(ctx); err != nil {
		return fmt.Errorf("failed to shutdown server: %w", err)
	}

	s.logger.Info("HTTP server shut down successfully")
	return nil
}
