package kbgovernance

import (
	"context"
	"time"
)

const (
	PublicationSubjectType   = "kb_publication"
	PublicationRequestType   = "kb_publication_request"
	PublicationPayloadSchema = 1
)

// PublicationPayload is the immutable review summary stored by AgentTeam's
// Approval domain. ContentDigest binds the request to the complete MeshX
// snapshot; PayloadDigest (on PreparedPublication) protects this envelope.
type PublicationPayload struct {
	SchemaVersion       int    `json:"schemaVersion"`
	WorkspaceID         string `json:"workspaceId"`
	KnowledgeBaseID     string `json:"knowledgeBaseId"`
	WorkingRevision     string `json:"workingRevision"`
	ContentDigest       string `json:"contentDigest"`
	SourceCount         int    `json:"sourceCount"`
	WikiReadyCount      int    `json:"wikiReadyCount"`
	DashboardReadyCount int    `json:"dashboardReadyCount"`
	SkippedCount        int    `json:"skippedCount"`
	RequesterID         string `json:"requesterId"`
	IdempotencyKey      string `json:"idempotencyKey"`
}

// PreparePublicationCommand asks the resource-domain KB authority to derive a
// canonical publication review from the current working revision. RequesterID
// comes from authenticated runtime context; source/readiness counts and content
// digests must be derived by the authority.
type PreparePublicationCommand struct {
	WorkspaceID     string
	KnowledgeBaseID string
	WorkingRevision string
	RequesterID     string
	IdempotencyKey  string
	CorrelationID   string
	Now             time.Time
}

// PreparedPublication is the immutable publication subject and complete
// resource snapshot produced for AgentTeam Approval. The digests bind the review
// summary to SnapshotJSON; it is not an API DTO or a published KB artifact.
type PreparedPublication struct {
	Payload       PublicationPayload
	PayloadJSON   []byte
	PayloadDigest string
	SnapshotJSON  []byte
	CorrelationID string
	PreparedAt    time.Time
}

// RecordPublicationApprovalCommand returns the Approval instance identity and
// version allocated by AgentTeam so the KB authority can durably correlate it with
// the prepared publication snapshot.
type RecordPublicationApprovalCommand struct {
	RequestID       string
	ApprovalID      string
	ApprovalVersion int64
	Prepared        PreparedPublication
	Now             time.Time
}

// PublicationState is the KB authority's persisted publication-governance
// state projected across the Approval gateway. It is distinct from AgentTeam's
// generic Approval instance and from the published KB revision.
type PublicationState struct {
	RequestID       string
	ApprovalID      string
	ApprovalVersion int64
	Status          string
	DomainVersion   int64
	Stale           bool
}

// PublicationApprover is the sanitized approver identity that AgentTeam derives
// from authoritative workspace assignments for resource-runtime presentation.
// It is not a caller-supplied assignment or workspace membership DTO.
type PublicationApprover struct {
	PrincipalID string
	DisplayName string
}

// InspectPublicationApprovalCommand asks AgentTeam Approval for the review facts
// visible to one authenticated actor. AgentTeam derives the actor's membership and
// assignment instead of accepting either from the resource runtime.
type InspectPublicationApprovalCommand struct {
	WorkspaceID      string
	ApprovalID       string
	ActorPrincipalID string
}

// PublicationApprovalReview is AgentTeam Approval's sanitized read projection for
// the resource runtime. Approvers and decision flags are authority-derived and
// must not be reused as mutable Approval or membership models.
type PublicationApprovalReview struct {
	Approvers     []PublicationApprover
	ActorAssigned bool
	CanDecide     bool
}

// ResolvePublicationApprovalCommand carries an authoritative AgentTeam Approval
// decision back to the KB authority, including the version and decision id used
// to reject stale or replayed publication transitions.
type ResolvePublicationApprovalCommand struct {
	WorkspaceID      string
	ApprovalID       string
	ApprovalVersion  int64
	ActorPrincipalID string
	ClientDecisionID string
	Decision         string
	Reason           string
	Now              time.Time
}

// SubmitPublicationCommand carries an authenticated actor and a publication
// envelope prepared by the KB authority into AgentTeam Approval. AgentTeam derives the
// member and approver assignments from core state.
type SubmitPublicationCommand struct {
	ActorPrincipalID string
	Prepared         PreparedPublication
}

// DecidePublicationCommand asks AgentTeam Approval to decide a publication review
// for the authenticated actor. Assignment and membership facts are absent by
// design and are resolved inside AgentTeam.
type DecidePublicationCommand struct {
	WorkspaceID      string
	ApprovalID       string
	ActorPrincipalID string
	ExpectedVersion  int64
	ClientDecisionID string
	Decision         string
	Reason           string
	CorrelationID    string
	Now              time.Time
}

// WithdrawPublicationCommand asks AgentTeam Approval to withdraw one publication
// review for the authenticated actor while enforcing the expected version and
// client request id.
type WithdrawPublicationCommand struct {
	WorkspaceID      string
	ApprovalID       string
	ActorPrincipalID string
	ExpectedVersion  int64
	ClientRequestID  string
	Now              time.Time
}

// PublicationApprovalGateway is implemented by AgentTeam's Approval control plane
// and consumed by the resource-domain KB runtime. It is the only port that may
// derive approver assignment and actor decision authority from AgentTeam core state.
type PublicationApprovalGateway interface {
	SubmitPublication(context.Context, SubmitPublicationCommand) (PublicationState, error)
	DecidePublication(context.Context, DecidePublicationCommand) (PublicationState, error)
	WithdrawPublication(context.Context, WithdrawPublicationCommand) (PublicationState, error)
	InspectPublication(context.Context, InspectPublicationApprovalCommand) (PublicationApprovalReview, error)
}

// PublicationAuthority is implemented by the resource-domain KB runtime and
// consumed by AgentTeam Approval. It owns snapshot preparation and persistence of
// Approval correlation and decision state.
type PublicationAuthority interface {
	PreparePublication(context.Context, PreparePublicationCommand) (PreparedPublication, error)
	RecordPublicationApproval(context.Context, RecordPublicationApprovalCommand) (PublicationState, error)
	ResolvePublicationApproval(context.Context, ResolvePublicationApprovalCommand) (PublicationState, error)
}

// Authority is the complete KB governance authority exposed by the embedded
// MeshX runtime to AgentTeam's generic Approval composition.
type Authority interface {
	WikiGenerationAuthority
	WikiGenerationTerminalAuthority
	PublicationAuthority
}
