package invocation

import (
	"time"

	domain "github.com/tidbcloud/AgentTeam/internal/workflow/invocation"
)

const (
	SourceKindManual   = domain.SourceKindManual
	SourceKindSchedule = domain.SourceKindSchedule
	ActorTypeHuman     = domain.ActorTypeHuman
	ActorTypeAgent     = domain.ActorTypeAgent
	RunStatusQueued    = domain.RunStatusQueued
	RunEventAccepted   = domain.RunEventAccepted
)

func InputDigest(input []byte) string { return domain.InputDigest(input) }

type Actor = domain.Actor
type ExecutionIdentitySnapshot = domain.ExecutionIdentitySnapshot
type Invocation = domain.Invocation
type Run = domain.Run
type RunEvent = domain.RunEvent
type AcceptResult = domain.AcceptResult

// Principal is the trusted current human authority behind a direct caller.
// The store revalidates it under lock and freezes it as owner, principal, and
// visible author. InvokedBy separately records the actual Human or Agent.
type Principal struct {
	UserID   string
	MemberID string
	Role     string
}

// ScheduleDeploymentFence identifies the exact automatic deployment inspected
// before cursor materialization. Acceptance rechecks it under lock.
type ScheduleDeploymentFence struct {
	BindingSourceID   string
	BindingRevisionID string
	PlanVersionID     string
	RevisionDigest    string
}

// ManualPlanVersion is the exact executable material selected for a direct
// manual Invocation. RequestedPlanVersionID is empty when the default role was
// requested; PlanVersionID is always the frozen immutable version.
type ManualPlanVersion struct {
	WorkspaceID            string
	PlanID                 string
	RequestedPlanVersionID string
	PlanVersionID          string
	WorkflowName           string
	PlanArtifactJSON       []byte
	PlanCompilerVersion    string
	PlanVersionDigest      string
}

type AcceptManualParams struct {
	WorkspaceID            string
	PlanID                 string
	RequestedPlanVersionID string
	ExpectedPlanVersionID  string
	ExpectedVersionDigest  string
	RequestInputJSON       []byte
	InputJSON              []byte
	Principal              Principal
	InvokedBy              Actor
	IdempotencyKey         string
	Now                    time.Time
	// TeamID is the caller-requested Team for an unlinked/dynamic Run. It is
	// server-authorized and frozen. When the Plan is already Team-linked, the
	// approved relation's Team is authoritative and a conflicting explicit value
	// is rejected.
	TeamID string
}

// AcceptParams is the transaction-level primitive shared by manual acceptance
// and the schedule dispatcher. Schedule callers must advance/close their
// source cursor in the same outer transaction after this method succeeds.
type AcceptParams struct {
	WorkspaceID      string
	BindingID        string
	Expected         ScheduleDeploymentFence
	SourceKind       string
	OccurrenceAt     *time.Time
	RequestInputJSON []byte
	InputJSON        []byte
	IdempotencyKey   string
	Now              time.Time
}

type ReplayManualParams struct {
	WorkspaceID            string
	PlanID                 string
	RequestedPlanVersionID string
	RequestInputJSON       []byte
	InvokedBy              Actor
	IdempotencyKey         string
	// TeamID is part of the manual request identity so a retry that changes the
	// Team cannot replay an old frozen receipt.
	TeamID string
}

type ListParams struct {
	WorkspaceID      string
	PlanID           string
	Limit            int
	BeforeAcceptedAt time.Time
	BeforeID         string
}

// ListItem is the bounded collection projection. It deliberately excludes the
// potentially multi-megabyte input and provenance documents; callers fetch
// those only from the Invocation detail resource.
type ListItem struct {
	Invocation Invocation
	RunStatus  string
}
