// Package trigger contains browser-facing trigger management routes.
package trigger

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

	"github.com/tidbcloud/AgentTeam/internal/api"
	"github.com/tidbcloud/AgentTeam/internal/api/dto"
)

const triggerInvalidRequestBodyMessage = "invalid request body"

func handleTriggerWorkspaceJSON[T any](handler func(api.WorkspaceScopedJSON[T]) (api.Response, error)) gin.HandlerFunc {
	return api.HandleWorkspaceScopedJSON[T](handler, api.WithInvalidJSONMessage(triggerInvalidRequestBodyMessage))
}

// Dependencies contains collaborators and config for trigger routes.
type Dependencies struct {
	AuthStore                 api.SessionAuthenticator
	WorkspaceStore            api.WorkspaceResolver
	EmailVerificationRequired bool
	TriggerService            TriggerService
}

// RegisterRoutes mounts browser-facing trigger management routes.
func RegisterRoutes(router gin.IRouter, dependencies Dependencies) {
	if router == nil {
		return
	}
	apiGroup := router.Group("/api")
	workspaceScoped := apiGroup.Group(
		"/v1/workspaces/:workspaceId",
		api.RequireAuthenticatedUser(dependencies.AuthStore),
		api.RequireVerifiedIdentity(dependencies.EmailVerificationRequired),
		api.RequireRouteWorkspace(dependencies.WorkspaceStore),
	)
	handlers := newRouteHandlers(dependencies)
	registerTriggerCollectionRoutes(workspaceScoped, handlers.collection)
	registerTriggerValidationRoutes(workspaceScoped, handlers.validation)
	registerTriggerDetailRoutes(workspaceScoped, handlers.detail)
	registerTriggerLifecycleRoutes(workspaceScoped, handlers.lifecycle)
	registerTriggerRunRoutes(workspaceScoped, handlers.runs)
}

func registerTriggerCollectionRoutes(workspaceScoped gin.IRoutes, handler *CollectionHandler) {
	workspaceScoped.GET("/triggers", api.HandleWorkspaceScoped(handler.List))
	workspaceScoped.POST("/triggers", handleTriggerWorkspaceJSON[dto.TriggerMutationRequest](handler.Create))
}

func registerTriggerValidationRoutes(workspaceScoped gin.IRoutes, handler *ValidationHandler) {
	workspaceScoped.POST("/triggers:validate", handleTriggerWorkspaceJSON[dto.TriggerValidateRequest](handler.Validate))
}

func registerTriggerDetailRoutes(workspaceScoped gin.IRoutes, handler *DetailHandler) {
	workspaceScoped.GET("/triggers/:triggerId", api.HandleWorkspaceScoped(handler.Get))
	workspaceScoped.PATCH("/triggers/:triggerId", handleTriggerWorkspaceJSON[dto.TriggerMutationRequest](handler.Update))
	workspaceScoped.DELETE("/triggers/:triggerId", api.HandleWorkspaceScoped(handler.Delete))
}

func registerTriggerLifecycleRoutes(workspaceScoped gin.IRoutes, handler *LifecycleHandler) {
	workspaceScoped.POST("/triggers/:triggerAction", api.HandleWorkspaceScoped(handler.Action))
}

func registerTriggerRunRoutes(workspaceScoped gin.IRoutes, handler *RunHandler) {
	workspaceScoped.GET("/triggers/:triggerId/runs", api.HandleWorkspaceScoped(handler.List))
}
