// Package invocation persists immutable Workflow Invocations and the
// one queued first-class Run atomically created for each accepted occurrence.
package invocation

import (
	"errors"
	"fmt"
	"strings"

	"github.com/tidbcloud/AgentTeam/internal/coredb"
	"github.com/tidbcloud/AgentTeam/internal/store/storeerr"
)

const (
	defaultListLimit = 50
	maxListLimit     = 101
)

var (
	ErrNotFound   = storeerr.ErrNotFound
	ErrConflict   = storeerr.ErrConflict
	ErrBadRequest = storeerr.ErrBadRequest

	ErrInactiveDeployment     = errors.New("workflow invocation deployment is inactive")
	ErrPlanVersionUnavailable = errors.New("workflow invocation Plan version is unavailable")
	ErrOwnerUnavailable       = errors.New("workflow invocation execution owner is unavailable")
	ErrPrincipalUnavailable   = errors.New("workflow invocation principal is unavailable")
	ErrDeploymentChanged      = errors.New("workflow invocation deployment changed")
)

type IdempotencyConflictError struct{}

func (IdempotencyConflictError) Error() string {
	return "workflow invocation idempotency key was already used for a different request"
}
func (IdempotencyConflictError) Unwrap() error { return ErrConflict }

type OccurrenceConflictError struct{}

func (OccurrenceConflictError) Error() string {
	return "workflow invocation source occurrence was already accepted with different input"
}
func (OccurrenceConflictError) Unwrap() error { return ErrConflict }

// StoreOptions configures optional Invocation scheduler behavior.
type StoreOptions struct {
	// WorkspaceGroupID restricts schedule scans and materialization to
	// workspaces currently routed to one workspace profile group. Empty keeps
	// monolith and management callers unrestricted while retaining placement
	// fencing.
	WorkspaceGroupID string
}

type Store struct {
	db               coredb.DB
	workspaceGroupID string
}

func New(db coredb.DB) *Store { return NewWithOptions(db, StoreOptions{}) }

// NewWithOptions constructs a Store with optional scheduler placement scope.
func NewWithOptions(db coredb.DB, options StoreOptions) *Store {
	return &Store{db: db, workspaceGroupID: strings.TrimSpace(options.WorkspaceGroupID)}
}

func (store *Store) schedulerWorkspaceGroupID() string {
	if store == nil {
		return ""
	}
	return strings.TrimSpace(store.workspaceGroupID)
}

func (store *Store) Validate() error {
	if store == nil || store.db == nil {
		return fmt.Errorf("workflow invocation store database is not configured")
	}
	return nil
}
