package routes

import (
	"github.com/gin-gonic/gin"

	"customer-support-system/internal/auth"
	"customer-support-system/internal/handlers"
)

// SetupRoutes configures all the routes for the application
func SetupRoutes() *gin.Engine {
	// Create a new Gin engine
	r := gin.Default()

	// Add CORS middleware
	r.Use(CORSMiddleware())

	// Create handlers
	userHandler := handlers.NewUserHandler()
	conversationHandler := handlers.NewConversationHandler()
	knowledgeHandler := handlers.NewKnowledgeHandler()
	aiHandler := handlers.NewAIHandler()

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

	// API version 1 group
	v1 := r.Group("/api/v1")
	{
		// Public routes (no authentication required)
		public := v1.Group("/public")
		{
			// User authentication routes
			public.POST("/register", userHandler.Register)
			public.POST("/login", userHandler.Login)
		}

		// Protected routes (authentication required)
		protected := v1.Group("")
		protected.Use(auth.AuthMiddleware())
		{
			// User routes
			user := protected.Group("/user")
			{
				user.GET("/profile", userHandler.GetProfile)
				user.PUT("/profile", userHandler.UpdateProfile)
				user.PUT("/change-password", userHandler.ChangePassword)
			}

			// Conversation routes
			conversations := protected.Group("/conversations")
			{
				conversations.GET("", conversationHandler.ListConversations)
				conversations.POST("", conversationHandler.CreateConversation)
				conversations.GET("/:id", conversationHandler.GetConversation)
				conversations.PUT("/:id", conversationHandler.UpdateConversation)
				conversations.DELETE("/:id", conversationHandler.DeleteConversation)
				conversations.GET("/:id/stats", conversationHandler.GetConversationStats)

				// Message routes
				conversations.POST("/:id/messages", conversationHandler.CreateMessage)
				conversations.GET("/:id/messages", conversationHandler.GetMessages)
				conversations.PUT("/:id/messages/:messageId", conversationHandler.UpdateMessage)
				conversations.DELETE("/:id/messages/:messageId", conversationHandler.DeleteMessage)

				// AI interaction routes
				conversations.POST("/:id/ai", conversationHandler.SendMessageWithAI)
			}

			// Knowledge base routes
			knowledge := protected.Group("/knowledge")
			{
				knowledge.GET("", knowledgeHandler.ListKnowledgeEntries)
				knowledge.GET("/search", knowledgeHandler.SearchKnowledge)
				knowledge.GET("/categories", knowledgeHandler.GetCategories)
				knowledge.GET("/tags", knowledgeHandler.GetTags)
				knowledge.GET("/popular", knowledgeHandler.GetPopularKnowledge)
				knowledge.GET("/recent", knowledgeHandler.GetRecentKnowledge)
				knowledge.GET("/best-match", knowledgeHandler.FindBestMatch)
				knowledge.GET("/stats", knowledgeHandler.GetKnowledgeStats)
				knowledge.GET("/:id", knowledgeHandler.GetKnowledgeEntry)
				knowledge.POST("/:id/rate", knowledgeHandler.RateKnowledgeEntry)
			}

			// AI routes
			ai := protected.Group("/ai")
			{
				ai.POST("/query", aiHandler.QueryAI)
				ai.POST("/analyze-complexity", aiHandler.AnalyzeComplexity)
				ai.GET("/models", aiHandler.GetAvailableModels)
				ai.POST("/openai", aiHandler.QueryOpenAI)
				ai.POST("/ollama", aiHandler.QueryOllama)
			}

			// Admin routes (admin role required)
			admin := protected.Group("/admin")
			admin.Use(auth.RoleMiddleware("admin"))
			{
				// User management
				admin.GET("/users", userHandler.AdminGetUsers)
				admin.GET("/users/:id", userHandler.AdminGetUser)
				admin.PUT("/users/:id", userHandler.AdminUpdateUser)
				admin.DELETE("/users/:id", userHandler.AdminDeleteUser)

				// Knowledge base management
				admin.POST("/knowledge", knowledgeHandler.CreateKnowledgeEntry)
				admin.PUT("/knowledge/:id", knowledgeHandler.UpdateKnowledgeEntry)
				admin.DELETE("/knowledge/:id", knowledgeHandler.DeleteKnowledgeEntry)
			}

			// Agent routes (agent or admin role required)
			agent := protected.Group("/agent")
			agent.Use(auth.RoleMiddleware("agent", "admin"))
			{
				// Additional agent-only endpoints can be added here
			}
		}
	}

	return r
}

// CORSMiddleware adds CORS headers to the response
func CORSMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
		c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
		c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
		c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, DELETE")

		if c.Request.Method == "OPTIONS" {
			c.AbortWithStatus(204)
			return
		}

		c.Next()
	}
}
