package routes

import (
	"gauth-central/api/handlers"
	"gauth-central/api/middlewares"
	_ "gauth-central/docs" // docs import
	"gauth-central/internal/services"
	"net/http"

	"github.com/gin-gonic/gin"
	swaggerFiles "github.com/swaggo/files"
	ginSwagger "github.com/swaggo/gin-swagger"
)

func SetupRoutes(r *gin.Engine) {
	jwtService := services.NewJWTService()
	authService := services.NewAuthService()
	authHandler := handlers.NewAuthHandler(authService)

	settingsService := services.NewSettingsService()
	settingsHandler := handlers.NewSettingsHandler(settingsService)

	userManagementService := services.NewUserManagementService()
	userManagementHandler := handlers.NewUserManagementHandler(userManagementService)

	avatarHandler := handlers.NewAvatarHandler()
	profileHandler := handlers.NewProfileHandler()

	contactService := services.NewContactService()
	contactHandler := handlers.NewContactHandler(contactService)

	tagService := services.NewTagService()
	tagHandler := handlers.NewTagHandler(tagService)

	postCategoryService := services.NewPostCategoryService()
	postCategoryHandler := handlers.NewPostCategoryHandler(postCategoryService)

	postTagService := services.NewPostTagService()
	postTagHandler := handlers.NewPostTagHandler(postTagService)

	postService := services.NewPostService()
	postHandler := handlers.NewPostHandler(postService)

	postCommentService := services.NewPostCommentService()
	postCommentHandler := handlers.NewPostCommentHandler(postCommentService)

	postCategoryViewService := services.NewPostCategoryViewService()
	postCategoryViewHandler := handlers.NewPostCategoryViewHandler(postCategoryViewService)

	homeService := services.NewHomeService()
	homeHandler := handlers.NewHomeHandler(homeService)

	aboutService := services.NewAboutService()
	aboutHandler := handlers.NewAboutHandler(aboutService)

	serviceService := services.NewServiceService()
	serviceHandler := handlers.NewServiceHandler(serviceService)

	serviceTitleService := services.NewServiceTitleService()
	serviceTitleHandler := handlers.NewServiceTitleHandler(serviceTitleService)

	siteInfoService := services.NewSiteInfoService()
	siteInfoHandler := handlers.NewSiteInfoHandler(siteInfoService)

	bannerService := services.NewBannerService()
	bannerHandler := handlers.NewBannerHandler(bannerService)

	siteSettingsService := services.NewSiteSettingsService()
	siteSettingsHandler := handlers.NewSiteSettingsHandler(siteSettingsService)

	resumeService := services.NewResumeService()
	resumeHandler := handlers.NewResumeHandler(resumeService)

	educationService := services.NewEducationService()
	educationHandler := handlers.NewEducationHandler(educationService)

	experienceService := services.NewExperienceService()
	experienceHandler := handlers.NewExperienceHandler(experienceService)

	skillService := services.NewSkillService()
	skillHandler := handlers.NewSkillHandler(skillService)

	knowledgeService := services.NewKnowledgeService()
	knowledgeHandler := handlers.NewKnowledgeHandler(knowledgeService)

	mainMenuService := services.NewMainMenuService()
	mainMenuHandler := handlers.NewMainMenuHandler(mainMenuService)

	// Serve static files (uploaded avatars)
	r.Static("/uploads", "./uploads")

	// Homepage
	r.LoadHTMLGlob("web/*")
	r.GET("/", func(c *gin.Context) {
		c.HTML(http.StatusOK, "index.html", nil)
	})

	// Swagger route moved outside of v1 group to be accessible at /docs/index.html
	r.GET("/docs/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))

	v1 := r.Group("/v1")
	v1.Use(middlewares.APIRateLimitMiddleware()) // General API rate limiting
	{
		auth := v1.Group("/auth")
		{
			auth.POST("/register", middlewares.RegisterRateLimitMiddleware(), authHandler.Register)
			auth.POST("/login", middlewares.LoginRateLimitMiddleware(), authHandler.Login)
			auth.GET("/verify-email", authHandler.VerifyEmail)
			auth.GET("/:provider", authHandler.BeginAuth)
			auth.GET("/:provider/callback", authHandler.Callback)
			auth.POST("/refresh", authHandler.Refresh)

			// Protected routes
			protected := auth.Group("/")
			protected.Use(middlewares.AuthMiddleware(jwtService))
			{
				protected.GET("/me", authHandler.Me)
				protected.GET("/validate", func(c *gin.Context) {
					c.JSON(http.StatusOK, gin.H{
						"message": "Token is valid",
						"user_id": c.GetString("user_id"),
						"email":   c.GetString("email"),
					})
				})
			}
		}

		// Contact endpoint (Public but can optionally use auth)
		v1.POST("/contact", middlewares.OptionalAuthMiddleware(jwtService), contactHandler.CreateContact)

		// Public Tags Endpoint (Only active tags)
		v1.GET("/tags", tagHandler.GetAllTags)

		// Public Post Categories
		v1.GET("/post-categories", postCategoryHandler.GetAllPostCategories)
		v1.GET("/post-categories/:slug", postCategoryHandler.GetPostCategoryBySlug)
		v1.POST("/post-categories/:id/views", postCategoryViewHandler.TrackPostCategoryView)

		// Public Post Tags
		v1.GET("/post-tags", postTagHandler.GetAllPostTags)

		// Public Posts
		v1.GET("/posts", postHandler.GetAllPosts)
		v1.GET("/posts/slug/:slug", postHandler.GetPostBySlug)
		v1.GET("/posts/:id/comments", postCommentHandler.GetPostCommentsByPostID)

		// Public About Endpoints (Only active about entries)
		v1.GET("/about", aboutHandler.GetAllAbout)
		v1.GET("/about/active", aboutHandler.GetActiveAbout)

		// Public Services Endpoints (Only active services)
		v1.GET("/services", serviceHandler.GetAllServices)
		v1.GET("/services/:slug", serviceHandler.GetServiceBySlug)

		// Public Service Titles Endpoints (Only active service titles)
		v1.GET("/service-titles", serviceTitleHandler.GetAllServiceTitles)
		v1.GET("/service-titles/active", serviceTitleHandler.GetActiveServiceTitle)

		// Public Main Menu Endpoints (Only active entries)
		v1.GET("/main-menu", mainMenuHandler.GetAllMainMenus)
		v1.GET("/main-menu/active", mainMenuHandler.GetActiveMainMenu)

		// Public Site Info Endpoints (Only active entries)
		v1.GET("/site-info", siteInfoHandler.GetAllSiteInfos)
		v1.GET("/site-info/active", siteInfoHandler.GetActiveSiteInfo)

		// Public Banner Endpoints (Only active entries)
		v1.GET("/banners", bannerHandler.GetAllBanners)
		v1.GET("/banners/active", bannerHandler.GetActiveBanner)

		// Public Site Settings Endpoints (Only active entries)
		v1.GET("/site-settings", siteSettingsHandler.GetAllSiteSettings)
		v1.GET("/site-settings/active", siteSettingsHandler.GetActiveSiteSettings)

		// Public Homes Endpoints (Only active homes)
		v1.GET("/homes", homeHandler.GetAllHomes)
		v1.GET("/homes/:slug", homeHandler.GetHomeBySlug)

		// Public Resume Endpoints
		v1.GET("/resumes", resumeHandler.GetAllResumes)
		v1.GET("/resumes/active", resumeHandler.GetActiveResume)
		v1.GET("/educations", educationHandler.GetAllEducations)
		v1.GET("/experiences", experienceHandler.GetAllExperiences)
		v1.GET("/skills", skillHandler.GetAllSkills)
		v1.GET("/knowledges", knowledgeHandler.GetAllKnowledges)

		// User endpoints
		user := v1.Group("/user")
		user.Use(middlewares.AuthMiddleware(jwtService))
		{
			// Avatar management
			user.POST("/avatar", avatarHandler.UploadAvatar)
			user.DELETE("/avatar", avatarHandler.DeleteAvatar)
		}

		// Post comment creation (Auth required)
		postAuth := v1.Group("/posts")
		postAuth.Use(middlewares.AuthMiddleware(jwtService))
		{
			postAuth.POST("/:id/comments", postCommentHandler.CreatePostComment)
		}

		// Profile endpoints
		profile := v1.Group("/profile")
		profile.Use(middlewares.AuthMiddleware(jwtService))
		{
			profile.GET("", profileHandler.GetProfile)
			profile.PUT("", profileHandler.UpdateProfile)
			profile.PUT("/password", profileHandler.ChangePassword)
			profile.PUT("/email", profileHandler.ChangeEmail)
		}

		// Settings endpoints (Admin only)
		settings := v1.Group("/settings")
		settings.Use(middlewares.AuthMiddleware(jwtService))
		settings.Use(middlewares.AdminMiddleware())
		{
			// CORS Whitelist
			corsWhitelist := settings.Group("/cors/whitelist")
			{
				corsWhitelist.GET("", settingsHandler.GetAllWhitelist)
				corsWhitelist.POST("", settingsHandler.CreateWhitelist)
				corsWhitelist.PUT("/:id", settingsHandler.UpdateWhitelist)
				corsWhitelist.DELETE("/:id", settingsHandler.DeleteWhitelist)
			}

			// CORS Blacklist
			corsBlacklist := settings.Group("/cors/blacklist")
			{
				corsBlacklist.GET("", settingsHandler.GetAllBlacklist)
				corsBlacklist.POST("", settingsHandler.CreateBlacklist)
				corsBlacklist.PUT("/:id", settingsHandler.UpdateBlacklist)
				corsBlacklist.DELETE("/:id", settingsHandler.DeleteBlacklist)
			}

			// Rate Limit Settings
			rateLimit := settings.Group("/ratelimit")
			{
				rateLimit.GET("", settingsHandler.GetAllRateLimits)
				rateLimit.PUT("/:id", settingsHandler.UpdateRateLimit)
			}

			// CORS Cache
			settings.POST("/cors/cache/invalidate", settingsHandler.InvalidateCorsCache)
		}

		// Admin - User Management
		admin := v1.Group("/admin")
		admin.Use(middlewares.AuthMiddleware(jwtService))
		admin.Use(middlewares.AdminMiddleware())
		{
			users := admin.Group("/users")
			{
				users.GET("/search", userManagementHandler.SearchUsers)
				users.GET("/deleted", userManagementHandler.GetDeletedUsers) // Yeni: Silinen kullanıcılar
				users.GET("", userManagementHandler.GetAllUsers)
				users.POST("", userManagementHandler.CreateUser)
				users.GET("/:id", userManagementHandler.GetUserByID)
				users.PUT("/:id", userManagementHandler.UpdateUser)
				users.DELETE("/:id", userManagementHandler.DeleteUser)
				users.POST("/:id/roles", userManagementHandler.AssignRoles)
				users.DELETE("/:id/roles/:role", userManagementHandler.RemoveRole)
				users.POST("/:id/restore", userManagementHandler.RestoreUser) // Yeni: Kullanıcıyı restore et

				// Avatar management for users (Admin)
				users.POST("/:id/avatar", avatarHandler.AdminUploadAvatar)
			}

			// Admin - Home Management
			homes := admin.Group("/homes")
			{
				homes.GET("", homeHandler.AdminGetAllHomes)
				homes.POST("", homeHandler.CreateHome)
				homes.GET("/:id", homeHandler.AdminGetHomeByID)
				homes.PUT("/:id", homeHandler.UpdateHome)
				homes.DELETE("/:id", homeHandler.DeleteHome)
				homes.POST("/:id/image", homeHandler.AdminUploadHomeImage)
			}

			// Admin - Post Categories
			postCategories := admin.Group("/post-categories")
			{
				postCategories.GET("", postCategoryHandler.AdminGetAllPostCategories)
				postCategories.POST("", postCategoryHandler.CreatePostCategory)
				postCategories.GET("/:id", postCategoryHandler.AdminGetPostCategoryByID)
				postCategories.PUT("/:id", postCategoryHandler.UpdatePostCategory)
				postCategories.DELETE("/:id", postCategoryHandler.DeletePostCategory)
			}

			// Admin - Post Tags
			postTags := admin.Group("/post-tags")
			{
				postTags.GET("", postTagHandler.AdminGetAllPostTags)
				postTags.POST("", postTagHandler.CreatePostTag)
				postTags.GET("/:id", postTagHandler.GetPostTagByID)
				postTags.PUT("/:id", postTagHandler.UpdatePostTag)
				postTags.DELETE("/:id", postTagHandler.DeletePostTag)
			}

			// Admin - Posts
			posts := admin.Group("/posts")
			{
				posts.GET("", postHandler.AdminGetAllPosts)
				posts.POST("", postHandler.CreatePost)
				posts.GET("/:id", postHandler.AdminGetPostByID)
				posts.PUT("/:id", postHandler.UpdatePost)
				posts.DELETE("/:id", postHandler.DeletePost)
			}

			// Admin - Post Comments
			postComments := admin.Group("/post-comments")
			{
				postComments.GET("", postCommentHandler.AdminGetAllPostComments)
				postComments.GET("/:id", postCommentHandler.AdminGetPostCommentByID)
				postComments.PUT("/:id", postCommentHandler.AdminUpdatePostComment)
				postComments.DELETE("/:id", postCommentHandler.AdminDeletePostComment)
			}

			// Admin - Post Category Views
			postCategoryViews := admin.Group("/post-category-views")
			{
				postCategoryViews.GET("", postCategoryViewHandler.AdminGetPostCategoryViews)
			}

			// Admin - About Management
			about := admin.Group("/about")
			{
				about.GET("", aboutHandler.AdminGetAllAbout)
				about.POST("", aboutHandler.CreateAbout)
				about.GET("/:id", aboutHandler.AdminGetAboutByID)
				about.PUT("/:id", aboutHandler.UpdateAbout)
				about.DELETE("/:id", aboutHandler.DeleteAbout)
			}

			// Admin - Service Management
			servicesGroup := admin.Group("/services")
			{
				servicesGroup.GET("", serviceHandler.AdminGetAllServices)
				servicesGroup.POST("", serviceHandler.CreateService)
				servicesGroup.GET("/:id", serviceHandler.AdminGetServiceByID)
				servicesGroup.PUT("/:id", serviceHandler.UpdateService)
				servicesGroup.DELETE("/:id", serviceHandler.DeleteService)
			}

			// Admin - Service Title Management
			serviceTitles := admin.Group("/service-titles")
			{
				serviceTitles.GET("", serviceTitleHandler.AdminGetAllServiceTitles)
				serviceTitles.POST("", serviceTitleHandler.CreateServiceTitle)
				serviceTitles.GET("/:id", serviceTitleHandler.AdminGetServiceTitleByID)
				serviceTitles.PUT("/:id", serviceTitleHandler.UpdateServiceTitle)
				serviceTitles.DELETE("/:id", serviceTitleHandler.DeleteServiceTitle)
			}

			// Admin - Site Info Management
			siteInfo := admin.Group("/site-info")
			{
				siteInfo.GET("", siteInfoHandler.AdminGetAllSiteInfos)
				siteInfo.POST("", siteInfoHandler.CreateSiteInfo)
				siteInfo.GET("/:id", siteInfoHandler.AdminGetSiteInfoByID)
				siteInfo.PUT("/:id", siteInfoHandler.UpdateSiteInfo)
				siteInfo.DELETE("/:id", siteInfoHandler.DeleteSiteInfo)
			}

			// Admin - Banner Management
			banners := admin.Group("/banners")
			{
				banners.GET("", bannerHandler.AdminGetAllBanners)
				banners.POST("", bannerHandler.CreateBanner)
				banners.GET("/:id", bannerHandler.AdminGetBannerByID)
				banners.PUT("/:id", bannerHandler.UpdateBanner)
				banners.DELETE("/:id", bannerHandler.DeleteBanner)
			}

			// Admin - Site Settings Management
			siteSettings := admin.Group("/site-settings")
			{
				siteSettings.GET("", siteSettingsHandler.AdminGetAllSiteSettings)
				siteSettings.POST("", siteSettingsHandler.CreateSiteSettings)
				siteSettings.GET("/:id", siteSettingsHandler.AdminGetSiteSettingsByID)
				siteSettings.PUT("/:id", siteSettingsHandler.UpdateSiteSettings)
				siteSettings.DELETE("/:id", siteSettingsHandler.DeleteSiteSettings)
			}

			// Admin - Resume Management
			resumes := admin.Group("/resumes")
			{
				resumes.GET("", resumeHandler.AdminGetAllResumes)
				resumes.POST("", resumeHandler.CreateResume)
				resumes.GET("/:id", resumeHandler.AdminGetResumeByID)
				resumes.PUT("/:id", resumeHandler.UpdateResume)
				resumes.DELETE("/:id", resumeHandler.DeleteResume)
			}

			// Admin - Education Management
			educations := admin.Group("/educations")
			{
				educations.GET("", educationHandler.AdminGetAllEducations)
				educations.POST("", educationHandler.CreateEducation)
				educations.GET("/:id", educationHandler.AdminGetEducationByID)
				educations.PUT("/:id", educationHandler.UpdateEducation)
				educations.DELETE("/:id", educationHandler.DeleteEducation)
			}

			// Admin - Experience Management
			experiences := admin.Group("/experiences")
			{
				experiences.GET("", experienceHandler.AdminGetAllExperiences)
				experiences.POST("", experienceHandler.CreateExperience)
				experiences.GET("/:id", experienceHandler.AdminGetExperienceByID)
				experiences.PUT("/:id", experienceHandler.UpdateExperience)
				experiences.DELETE("/:id", experienceHandler.DeleteExperience)
			}

			// Admin - Skill Management
			skills := admin.Group("/skills")
			{
				skills.GET("", skillHandler.AdminGetAllSkills)
				skills.POST("", skillHandler.CreateSkill)
				skills.GET("/:id", skillHandler.AdminGetSkillByID)
				skills.PUT("/:id", skillHandler.UpdateSkill)
				skills.DELETE("/:id", skillHandler.DeleteSkill)
			}

			// Admin - Knowledge Management
			knowledges := admin.Group("/knowledges")
			{
				knowledges.GET("", knowledgeHandler.AdminGetAllKnowledges)
				knowledges.POST("", knowledgeHandler.CreateKnowledge)
				knowledges.GET("/:id", knowledgeHandler.AdminGetKnowledgeByID)
				knowledges.PUT("/:id", knowledgeHandler.UpdateKnowledge)
				knowledges.DELETE("/:id", knowledgeHandler.DeleteKnowledge)
			}

			// Admin - Main Menu Management
			mainMenu := admin.Group("/main-menu")
			{
				mainMenu.GET("", mainMenuHandler.AdminGetAllMainMenus)
				mainMenu.POST("", mainMenuHandler.CreateMainMenu)
				mainMenu.GET("/:id", mainMenuHandler.AdminGetMainMenuByID)
				mainMenu.PUT("/:id", mainMenuHandler.UpdateMainMenu)
				mainMenu.DELETE("/:id", mainMenuHandler.DeleteMainMenu)
			}

			// Admin - Contact Management
			contacts := admin.Group("/contacts")
			{
				contacts.GET("", contactHandler.GetAllContacts)
				contacts.GET("/:id", contactHandler.GetContactByID)
				contacts.DELETE("/:id", contactHandler.DeleteContact)
			}

			// Admin - Tag Management
			tags := admin.Group("/tags")
			{
				tags.GET("", tagHandler.AdminGetAllTags)
				tags.POST("", tagHandler.CreateTag)
				tags.GET("/:id", tagHandler.GetTagByID)
				tags.PUT("/:id", tagHandler.UpdateTag)
				tags.DELETE("/:id", tagHandler.DeleteTag)
			}
		}
	}
}
