package org

import (
	"net/http"
	"strings"

	"github.com/tidbcloud/AgentTeam/internal/api"
	"github.com/tidbcloud/AgentTeam/internal/api/dto"
	"github.com/tidbcloud/AgentTeam/internal/api/dto/converter"
	"github.com/tidbcloud/AgentTeam/internal/store/organization"

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

func (handler *ProviderHandler) LLMStatsSummary(ctx *gin.Context) {
	authenticated, ok := api.AuthenticatedUserFromContext(ctx)
	if !ok {
		api.Error(ctx, http.StatusUnauthorized, "Unauthorized")
		return
	}
	orgs, ok := handler.organizationProvider()
	if !ok {
		api.Error(ctx, http.StatusNotFound, "Organization provider not installed")
		return
	}
	organizationID := strings.TrimSpace(ctx.Param("orgId"))
	if organizationID == "" {
		api.Error(ctx, http.StatusBadRequest, "orgId is required")
		return
	}
	items, err := orgs.ListOrganizationLLMStatsSummaryForUser(ctx.Request.Context(), authenticated.User.ID, organizationID)
	if err != nil {
		api.StoreError(ctx, err)
		return
	}
	ctx.JSON(http.StatusOK, converter.ToOrgLLMStatsSummaryViews(items))
}

func (handler *ProviderHandler) LLMStatsDetail(ctx *gin.Context) {
	authenticated, ok := api.AuthenticatedUserFromContext(ctx)
	if !ok {
		api.Error(ctx, http.StatusUnauthorized, "Unauthorized")
		return
	}
	orgs, ok := handler.organizationProvider()
	if !ok {
		api.Error(ctx, http.StatusNotFound, "Organization provider not installed")
		return
	}
	organizationID := strings.TrimSpace(ctx.Param("orgId"))
	if organizationID == "" {
		api.Error(ctx, http.StatusBadRequest, "orgId is required")
		return
	}
	items, err := orgs.ListOrganizationLLMStatsDetailForUser(ctx.Request.Context(), authenticated.User.ID, organizationID, organizationLLMStatsQueryFromRequest(ctx))
	if err != nil {
		api.StoreError(ctx, err)
		return
	}
	ctx.JSON(http.StatusOK, converter.ToOrgLLMStatsDetailViews(items))
}

func (handler *ProviderHandler) LLMStatsTimeSeries(ctx *gin.Context) {
	authenticated, ok := api.AuthenticatedUserFromContext(ctx)
	if !ok {
		api.Error(ctx, http.StatusUnauthorized, "Unauthorized")
		return
	}
	orgs, ok := handler.organizationProvider()
	if !ok {
		api.Error(ctx, http.StatusNotFound, "Organization provider not installed")
		return
	}
	organizationID := strings.TrimSpace(ctx.Param("orgId"))
	if organizationID == "" {
		api.Error(ctx, http.StatusBadRequest, "orgId is required")
		return
	}
	item, err := orgs.GetOrganizationLLMStatsTimeSeriesForUser(ctx.Request.Context(), authenticated.User.ID, organizationID, organizationLLMStatsQueryFromRequest(ctx))
	if err != nil {
		api.StoreError(ctx, err)
		return
	}
	ctx.JSON(http.StatusOK, converter.ToOrgLLMTimeSeriesView(item))
}

func (handler *ProviderHandler) LLMStatsErrorsSummary(ctx *gin.Context) {
	authenticated, ok := api.AuthenticatedUserFromContext(ctx)
	if !ok {
		api.Error(ctx, http.StatusUnauthorized, "Unauthorized")
		return
	}
	orgs, ok := handler.organizationProvider()
	if !ok {
		api.Error(ctx, http.StatusNotFound, "Organization provider not installed")
		return
	}
	organizationID := strings.TrimSpace(ctx.Param("orgId"))
	if organizationID == "" {
		api.Error(ctx, http.StatusBadRequest, "orgId is required")
		return
	}
	item, err := orgs.GetOrganizationLLMErrorSummaryForUser(ctx.Request.Context(), authenticated.User.ID, organizationID, organizationLLMStatsQueryFromRequest(ctx))
	if err != nil {
		api.StoreError(ctx, err)
		return
	}
	ctx.JSON(http.StatusOK, converter.ToOrgLLMErrorSummaryView(item))
}

func (handler *ProviderHandler) LLMStatsErrorsTimeSeries(ctx *gin.Context) {
	authenticated, ok := api.AuthenticatedUserFromContext(ctx)
	if !ok {
		api.Error(ctx, http.StatusUnauthorized, "Unauthorized")
		return
	}
	orgs, ok := handler.organizationProvider()
	if !ok {
		api.Error(ctx, http.StatusNotFound, "Organization provider not installed")
		return
	}
	organizationID := strings.TrimSpace(ctx.Param("orgId"))
	if organizationID == "" {
		api.Error(ctx, http.StatusBadRequest, "orgId is required")
		return
	}
	item, err := orgs.GetOrganizationLLMErrorTimeSeriesForUser(ctx.Request.Context(), authenticated.User.ID, organizationID, organizationLLMStatsQueryFromRequest(ctx))
	if err != nil {
		api.StoreError(ctx, err)
		return
	}
	ctx.JSON(http.StatusOK, converter.ToOrgLLMErrorTimeSeriesView(item))
}

func (handler *ProviderHandler) LLMQuotaPoliciesList(ctx *gin.Context) {
	authenticated, ok := api.AuthenticatedUserFromContext(ctx)
	if !ok {
		api.Error(ctx, http.StatusUnauthorized, "Unauthorized")
		return
	}
	orgs, ok := handler.organizationProvider()
	if !ok {
		api.Error(ctx, http.StatusNotFound, "Organization provider not installed")
		return
	}
	organizationID := strings.TrimSpace(ctx.Param("orgId"))
	if organizationID == "" {
		api.Error(ctx, http.StatusBadRequest, "orgId is required")
		return
	}
	items, err := orgs.ListOrganizationLLMQuotaPoliciesForUser(ctx.Request.Context(), authenticated.User.ID, organizationID)
	if err != nil {
		api.StoreError(ctx, err)
		return
	}
	ctx.JSON(http.StatusOK, converter.ToOrgLLMQuotaPolicyViews(items))
}

func (handler *ProviderHandler) LLMQuotaPolicyUpsert(ctx *gin.Context) {
	authenticated, ok := api.AuthenticatedUserFromContext(ctx)
	if !ok {
		api.Error(ctx, http.StatusUnauthorized, "Unauthorized")
		return
	}
	orgs, ok := handler.organizationProvider()
	if !ok {
		api.Error(ctx, http.StatusNotFound, "Organization provider not installed")
		return
	}
	organizationID := strings.TrimSpace(ctx.Param("orgId"))
	subjectType := strings.TrimSpace(ctx.Param("subjectType"))
	subjectID := strings.TrimSpace(ctx.Param("subjectId"))
	if organizationID == "" || subjectType == "" || subjectID == "" {
		api.Error(ctx, http.StatusBadRequest, "Invalid request")
		return
	}
	var request dto.OrganizationLLMQuotaPolicyUpsertRequest
	if err := ctx.ShouldBindJSON(&request); err != nil {
		api.Error(ctx, http.StatusBadRequest, "Invalid request body")
		return
	}
	item, err := orgs.UpsertOrganizationLLMQuotaPolicyForUser(ctx.Request.Context(), authenticated.User.ID, organizationID, organization.UpsertOrganizationLLMQuotaPolicyParams{
		SubjectType:   subjectType,
		SubjectID:     subjectID,
		DailyQuotaUSD: request.DailyQuotaUSD,
	})
	if err != nil {
		api.StoreError(ctx, err)
		return
	}
	ctx.JSON(http.StatusOK, converter.ToOrgLLMQuotaPolicyView(item))
}

func (handler *ProviderHandler) LLMQuotaPolicyDelete(ctx *gin.Context) {
	authenticated, ok := api.AuthenticatedUserFromContext(ctx)
	if !ok {
		api.Error(ctx, http.StatusUnauthorized, "Unauthorized")
		return
	}
	orgs, ok := handler.organizationProvider()
	if !ok {
		api.Error(ctx, http.StatusNotFound, "Organization provider not installed")
		return
	}
	organizationID := strings.TrimSpace(ctx.Param("orgId"))
	subjectType := strings.TrimSpace(ctx.Param("subjectType"))
	subjectID := strings.TrimSpace(ctx.Param("subjectId"))
	if organizationID == "" || subjectType == "" || subjectID == "" {
		api.Error(ctx, http.StatusBadRequest, "Invalid request")
		return
	}
	if err := orgs.DeleteOrganizationLLMQuotaPolicyForUser(ctx.Request.Context(), authenticated.User.ID, organizationID, subjectType, subjectID); err != nil {
		api.StoreError(ctx, err)
		return
	}
	ctx.JSON(http.StatusOK, dto.EmptyResponse{})
}

func organizationLLMStatsQueryFromRequest(ctx *gin.Context) organization.OrganizationLLMStatsQuery {
	if ctx == nil {
		return organization.OrganizationLLMStatsQuery{}
	}
	return organization.OrganizationLLMStatsQuery{
		Window:      strings.TrimSpace(ctx.Query("window")),
		SubjectType: strings.TrimSpace(ctx.Query("subjectType")),
		SubjectID:   strings.TrimSpace(ctx.Query("subjectId")),
		Model:       strings.TrimSpace(ctx.Query("model")),
		ProviderID:  strings.TrimSpace(ctx.Query("providerId")),
	}
}
