// Package media contains browser-facing file, avatar, and sticker routes.
package media

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

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

// Dependencies contains collaborators and config for media routes.
type Dependencies struct {
	AuthStore                 api.SessionAuthenticator
	WorkspaceStore            api.WorkspaceResolver
	ControlWorkspaceStore     api.WorkspaceResolver
	AgentTokenStore           AgentTokenStore
	AgentStore                AgentAvatarProfileStore
	AttachmentStore           AttachmentStore
	PersonalStickerStore      PersonalStickerStore
	EmailVerificationRequired bool
}

// RegisterRoutes mounts browser-facing media routes.
func RegisterRoutes(router gin.IRouter, dependencies Dependencies) {
	RegisterControlRoutes(router, dependencies)
	RegisterWorkspaceRoutes(router, dependencies)
}

// RegisterControlRoutes mounts central media routes.
func RegisterControlRoutes(router gin.IRouter, dependencies Dependencies) {
	if router == nil {
		return
	}
	apiGroup := router.Group("/api/v1")
	registerUserAvatarRoutes(apiGroup, dependencies)
	registerAvatarAssetReadRoute(apiGroup, dependencies)
	registerDeprecatedAvatarObjectRoute(router.Group("/api"), dependencies)
	registerDeprecatedAttachmentObjectRoute(router.Group("/api"), dependencies)
}

func registerAvatarAssetReadRoute(apiGroup gin.IRouter, dependencies Dependencies) {
	handler := &AttachmentHandler{store: dependencies.AttachmentStore}
	apiGroup.GET("/avatar-assets/:avatarId", handler.GetAvatarAsset)
	apiGroup.GET("/avatar-assets/:avatarId/thumbnail", api.HandlePublic(handler.GetAvatarAssetThumbnail))
}

// RegisterWorkspaceRoutes mounts current-workspace media mutation routes.
func RegisterWorkspaceRoutes(router gin.IRouter, dependencies Dependencies) {
	if router == nil {
		return
	}
	apiGroup := router.Group("/api")
	workspaceObjectRoutes := apiGroup.Group("/v1/workspaces/:workspaceId")
	workspaceScoped := apiGroup.Group(
		"/v1/workspaces/:workspaceId",
		api.RequireAuthenticatedUser(dependencies.AuthStore),
		api.RequireVerifiedIdentity(dependencies.EmailVerificationRequired),
		api.RequireRouteWorkspace(dependencies.WorkspaceStore),
	)
	registerWorkspaceScopedAttachmentReadRoutes(workspaceObjectRoutes, dependencies)
	registerWorkspaceScopedAttachmentRoutes(workspaceScoped, dependencies)
	registerPersonalStickerRoutes(workspaceScoped, workspaceObjectRoutes, dependencies)
}

func registerWorkspaceScopedAttachmentReadRoutes(workspaceObjectRoutes gin.IRoutes, dependencies Dependencies) {
	workspaceStore := dependencies.ControlWorkspaceStore
	if workspaceStore == nil {
		workspaceStore = dependencies.WorkspaceStore
	}
	handler := &AttachmentHandler{
		authStore:                 dependencies.AuthStore,
		workspaceStore:            workspaceStore,
		agentTokenStore:           dependencies.AgentTokenStore,
		store:                     dependencies.AttachmentStore,
		emailVerificationRequired: dependencies.EmailVerificationRequired,
	}
	workspaceObjectRoutes.GET("/attachments/:attachmentId", handler.Get)
	workspaceObjectRoutes.GET("/agents/:agentId/avatar", handler.GetAgentAvatar)
	workspaceObjectRoutes.GET("/agents/:agentId/avatar/thumbnail", api.HandlePublic(handler.GetAgentAvatarThumbnail))
}

func registerUserAvatarRoutes(apiGroup gin.IRouter, dependencies Dependencies) {
	workspaceStore := dependencies.ControlWorkspaceStore
	if workspaceStore == nil {
		workspaceStore = dependencies.WorkspaceStore
	}
	userScoped := apiGroup.Group(
		"/me",
		api.RequireAuthenticatedUser(dependencies.AuthStore),
		api.RequireVerifiedIdentity(dependencies.EmailVerificationRequired),
	)
	handler := &AttachmentHandler{
		authStore:                 dependencies.AuthStore,
		workspaceStore:            workspaceStore,
		agentTokenStore:           dependencies.AgentTokenStore,
		store:                     dependencies.AttachmentStore,
		emailVerificationRequired: dependencies.EmailVerificationRequired,
	}
	apiGroup.GET("/users/:userId/avatar", handler.GetUserAvatar)
	apiGroup.GET("/users/:userId/avatar/thumbnail", api.HandlePublic(handler.GetUserAvatarThumbnail))
	userScoped.GET("/avatar", handler.GetCurrentUserAvatar)
	userScoped.GET("/avatar/thumbnail", api.HandleAuth(handler.GetCurrentUserAvatarThumbnail))
	userScoped.PUT("/avatar", handler.UploadAvatar)
}

func registerDeprecatedAvatarObjectRoute(apiGroup gin.IRouter, dependencies Dependencies) {
	handler := &AttachmentHandler{
		authStore:                 dependencies.AuthStore,
		workspaceStore:            dependencies.ControlWorkspaceStore,
		agentTokenStore:           dependencies.AgentTokenStore,
		store:                     dependencies.AttachmentStore,
		emailVerificationRequired: dependencies.EmailVerificationRequired,
	}

	// Deprecated: kept for historical avatar object URLs created before
	// 2026-06-12. New callers must use canonical user/avatar resource URLs:
	// /api/v1/users/:userId/avatar, /api/v1/me/avatar, or the workspace-scoped
	// agent avatar route. Remove after the avatar object URL compatibility window.
	apiGroup.GET("/avatars/:avatarId", handler.GetDeprecatedAvatarObject)
}

func registerDeprecatedAttachmentObjectRoute(apiGroup gin.IRouter, dependencies Dependencies) {
	workspaceStore := dependencies.ControlWorkspaceStore
	if workspaceStore == nil {
		workspaceStore = dependencies.WorkspaceStore
	}
	handler := &AttachmentHandler{
		authStore:                 dependencies.AuthStore,
		workspaceStore:            workspaceStore,
		agentTokenStore:           dependencies.AgentTokenStore,
		store:                     dependencies.AttachmentStore,
		emailVerificationRequired: dependencies.EmailVerificationRequired,
	}

	// Deprecated: kept for older daemon MCP clients that still call
	// /api/attachments/:attachmentId for view_file while newer clients use the
	// workspace-scoped /api/v1/workspaces/:workspaceId/attachments/:attachmentId
	// route. Remove after deployed daemon clients no longer need this shim.
	apiGroup.GET("/attachments/:attachmentId", handler.GetDeprecatedAttachmentObject)
}

func registerWorkspaceScopedAttachmentRoutes(workspaceScoped gin.IRoutes, dependencies Dependencies) {
	handler := &AttachmentHandler{
		authStore:                 dependencies.AuthStore,
		workspaceStore:            dependencies.WorkspaceStore,
		agentTokenStore:           dependencies.AgentTokenStore,
		agentStore:                dependencies.AgentStore,
		store:                     dependencies.AttachmentStore,
		emailVerificationRequired: dependencies.EmailVerificationRequired,
	}
	workspaceScoped.POST("/attachments", handler.Upload)
	workspaceScoped.GET("/attachments/:attachmentId/thumbnail", api.HandleWorkspaceScoped(handler.GetThumbnail))
	workspaceScoped.PUT("/agents/:agentId/avatar", handler.UploadAgentAvatar)
	workspaceScoped.PUT("/avatar-assets/:ownerKind/:ownerId", handler.UploadAvatarAsset)
}

func registerPersonalStickerRoutes(workspaceScoped gin.IRoutes, workspaceObjectRoutes gin.IRoutes, dependencies Dependencies) {
	handler := &PersonalStickerHandler{
		authStore:                 dependencies.AuthStore,
		store:                     dependencies.PersonalStickerStore,
		emailVerificationRequired: dependencies.EmailVerificationRequired,
	}
	workspaceScoped.GET("/stickers", api.HandleWorkspaceScoped(handler.List))
	workspaceScoped.POST("/stickers", handler.Upload)
	workspaceObjectRoutes.GET("/stickers/:stickerId", handler.Get)
	workspaceScoped.DELETE("/stickers/:stickerId", api.HandleWorkspaceScoped(handler.Delete))
}
