package router

import (
	"database/sql"
	"net/http"

	"git.godopu.com/lab/landing_page/backend/internal/handlers"
	"git.godopu.com/lab/landing_page/backend/internal/httpx"
	"git.godopu.com/lab/landing_page/backend/internal/repository"
	"github.com/gin-gonic/gin"
)

func SetupRouter(db *sql.DB, adminToken string, corsOrigins ...string) *gin.Engine {
	r := gin.Default()

	allowOrigin := "*"
	if len(corsOrigins) > 0 && corsOrigins[0] != "" {
		allowOrigin = corsOrigins[0]
	}

	// CORS Middleware
	r.Use(func(c *gin.Context) {
		c.Writer.Header().Set("Access-Control-Allow-Origin", allowOrigin)
		c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
		c.Writer.Header().Set("Access-Control-Allow-Headers", "Origin, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
		if c.Request.Method == "OPTIONS" {
			c.AbortWithStatus(http.StatusNoContent)
			return
		}
		c.Next()
	})

	// Repositories
	homeRepo := repository.NewHomeRepository(db)
	membersRepo := repository.NewMembersRepository(db)
	pubsRepo := repository.NewPublicationsRepository(db)
	lecturesRepo := repository.NewLecturesRepository(db)
	standardsRepo := repository.NewStandardizationRepository(db)

	// Handlers
	homeHandler := handlers.NewHomeHandler(homeRepo)
	membersHandler := handlers.NewMembersHandler(membersRepo)
	pubsHandler := handlers.NewPublicationsHandler(pubsRepo)
	lecturesHandler := handlers.NewLecturesHandler(lecturesRepo)
	standardsHandler := handlers.NewStandardizationHandler(standardsRepo)

	// API v1 Public Group (Read-only)
	v1 := r.Group("/api/v1")
	{
		v1.GET("/health", func(c *gin.Context) {
			httpx.OK(c, gin.H{"status": "ok", "service": "anl-backend-api"})
		})

		// Home
		v1.GET("/research-projects", homeHandler.GetResearchProjects)
		v1.GET("/research-areas", homeHandler.GetResearchAreas)
		v1.GET("/stats/summary", homeHandler.GetStatsSummary)

		// Members & Alumni
		v1.GET("/members", membersHandler.GetMembers)
		v1.GET("/alumni", membersHandler.GetAlumni)

		// Publications & Patents
		v1.GET("/publications", pubsHandler.GetPublications)
		v1.GET("/publications/highlights", pubsHandler.GetHighlights)
		v1.GET("/patents", pubsHandler.GetPatents)

		// Lectures
		v1.GET("/semesters", lecturesHandler.GetSemesters)

		// Standardization
		v1.GET("/standards-bodies", standardsHandler.GetStandardsBodies)
	}

	// API v1 Admin Group (Mutating operations requiring Bearer token)
	admin := v1.Group("")
	admin.Use(httpx.RequireAdminToken(adminToken))
	{
		admin.GET("/admin/verify", func(c *gin.Context) {
			httpx.OK(c, gin.H{"status": "authenticated"})
		})

		// Research Projects
		admin.POST("/research-projects", homeHandler.CreateResearchProject)
		admin.PUT("/research-projects/:id", homeHandler.UpdateResearchProject)
		admin.DELETE("/research-projects/:id", homeHandler.DeleteResearchProject)

		// Research Areas
		admin.POST("/research-areas", homeHandler.CreateResearchArea)
		admin.PUT("/research-areas/:id", homeHandler.UpdateResearchArea)
		admin.DELETE("/research-areas/:id", homeHandler.DeleteResearchArea)

		// Members & Alumni
		admin.POST("/members", membersHandler.CreateMember)
		admin.PUT("/members/:id", membersHandler.UpdateMember)
		admin.DELETE("/members/:id", membersHandler.DeleteMember)

		admin.POST("/alumni", membersHandler.CreateAlumnus)
		admin.PUT("/alumni/:id", membersHandler.UpdateAlumnus)
		admin.DELETE("/alumni/:id", membersHandler.DeleteAlumnus)

		// Publications & Patents
		admin.POST("/publications", pubsHandler.CreatePublication)
		admin.PUT("/publications/:id", pubsHandler.UpdatePublication)
		admin.DELETE("/publications/:id", pubsHandler.DeletePublication)

		admin.POST("/patents", pubsHandler.CreatePatent)
		admin.PUT("/patents/:id", pubsHandler.UpdatePatent)
		admin.DELETE("/patents/:id", pubsHandler.DeletePatent)

		// Lectures (Semesters & Courses)
		admin.POST("/semesters", lecturesHandler.CreateSemester)
		admin.PUT("/semesters/:id", lecturesHandler.UpdateSemester)
		admin.DELETE("/semesters/:id", lecturesHandler.DeleteSemester)

		admin.POST("/semesters/:semesterId/courses", lecturesHandler.CreateCourse)
		admin.PUT("/courses/:id", lecturesHandler.UpdateCourse)
		admin.DELETE("/courses/:id", lecturesHandler.DeleteCourse)

		// Standardization (Bodies & Documents)
		admin.POST("/standards-bodies", standardsHandler.CreateStandardsBody)
		admin.PUT("/standards-bodies/:id", standardsHandler.UpdateStandardsBody)
		admin.DELETE("/standards-bodies/:id", standardsHandler.DeleteStandardsBody)

		admin.POST("/standards-bodies/:bodyId/documents", standardsHandler.CreateStandardDocument)
		admin.PUT("/standard-documents/:id", standardsHandler.UpdateStandardDocument)
		admin.DELETE("/standard-documents/:id", standardsHandler.DeleteStandardDocument)
	}

	return r
}
