package v1

import (
	"api-service/internal/config"
	"api-service/internal/database"
	authHandlers "api-service/internal/handlers/auth"
	healthcheckHandlers "api-service/internal/handlers/healthcheck"
	pesertaHandlers "api-service/internal/handlers/peserta"
	retribusiHandlers "api-service/internal/handlers/retribusi"
	rujukanHandlers "api-service/internal/handlers/rujukan"
	"api-service/internal/middleware"
	services "api-service/internal/services/auth"
	"api-service/pkg/logger"

	"github.com/gin-gonic/gin"
	"github.com/go-playground/validator/v10"
	swaggerFiles "github.com/swaggo/files"
	ginSwagger "github.com/swaggo/gin-swagger"
)

func RegisterRoutes(cfg *config.Config) *gin.Engine {
	router := gin.New()

	// Initialize auth middleware configuration
	middleware.InitializeAuth(cfg)

	// Add global middleware
	router.Use(middleware.CORSConfig())
	router.Use(middleware.ErrorHandler())
	router.Use(logger.RequestLoggerMiddleware(logger.Default()))
	router.Use(gin.Recovery())

	// Initialize services with error handling
	authService := services.NewAuthService(cfg)
	if authService == nil {
		logger.Fatal("Failed to initialize auth service")
	}

	// Initialize database service for health check
	dbService := database.New(cfg)

	// Health check endpoint
	healthCheckHandler := healthcheckHandlers.NewHealthCheckHandler(dbService)
	sistem := router.Group("/api/sistem")
	sistem.GET("/health", healthCheckHandler.CheckHealth)

	// Swagger UI route
	router.GET("/swagger/*any", ginSwagger.WrapHandler(
		swaggerFiles.Handler,                    // Models configuration
		ginSwagger.DefaultModelsExpandDepth(-1), // Hide models completely
		// ginSwagger.DefaultModelExpandDepth(0),   // Keep individual models collapsed

		// General UI configuration
		// ginSwagger.DocExpansion("none"), // Collapse all sections
		ginSwagger.DeepLinking(true), // Enable deep linking
		// ginSwagger.PersistAuthorization(true), // Persist auth between refreshes

		// // Optional: Custom title
		// ginSwagger.InstanceName("API Service v1.0.0"),
	))

	// API v1 group
	v1 := router.Group("/api/v1")

	// =============================================================================
	// PUBLIC ROUTES (No Authentication Required)
	// =============================================================================

	// Authentication routes
	authHandler := authHandlers.NewAuthHandler(authService)
	tokenHandler := authHandlers.NewTokenHandler(authService)

	// Basic auth routes
	v1.POST("/auth/login", authHandler.Login)
	v1.POST("/auth/register", authHandler.Register)
	v1.POST("/auth/refresh", authHandler.RefreshToken)

	// Token generation routes (keep public if needed)
	v1.POST("/token/generate", tokenHandler.GenerateToken)
	v1.POST("/token/generate-direct", tokenHandler.GenerateTokenDirect)

	// ============= PUBLISHED ROUTES ===============================================

	// Participant eligibility information (peserta) routes
	pesertaHandler := pesertaHandlers.NewPesertaHandler(pesertaHandlers.PesertaHandlerConfig{
		BpjsConfig: cfg.Bpjs,
		Logger:     *logger.Default(),
		Validator:  validator.New(),
	})
	pesertaGroup := v1.Group("/peserta")
	pesertaGroup.GET("/Peserta/nokartu/:nokartu", pesertaHandler.GetBynokartu)
	pesertaGroup.GET("/Peserta/nik/:nik", pesertaHandler.GetBynik)

	// Rujukan management endpoints (rujukan) routes
	rujukanHandler := rujukanHandlers.NewRujukanHandler(rujukanHandlers.RujukanHandlerConfig{
		BpjsConfig: cfg.Bpjs,
		Logger:     *logger.Default(),
		Validator:  validator.New(),
	})
	rujukanGroup := v1.Group("/rujukan")
	rujukanGroup.POST("/Rujukan/:norujukan", rujukanHandler.CreateRujukan)
	rujukanGroup.PUT("/Rujukan/:norujukan", rujukanHandler.UpdateRujukan)
	rujukanGroup.DELETE("/Rujukan/:norujukan", rujukanHandler.DeleteRujukan)
	rujukanGroup.POST("/Rujukanbalik/:norujukan", rujukanHandler.CreateRujukanbalik)
	rujukanGroup.PUT("/Rujukanbalik/:norujukan", rujukanHandler.UpdateRujukanbalik)
	rujukanGroup.DELETE("/Rujukanbalik/:norujukan", rujukanHandler.DeleteRujukanbalik)

	// Search for rujukan endpoints (search) routes
	searchHandler := rujukanHandlers.NewSearchHandler(rujukanHandlers.SearchHandlerConfig{
		BpjsConfig: cfg.Bpjs,
		Logger:     *logger.Default(),
		Validator:  validator.New(),
	})
	searchGroup := v1.Group("/search")
	searchGroup.GET("/bynorujukan/:norujukan", searchHandler.GetBynorujukan)
	searchGroup.GET("/bynokartu/:nokartu", searchHandler.GetBynokartu)

	// // Retribusi endpoints
	retribusiHandler := retribusiHandlers.NewRetribusiHandler()
	retribusiGroup := v1.Group("/retribusi")
	{
		retribusiGroup.GET("", retribusiHandler.GetRetribusi)
		retribusiGroup.GET("/dynamic", retribusiHandler.GetRetribusiDynamic)    // Route baru
		retribusiGroup.GET("/search", retribusiHandler.SearchRetribusiAdvanced) // Route pencarian
		retribusiGroup.GET("/id/:id", retribusiHandler.GetRetribusiByID)
		retribusiGroup.POST("", retribusiHandler.CreateRetribusi)
		retribusiGroup.PUT("/id/:id", retribusiHandler.UpdateRetribusi)
		retribusiGroup.DELETE("/id/:id", retribusiHandler.DeleteRetribusi)
	}
	// =============================================================================
	// PROTECTED ROUTES (Authentication Required)
	// =============================================================================

	// Create protected group with configurable authentication
	protected := v1.Group("/")
	protected.Use(middleware.ConfigurableAuthMiddleware(cfg)) // Use configurable authentication

	// User profile (protected)
	// protected.GET("/auth/me", authHandler.Me)

	// // Retribusi endpoints (CRUD operations - should be protected)
	// retribusiHandler := retribusiHandlers.NewRetribusiHandler()
	// protectedRetribusi := protected.Group("/retribusi")
	// {
	// 	protectedRetribusi.GET("", retribusiHandler.GetRetribusi)           // GET /api/v1/retribusi
	// 	protectedRetribusi.GET("/:id", retribusiHandler.GetRetribusiByID)   // GET /api/v1/retribusi/:id
	// 	protectedRetribusi.POST("/", retribusiHandler.CreateRetribusi)      // POST /api/v1/retribusi/
	// 	protectedRetribusi.PUT("/:id", retribusiHandler.UpdateRetribusi)    // PUT /api/v1/retribusi/:id
	// 	protectedRetribusi.DELETE("/:id", retribusiHandler.DeleteRetribusi) // DELETE /api/v1/retribusi/:id
	// }

	// // BPJS VClaim endpoints (require authentication)
	// // Peserta routes
	// pesertaHandler := peserta.NewVClaimHandler(peserta.VClaimHandlerConfig{
	// 	BpjsConfig: cfg.Bpjs,
	// 	Logger:     *logger.Default(),
	// 	Validator:  nil,
	// })
	// protectedPeserta := protected.Group("/peserta")
	// protectedPeserta.GET("/peserta/:nokartu", pesertaHandler.GetPesertaBynokartu)
	// protectedPeserta.GET("/peserta/nik/:nik", pesertaHandler.GetPesertaBynik)

	// // Sep routes
	// sepHandler := sep.NewVClaimHandler(sep.VClaimHandlerConfig{
	// 	BpjsConfig: cfg.Bpjs,
	// 	Logger:     *logger.Default(),
	// 	Validator:  nil,
	// })
	// protectedSep := protected.Group("/sep")
	// protectedSep.GET("/sep/:nosep", sepHandler.GetSepSep)
	// protectedSep.POST("/sep", sepHandler.CreateSepSep)
	// protectedSep.PUT("/sep/:nosep", sepHandler.UpdateSepSep)
	// protectedSep.DELETE("/sep/:nosep", sepHandler.DeleteSepSep)

	return router
}
