package fn_operations

import "time"

// EntityStatus represents the lifecycle state of an entity.
type EntityStatus string

const (
	StatusActive    EntityStatus = "active"
	StatusStale     EntityStatus = "stale"
	StatusCorrupted EntityStatus = "corrupted"
	StatusArchived  EntityStatus = "archived"
)

// RelationStatus represents the lifecycle state of a relation.
type RelationStatus string

const (
	RelDesigned    RelationStatus = "designed"
	RelImplemented RelationStatus = "implemented"
	RelTested      RelationStatus = "tested"
	RelRunning     RelationStatus = "running"
	RelDeprecated  RelationStatus = "deprecated"
)

// Direction represents the directionality of a relation.
type Direction string

const (
	DirUnidirectional Direction = "unidirectional"
	DirBidirectional  Direction = "bidirectional"
	DirInverse        Direction = "inverse"
)

// Entity is a concrete instance of a registry type within a project context.
type Entity struct {
	ID          string            `json:"id"`
	Name        string            `json:"name"`
	TypeRef     string            `json:"type_ref"`
	Status      EntityStatus      `json:"status"`
	Description string            `json:"description"`
	Domain      string            `json:"domain"`
	Tags        []string          `json:"tags"`
	Source      string            `json:"source"`
	Metadata    map[string]any    `json:"metadata"`
	Notes       string            `json:"notes"`
	CreatedAt   time.Time         `json:"created_at"`
	UpdatedAt   time.Time         `json:"updated_at"`
}

// Relation describes how one entity connects to or transforms into another.
type Relation struct {
	ID          string         `json:"id"`
	Name        string         `json:"name"`
	FromEntity  string         `json:"from_entity"`
	ToEntity    string         `json:"to_entity"`
	Via         string         `json:"via"`
	Description string         `json:"description"`
	Purity      string         `json:"purity"`
	Direction   Direction      `json:"direction"`
	Weight      *float64       `json:"weight"`
	Status      RelationStatus `json:"status"`
	StartedAt   *time.Time     `json:"started_at"`
	EndedAt     *time.Time     `json:"ended_at"`
	Order       *int           `json:"order"`
	Tags        []string       `json:"tags"`
	Notes       string         `json:"notes"`
	CreatedAt   time.Time      `json:"created_at"`
	UpdatedAt   time.Time      `json:"updated_at"`
}

// RelationInput represents one input entity in a multi-input relation.
type RelationInput struct {
	ID         string `json:"id"`
	RelationID string `json:"relation_id"`
	EntityID   string `json:"entity_id"`
	Role       string `json:"role"`
	Order      *int   `json:"order"`
}

// ExecutionStatus represents the result of a pipeline execution.
type ExecutionStatus string

const (
	ExecSuccess ExecutionStatus = "success"
	ExecFailure ExecutionStatus = "failure"
	ExecPartial ExecutionStatus = "partial"
)

// Severity classifies the impact of an assertion failure.
type Severity string

const (
	SeverityCritical Severity = "critical"
	SeverityWarning  Severity = "warning"
	SeverityInfo     Severity = "info"
)

// AssertionResultStatus represents the outcome of an assertion evaluation.
type AssertionResultStatus string

const (
	ResultPass AssertionResultStatus = "pass"
	ResultFail AssertionResultStatus = "fail"
	ResultSkip AssertionResultStatus = "skip"
)

// Execution records a pipeline run with its metrics and outcome.
type Execution struct {
	ID         string          `json:"id"`
	PipelineID string          `json:"pipeline_id"`
	RelationID string          `json:"relation_id"`
	Status     ExecutionStatus `json:"status"`
	StartedAt  time.Time       `json:"started_at"`
	EndedAt    *time.Time      `json:"ended_at"`
	DurationMs *int64          `json:"duration_ms"`
	RecordsIn  *int64          `json:"records_in"`
	RecordsOut *int64          `json:"records_out"`
	Error      string          `json:"error"`
	Metrics    map[string]any  `json:"metrics"`
	CreatedAt  time.Time       `json:"created_at"`
}

// Assertion is a formal quality rule evaluated against an entity.
type Assertion struct {
	ID          string   `json:"id"`
	EntityID    string   `json:"entity_id"`
	Name        string   `json:"name"`
	Kind        string   `json:"kind"` // free text: range, null, statistical, consistency, freshness, ...
	Rule        string   `json:"rule"`
	Severity    Severity `json:"severity"`
	Description string   `json:"description"`
	Active      bool     `json:"active"`
	CreatedAt   time.Time `json:"created_at"`
}

// AssertionResult records one evaluation of an assertion.
type AssertionResult struct {
	ID          string                `json:"id"`
	AssertionID string                `json:"assertion_id"`
	ExecutionID string                `json:"execution_id"`
	Status      AssertionResultStatus `json:"status"`
	Value       map[string]any        `json:"value"`
	Message     string                `json:"message"`
	EvaluatedAt time.Time             `json:"evaluated_at"`
}

// LogLevel represents the severity of a log entry.
type LogLevel string

const (
	LogDebug LogLevel = "debug"
	LogInfo  LogLevel = "info"
	LogWarn  LogLevel = "warn"
	LogError LogLevel = "error"
)

// Log is a free-form operational event within a project context.
type Log struct {
	ID          string         `json:"id"`
	Level       LogLevel       `json:"level"`
	Source      string         `json:"source"`       // who: agent, pipeline, reactive_loop, function name...
	EntityID    string         `json:"entity_id"`    // optional context
	ExecutionID string         `json:"execution_id"` // optional context
	Message     string         `json:"message"`
	Metadata    map[string]any `json:"metadata"`
	CreatedAt   time.Time      `json:"created_at"`
}

// E2ETestStatus represents the result of an e2e test run.
type E2ETestStatus string

const (
	E2EPass    E2ETestStatus = "pass"
	E2EFail    E2ETestStatus = "fail"
	E2ESkip    E2ETestStatus = "skip"
	E2EPending E2ETestStatus = ""
)

// E2ETest is an integration test that verifies function composition within an app.
type E2ETest struct {
	ID           string         `json:"id"`
	Name         string         `json:"name"`
	Description  string         `json:"description"`
	RelationID   string         `json:"relation_id"`
	Steps        []string       `json:"steps"`
	InputFixture map[string]any `json:"input_fixture"`
	Expected     map[string]any `json:"expected"`
	LastStatus   E2ETestStatus  `json:"last_status"`
	LastRunAt    string         `json:"last_run_at"`
	ExecutionID  string         `json:"execution_id"`
	DurationMs   int64          `json:"duration_ms"`
	CreatedAt    time.Time      `json:"created_at"`
	UpdatedAt    time.Time      `json:"updated_at"`
}

// TypeSnapshot is an immutable copy of a registry type at point of use.
type TypeSnapshot struct {
	ID          string    `json:"id"`
	Version     string    `json:"version"`
	Lang        string    `json:"lang"`
	Algebraic   string    `json:"algebraic"`
	Definition  string    `json:"definition"`
	Description string    `json:"description"`
	SnappedAt   time.Time `json:"snapped_at"`
}
