package domain

import (
	"time"
)

// Entity is the core graph node — every object in the OS is an entity.
// Typed tables (signals, executions, etc.) reference entities(id) for
// indexed querying; graph edges live in the relationships table.
type Entity struct {
	ID              UUID
	Slug            string
	Type            string
	Name            string
	State           string
	Attributes      map[string]any
	MaintenanceUntil *time.Time
	Version         int
	CreatedAt       time.Time
	UpdatedAt       time.Time
}

// EntityType is the meta-schema entry defining what entities can exist.
type EntityType struct {
	Name            string
	ParentType      string
	IsAbstract      bool
	Domain          string
	Layer           string
	Description     string
	LifecycleID     string
	AttributeSchema map[string]any
	SchemaVersion   int
	Status          string
}

// RelationshipType defines a typed edge between entity types.
type RelationshipType struct {
	Name        string
	Inverse     string
	SourceType  string
	TargetType  string
	Cardinality string
	Description string
}

// LifecycleDef is the state machine for an entity type.
type LifecycleDef struct {
	ID             string
	States         []string
	DefaultState   string
	TerminalStates []string
	Transitions    map[string]map[string]TransitionReq
}

// TransitionReq holds the named preconditions for a lifecycle transition.
type TransitionReq struct {
	Requires []string `json:"requires"`
}

// Relationship is a typed edge between two entities.
type Relationship struct {
	SourceID   UUID
	TargetID   UUID
	Type       string
	Attributes map[string]any
	ValidFrom  time.Time
	ValidTo    *time.Time
}

// UUID is a type alias for UUID values. Using string for simplicity;
// the DB layer uses pgx's UUID type. Conversion happens at the boundary.
type UUID string

// IsNil returns true if the UUID is empty.
func (u UUID) IsNil() bool { return u == "" }
