package routes

import (
	"github.com/gin-gonic/gin"
	"github.com/timetracker/backend/internal/api/handlers"
	"github.com/timetracker/backend/internal/api/middleware"
	"github.com/timetracker/backend/internal/config"
)

// SetupRouter configures all the routes for the API
func SetupRouter(r *gin.Engine, cfg *config.Config) {
	// Create handlers
	// Apply API key middleware to all API routes
	r.Use(middleware.APIKeyMiddleware(cfg))
	userHandler := handlers.NewUserHandler()
	activityHandler := handlers.NewActivityHandler()
	companyHandler := handlers.NewCompanyHandler()
	customerHandler := handlers.NewCustomerHandler()
	projectHandler := handlers.NewProjectHandler()
	timeEntryHandler := handlers.NewTimeEntryHandler()

	// API routes
	api := r.Group("/api")
	{
		// Auth routes (public)
		auth := api.Group("/auth")
		{
			auth.POST("/login", userHandler.Login)
			auth.POST("/register", userHandler.Register)
		}

		// Protected routes
		protected := api.Group("")
		protected.Use(middleware.AuthMiddleware())
		{
			// Auth routes (protected)
			protectedAuth := protected.Group("/auth")
			{
				protectedAuth.GET("/me", userHandler.GetCurrentUser)
			}

			// User routes
			users := protected.Group("/users")
			{
				users.GET("", userHandler.GetUsers)
				users.GET("/:id", userHandler.GetUserByID)
				users.POST("", middleware.RoleMiddleware("admin"), userHandler.CreateUser)
				users.PUT("/:id", middleware.RoleMiddleware("admin"), userHandler.UpdateUser)
				users.DELETE("/:id", middleware.RoleMiddleware("admin"), userHandler.DeleteUser)
			}

			// Activity routes
			activities := protected.Group("/activities")
			{
				activities.GET("", activityHandler.GetActivities)
				activities.GET("/:id", activityHandler.GetActivityByID)
				activities.POST("", middleware.RoleMiddleware("admin"), activityHandler.CreateActivity)
				activities.PUT("/:id", middleware.RoleMiddleware("admin"), activityHandler.UpdateActivity)
				activities.DELETE("/:id", middleware.RoleMiddleware("admin"), activityHandler.DeleteActivity)
			}

			// Company routes
			companies := protected.Group("/companies")
			{
				companies.GET("", companyHandler.GetCompanies)
				companies.GET("/:id", companyHandler.GetCompanyByID)
				companies.POST("", middleware.RoleMiddleware("admin"), companyHandler.CreateCompany)
				companies.PUT("/:id", middleware.RoleMiddleware("admin"), companyHandler.UpdateCompany)
				companies.DELETE("/:id", middleware.RoleMiddleware("admin"), companyHandler.DeleteCompany)
			}

			// Customer routes
			customers := protected.Group("/customers")
			{
				customers.GET("", customerHandler.GetCustomers)
				customers.GET("/:id", customerHandler.GetCustomerByID)
				customers.GET("/company/:companyId", customerHandler.GetCustomersByCompanyID)
				customers.POST("", middleware.RoleMiddleware("admin"), customerHandler.CreateCustomer)
				customers.PUT("/:id", middleware.RoleMiddleware("admin"), customerHandler.UpdateCustomer)
				customers.DELETE("/:id", middleware.RoleMiddleware("admin"), customerHandler.DeleteCustomer)
			}

			// Project routes
			projects := protected.Group("/projects")
			{
				projects.GET("", projectHandler.GetProjects)
				projects.GET("/with-customers", projectHandler.GetProjectsWithCustomers)
				projects.GET("/:id", projectHandler.GetProjectByID)
				projects.GET("/customer/:customerId", projectHandler.GetProjectsByCustomerID)
				projects.POST("", middleware.RoleMiddleware("admin"), projectHandler.CreateProject)
				projects.PUT("/:id", middleware.RoleMiddleware("admin"), projectHandler.UpdateProject)
				projects.DELETE("/:id", middleware.RoleMiddleware("admin"), projectHandler.DeleteProject)
			}

			// Time Entry routes
			timeEntries := protected.Group("/time-entries")
			{
				timeEntries.GET("", timeEntryHandler.GetTimeEntries)
				timeEntries.GET("/me", timeEntryHandler.GetMyTimeEntries)
				timeEntries.GET("/range", timeEntryHandler.GetTimeEntriesByDateRange)
				timeEntries.GET("/:id", timeEntryHandler.GetTimeEntryByID)
				timeEntries.GET("/user/:userId", timeEntryHandler.GetTimeEntriesByUserID)
				timeEntries.GET("/project/:projectId", timeEntryHandler.GetTimeEntriesByProjectID)
				timeEntries.POST("", timeEntryHandler.CreateTimeEntry)
				timeEntries.PUT("/:id", timeEntryHandler.UpdateTimeEntry)
				timeEntries.DELETE("/:id", timeEntryHandler.DeleteTimeEntry)
			}
		}
	}
}
