package ports

import (
	"context"
	"encoding/json"
	"time"

	"github.com/dtoro/oikos/internal/core/domain"
)

// CheckDef is a health-check definition (subset of the check_defs row the
// observe pass consumes; grows with the probe adapters in Phase 5).
type CheckDef struct {
	ID         domain.UUID
	EntityID   domain.UUID
	Kind       string
	Name       string
	Config     json.RawMessage
	IntervalS  int
	Enabled    bool
	Severity   string
	CreatedAt  time.Time
	UpdatedAt  time.Time
}

// CheckResult is what one probe run produces.
type CheckResult struct {
	Value   float64
	State   string // "ok", "warning", "critical", "unknown"
	Message string
}

// Checker probes one check kind. One adapter per kind under adapters/probes;
// the ObservationService picks the adapter by CheckDef.Kind.
type Checker interface {
	Check(ctx context.Context, def CheckDef, target Target) CheckResult
}

// MetricSample is one metric observation to record.
type MetricSample struct {
	Metric    string
	Value     float64
	Timestamp time.Time
}

// MetricsRepository records observe-pass metrics (Timescale write path;
// bucketed/trend reads belong to ReadModels).
type MetricsRepository interface {
	InsertSamples(ctx context.Context, entityID domain.UUID, samples []MetricSample) error
}

// CheckRepository — monitoring definitions. EnsureFor is the read-diff-write
// derivation in one transaction.
type CheckRepository interface {
	ListEnabled(ctx context.Context) ([]CheckDef, error)
	ListFor(ctx context.Context, entityID domain.UUID) ([]CheckDef, error)
	// EnsureFor inserts defs that are missing, updates changed ones, and
	// removes stale ones for the entity — atomically.
	EnsureFor(ctx context.Context, entityID domain.UUID, desired []CheckDef) error
	SetEnabled(ctx context.Context, checkID domain.UUID, enabled bool) error
}
