// Package llm contains browser-facing and service-facing AgentTeam APR-backed proxy routes.
package llm

import (
	"context"
	"log/slog"
	"net/http"

	"github.com/tidbcloud/AgentTeam/internal/apr/runtime"
	"github.com/tidbcloud/AgentTeam/internal/store/organization"
	"github.com/tidbcloud/AgentTeam/internal/workspace/owner"

	"github.com/gin-gonic/gin"
)

type ProxyKeyAuthenticator interface {
	AuthenticateOrganizationLLMProxyKey(ctx context.Context, token string) (organization.OrganizationProviderProxyAccess, error)
}

type UsageTracker interface {
	CheckOrganizationLLMQuota(ctx context.Context, access organization.OrganizationProviderProxyAccess, model string) (organization.OrganizationLLMQuotaDecision, error)
	RecordOrganizationLLMUsage(ctx context.Context, record organization.OrganizationLLMUsageRecord) error
}

// Dependencies contains collaborators for AgentTeam APR-backed proxy routes.
type Dependencies struct {
	APRDispatcher         *runtime.Dispatcher
	Logger                *slog.Logger
	ProxyKeyAuthenticator ProxyKeyAuthenticator
	UsageTracker          UsageTracker
	ManagedWorkspaces     owner.ManagedWorkspaceSet
}

// RegisterRoutes mounts AgentTeam APR-backed proxy routes when the service is enabled.
func RegisterRoutes(router gin.IRouter, dependencies Dependencies) {
	if router == nil || dependencies.APRDispatcher == nil {
		return
	}

	handler := &LLMHandler{
		aprDispatcher:         dependencies.APRDispatcher,
		logger:                dependencies.Logger,
		proxyKeyAuthenticator: dependencies.ProxyKeyAuthenticator,
		usageTracker:          dependencies.UsageTracker,
		managedWorkspaces:     dependencies.ManagedWorkspaces,
	}
	apiGroup := router.Group("/api/v1/workspaces/:workspaceId/llm", handler.RequireWorkspaceRoute())
	apiGroup.GET("/healthz", func(ctx *gin.Context) {
		ctx.JSON(http.StatusOK, gin.H{
			"status":  "ok",
			"service": "agentteam-apr-proxy",
		})
	})
	v1 := apiGroup.Group("/v1", handler.RequireProxyAuthorization())
	v1.GET("/models", handler.Models)
	v1.POST("/chat/completions", handler.ChatCompletions)
	v1.POST("/messages", handler.Messages)
	v1.POST("/messages/count_tokens", handler.CountTokens)
	v1.POST("/responses", handler.Responses)
	v1.POST("/embeddings", handler.Embeddings)
}
