package routes

import (
	"sno/internal/handlers"
	"sno/internal/middleware"
	"sno/internal/service"
	"sno/internal/types"

	"github.com/gofiber/fiber/v2"
	"github.com/gofiber/fiber/v2/middleware/logger"
	"github.com/gofiber/fiber/v2/middleware/cors"
)

func Setup(app *fiber.App, quizHandler *handlers.QuizHandler, questionHandler *handlers.QuestionHandler, rewardHandler *handlers.RewardHandler, userHandler *handlers.UserHandler, adminHandler *handlers.AdminHandler, qrHandler *handlers.QRHandler, authHandler *handlers.AuthHandler, adminService service.AdminService, botToken string) {
	// General middleware
	app.Use(logger.New())

	// CORS middleware - must come before auth middleware to handle preflight requests
	app.Use(cors.New(cors.Config{
		AllowOrigins:     "*",
		AllowMethods:     "GET,POST,PUT,DELETE,OPTIONS",
		AllowHeaders:     "Origin,Content-Type,Accept,Authorization,X-Telegram-Init-Data,X-Telegram-WebApp-Init-Data",
		AllowCredentials: false,
		ExposeHeaders:    "Content-Length",
		MaxAge:           86400, // Pre-flight request cache duration (24 hours)
	}))

	// Group API routes
	api := app.Group("/api")

	// --- Auth Routes ---
	api.Post("/auth/validate", authHandler.Validate) // Validates Telegram initData without middleware
	auth := api.Group("/auth")
	auth.Use(middleware.AuthMiddleware(middleware.AuthConfig{BotToken: botToken}))
	auth.Get("/me", authHandler.GetMe) // Get current authenticated user
	auth.Get("/admin-role", authHandler.GetAdminRole) // Get admin role for current user

	// --- Protected Routes (require auth) ---
	protected := api.Group("")
	protected.Use(middleware.AuthMiddleware(middleware.AuthConfig{BotToken: botToken}))

	// --- User Routes ---
	protected.Get("/me", userHandler.GetMe) // Get current user profile
	user := protected.Group("/user")
	user.Get("/transactions", userHandler.GetUserTransactions)
	user.Get("/purchases", userHandler.GetUserPurchases)

	// --- Quiz Routes ---
	quiz := protected.Group("/quizzes")
	quiz.Get("/", quizHandler.GetAllQuizzes)
	quiz.Get("/:id", quizHandler.GetQuizByID)
	quiz.Post("/:id/submit", quizHandler.SubmitQuiz)
	quiz.Get("/:id/can-repeat", quizHandler.CanRepeat)

	// --- Reward (Shop) Routes ---
	reward := protected.Group("/rewards")
	reward.Get("/", rewardHandler.GetAllRewards)
	reward.Post("/:id/purchase", rewardHandler.PurchaseReward)

	// --- QR & Deep Link Routes ---
	qr := protected.Group("/qr")
	qr.Post("/validate", qrHandler.Validate)

	// --- Admin Routes (with role-based middleware) ---
	admin := api.Group("/admin")

	// Admin middleware configuration
	adminConfig := middleware.AdminConfig{
		AdminService: adminService, // Need to pass this from main
	}

	// Admin routes requiring any admin role (admin or operator)
	adminAnyRole := admin.Group("")
	adminAnyRole.Use(middleware.WithAdminRoles(adminConfig, types.RoleAdmin, types.RoleOperator))

	// Admin routes requiring admin role only
	adminOnly := admin.Group("")
	adminOnly.Use(middleware.WithAdminRoles(adminConfig, types.RoleAdmin))

	// Admin: Quizzes (operator+)
	adminAnyRole.Post("/quizzes", quizHandler.CreateQuiz)
	adminAnyRole.Post("/quizzes/:quiz_id/questions", questionHandler.CreateQuestion)
	adminAnyRole.Put("/quizzes/:quiz_id/questions/:question_id", questionHandler.UpdateQuestion)
	adminAnyRole.Delete("/quizzes/:quiz_id/questions/:question_id", questionHandler.DeleteQuestion)
	adminOnly.Put("/quizzes/:id", quizHandler.UpdateQuiz)
	adminOnly.Delete("/quizzes/:id", quizHandler.DeleteQuiz)

	// Admin: Rewards (operator+)
	adminAnyRole.Post("/rewards", rewardHandler.CreateReward)
	adminOnly.Put("/rewards/:id", rewardHandler.UpdateReward)
	adminOnly.Delete("/rewards/:id", rewardHandler.DeleteReward)

	// Admin: Users & Balance (admin only)
	adminOnly.Post("/users/grant-stars", adminHandler.GrantStars)
	adminAnyRole.Post("/qrcodes", adminHandler.GenerateQRCodes)

	// Admin: Operators (admin only)
	adminOnly.Post("/operators", adminHandler.CreateOperator)
	adminOnly.Delete("/operators/:id", adminHandler.DeleteOperator)

	// Admin: Analytics (operator+)
	adminAnyRole.Get("/analytics", adminHandler.GetAnalytics)
}
