package binding

import "time"

const (
	BindingStateDisabled = "disabled"
	BindingStateEnabled  = "enabled"
	BindingStateArchived = "archived"

	SourceKindSchedule = "schedule"

	SourceStatusActive    = "active"
	SourceStatusDisabled  = "disabled"
	SourceStatusCompleted = "completed"

	ActorTypeHuman = "human"
	ActorTypeAgent = "agent"

	// Idempotency scopes keep the child receipts materialized by Binding create
	// separate from the independently callable revision/activation actions. The
	// caller key alone is not an operation identity.
	IdempotencyScopeBindingCreate    = "binding_create"
	IdempotencyScopeRevisionCreate   = "revision_create"
	IdempotencyScopeRevisionActivate = "revision_activate"
)

// Actor is immutable command provenance. It does not grant execution
// authority; Owner is the independently resolved human authority.
type Actor struct {
	Type     string
	ID       string
	MemberID string
}

// Owner is the canonical human execution authority captured when a Binding is
// created. Store mutations deliberately expose no way to replace it.
type Owner struct {
	UserID   string
	MemberID string
}

// RevisionRef identifies one immutable Binding revision.
type RevisionRef struct {
	ID       string
	Revision int64
}

// Binding is the stable deployment aggregate. PlanID and Owner are immutable;
// executable configuration lives in append-only Revision rows.
type Binding struct {
	ID                   string
	WorkspaceID          string
	PlanID               string
	PlanDisplayName      string
	Key                  string
	DisplayName          string
	DescriptionMD        string
	State                string
	Revision             int64
	LatestRevision       RevisionRef
	ActiveRevision       *RevisionRef
	ActiveSourceID       string
	Owner                Owner
	CreateIdempotencyKey string
	CreateRequestDigest  string
	CreatedBy            Actor
	CreatedAt            time.Time
	UpdatedBy            Actor
	UpdatedAt            time.Time
	ArchivedBy           *Actor
	ArchivedAt           *time.Time
}

// Revision is an immutable deployment snapshot. ConfigJSON is the canonical
// normalized Binding config owned by the Binding service; the store only keeps
// its indexed source discriminator and durable semantic digest alongside it.
type Revision struct {
	ID                     string
	WorkspaceID            string
	BindingID              string
	PlanID                 string
	Revision               int64
	PlanVersionID          string
	SourceKind             string
	ConfigJSON             []byte
	Digest                 string
	CreateIdempotencyScope string
	CreateIdempotencyKey   string
	CreateRequestDigest    string
	CreatedBy              Actor
	CreatedAt              time.Time
}

// Source is one mutable activation reservation for an immutable Revision.
// Activating the same Revision again creates a new Source rather than reviving
// or mutating a historical reservation.
type Source struct {
	ID                         string
	WorkspaceID                string
	BindingID                  string
	BindingRevisionID          string
	Activation                 int64
	SourceKind                 string
	Status                     string
	Revision                   int64
	NextOccurrenceAt           *time.Time
	ActivationIdempotencyScope string
	ActivationIdempotencyKey   string
	ActivationRequestDigest    string
	ActivatedBy                Actor
	ActivatedAt                time.Time
	ClosedAt                   *time.Time
	ClosedReason               string
	CreatedAt                  time.Time
	UpdatedAt                  time.Time
}

type CreateResult struct {
	Binding  Binding
	Revision Revision
	Source   *Source
	Replayed bool
}

// ReplayCommandResult is the persisted response snapshot for one Binding
// command receipt. Revision is populated only by commands whose response
// includes an immutable BindingRevision.
type ReplayCommandResult struct {
	Binding  Binding
	Revision *Revision
}

type CreateRevisionResult struct {
	Binding  Binding
	Revision Revision
	Replayed bool
}

type ActivateResult struct {
	Binding  Binding
	Revision Revision
	Source   Source
	Replayed bool
}
