package agent

import (
	"context"
	"net/http"
	"strings"

	"github.com/gin-gonic/gin"

	"github.com/tidbcloud/AgentTeam/internal/api/dto"
	"github.com/tidbcloud/AgentTeam/internal/api/dto/converter"
	"github.com/tidbcloud/AgentTeam/internal/store/agent"
	"github.com/tidbcloud/AgentTeam/internal/trigger"
)

// TriggerOwnerStore resolves the owning user and target scope for trigger operations.
type TriggerOwnerStore interface {
	AgentManagedByUser(ctx context.Context, workspaceID string, agentID string) (string, error)
	ResolveWritableAgentTargetScopeID(ctx context.Context, agent agent.AuthenticatedAgent, target string) (string, error)
}

func (h *TriggerHandler) handleLifecycleMutation(c *gin.Context, authenticatedAgent agent.AuthenticatedAgent, fn func(context.Context, TriggerControlService, string, string, string) (trigger.TriggerView, error)) {
	triggers := h.requireTriggerService(c)
	if triggers == nil {
		return
	}

	ownerUserID, err := h.owners.AgentManagedByUser(c.Request.Context(), authenticatedAgent.WorkspaceID, authenticatedAgent.AgentID)
	if err != nil {
		c.JSON(HTTPStatus(err), agentError(err.Error()))
		return
	}

	result, err := fn(c.Request.Context(), triggers, ownerUserID, authenticatedAgent.WorkspaceID, scheduleOrTriggerID(c))
	if err != nil {
		c.JSON(HTTPStatus(err), agentError(err.Error()))
		return
	}
	c.JSON(http.StatusOK, result)
}

func scheduleOrTriggerID(c *gin.Context) string {
	if c == nil {
		return ""
	}
	if scheduleID := strings.TrimSpace(c.Param("scheduleId")); scheduleID != "" {
		return scheduleID
	}
	return strings.TrimSpace(c.Param("triggerId"))
}

func (h *TriggerHandler) triggerInputForAgent(ctx context.Context, authenticatedAgent agent.AuthenticatedAgent, request dto.AgentTriggerMutationRequest) (string, trigger.UpsertInput, error) {
	ownerUserID, err := h.owners.AgentManagedByUser(ctx, authenticatedAgent.WorkspaceID, authenticatedAgent.AgentID)
	if err != nil {
		return "", trigger.UpsertInput{}, err
	}

	targetRef, err := h.owners.ResolveWritableAgentTargetScopeID(ctx, authenticatedAgent, strings.TrimSpace(request.Target))
	if err != nil {
		return "", trigger.UpsertInput{}, err
	}

	return ownerUserID, trigger.UpsertInput{
		Name:                  request.Name,
		Source:                request.Source,
		Target:                trigger.TargetInput{Ref: targetRef},
		MessageTemplate:       request.MessageTemplate,
		MentionHints:          converter.FromScheduleMentionHints(request.Mentions),
		MentionHintsSet:       request.Mentions != nil,
		HumanNotificationMode: request.HumanNotificationMode,
	}, nil
}
