package trigger

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

	"github.com/gin-gonic/gin"

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

const triggerServiceNotConfiguredMessage = "Trigger service is not configured"

type triggerHandlerBase struct {
	triggerService TriggerService
}

// CollectionHandler owns trigger collection routes.
type CollectionHandler struct {
	triggerHandlerBase
}

// ValidationHandler owns trigger validation routes.
type ValidationHandler struct {
	triggerHandlerBase
}

// DetailHandler owns trigger detail, update, and delete routes.
type DetailHandler struct {
	triggerHandlerBase
}

// LifecycleHandler owns trigger pause and resume routes.
type LifecycleHandler struct {
	triggerHandlerBase
}

// RunHandler owns trigger run-history routes.
type RunHandler struct {
	triggerHandlerBase
}

type routeHandlers struct {
	collection *CollectionHandler
	validation *ValidationHandler
	detail     *DetailHandler
	lifecycle  *LifecycleHandler
	runs       *RunHandler
}

func newRouteHandlers(dependencies Dependencies) routeHandlers {
	triggerService := dependencies.TriggerService
	if triggerService == nil {
		triggerService = notConfiguredTriggerService{}
	}
	base := triggerHandlerBase{triggerService: triggerService}
	return routeHandlers{
		collection: &CollectionHandler{triggerHandlerBase: base},
		validation: &ValidationHandler{triggerHandlerBase: base},
		detail:     &DetailHandler{triggerHandlerBase: base},
		lifecycle:  &LifecycleHandler{triggerHandlerBase: base},
		runs:       &RunHandler{triggerHandlerBase: base},
	}
}

type notConfiguredTriggerService struct{}

func (notConfiguredTriggerService) ListForOwnerWithFilter(context.Context, string, string, trigger.ListFilter) ([]trigger.TriggerView, error) {
	return nil, triggerServiceNotConfiguredError()
}

func (notConfiguredTriggerService) ValidateForOwner(context.Context, string, string, trigger.UpsertInput, string) (trigger.ValidateResult, error) {
	return trigger.ValidateResult{}, triggerServiceNotConfiguredError()
}

func (notConfiguredTriggerService) CreateForOwner(context.Context, string, string, trigger.UpsertInput) (trigger.TriggerView, error) {
	return trigger.TriggerView{}, triggerServiceNotConfiguredError()
}

func (notConfiguredTriggerService) GetForOwner(context.Context, string, string, string) (trigger.TriggerView, error) {
	return trigger.TriggerView{}, triggerServiceNotConfiguredError()
}

func (notConfiguredTriggerService) UpdateForOwner(context.Context, string, string, string, trigger.UpsertInput) (trigger.TriggerView, error) {
	return trigger.TriggerView{}, triggerServiceNotConfiguredError()
}

func (notConfiguredTriggerService) PauseForOwner(context.Context, string, string, string) (trigger.TriggerView, error) {
	return trigger.TriggerView{}, triggerServiceNotConfiguredError()
}

func (notConfiguredTriggerService) ResumeForOwner(context.Context, string, string, string) (trigger.TriggerView, error) {
	return trigger.TriggerView{}, triggerServiceNotConfiguredError()
}

func (notConfiguredTriggerService) DeleteForOwner(context.Context, string, string, string) error {
	return triggerServiceNotConfiguredError()
}

func (notConfiguredTriggerService) ListRunsForOwner(context.Context, string, string, string, int) ([]trigger.RunView, error) {
	return nil, triggerServiceNotConfiguredError()
}

func triggerServiceNotConfiguredError() error {
	return api.NewHTTPError(http.StatusNotImplemented, triggerServiceNotConfiguredMessage)
}

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