package domain

import (
	"context"
	"time"
)

// SignozRepository defines the interface for interacting with Signoz API
type SignozRepository interface {
	// Connection management
	TestConnection(ctx context.Context) (*ConnectionStatus, error)

	// Dashboard operations
	GetDashboards(ctx context.Context) ([]Dashboard, error)
	GetDashboardDetails(ctx context.Context, dashboardID string) (*Dashboard, error)
	GetDashboardData(ctx context.Context, dashboardName string, timeRange TimeRange) (*DashboardData, error)

	// Service operations
	GetServices(ctx context.Context, timeRange *TimeRange) ([]Service, error)
	GetAPMMetrics(ctx context.Context, serviceName string, timeRange TimeRange) (*APMMetrics, error)

	// Query operations
	ExecuteClickHouseQuery(ctx context.Context, query ClickHouseQuery) (*QueryResult, error)
	ExecuteBuilderQuery(ctx context.Context, query BuilderQuery) (*QueryResult, error)

	// Trace and log operations
	GetTracesOrLogs(ctx context.Context, dataType string, timeRange TimeRange, serviceName string, limit int) ([]TraceLog, error)
}

// MCPService defines the interface for MCP tool implementations
type MCPService interface {
	// Tool implementations
	TestConnection(ctx context.Context) (*ConnectionStatus, error)
	FetchDashboards(ctx context.Context) ([]Dashboard, error)
	FetchDashboardDetails(ctx context.Context, dashboardID string) (*Dashboard, error)
	FetchDashboardData(ctx context.Context, dashboardName string, startTime, endTime time.Time) (*DashboardData, error)
	FetchAPMMetrics(ctx context.Context, serviceName string, startTime, endTime time.Time) (*APMMetrics, error)
	FetchServices(ctx context.Context, startTime, endTime *time.Time) ([]Service, error)
	ExecuteClickHouseQuery(ctx context.Context, sql string, startTime, endTime time.Time, params map[string]interface{}) (*QueryResult, error)
	ExecuteBuilderQuery(ctx context.Context, queryType, metricName, aggregation string, filters []QueryFilter, groupBy []string, startTime, endTime time.Time, step time.Duration, options map[string]interface{}) (*QueryResult, error)
	FetchTracesOrLogs(ctx context.Context, dataType string, startTime, endTime time.Time, serviceName string, limit int) ([]TraceLog, error)
}

// ConfigRepository defines the interface for configuration management
type ConfigRepository interface {
	GetSignozURL() string
	GetSignozAPIKey() string
	GetTimeout() time.Duration
	GetRetryAttempts() int
	GetRetryDelay() time.Duration
	Validate() error
}

// Logger defines the interface for structured logging
type Logger interface {
	Debug(msg string, fields ...Field)
	Info(msg string, fields ...Field)
	Warn(msg string, fields ...Field)
	Error(msg string, fields ...Field)
	Fatal(msg string, fields ...Field)
	With(fields ...Field) Logger
}

// Field represents a structured log field
type Field struct {
	Key   string
	Value interface{}
}

// Tracer defines the interface for distributed tracing
type Tracer interface {
	StartSpan(ctx context.Context, name string, opts ...SpanOption) (context.Context, Span)
}

// Span represents a tracing span
type Span interface {
	SetAttribute(key string, value interface{})
	SetStatus(code StatusCode, description string)
	RecordError(err error, opts ...EventOption)
	End()
}

// SpanOption represents span configuration options
type SpanOption interface {
	Apply(*SpanConfig)
}

// SpanConfig represents span configuration
type SpanConfig struct {
	Kind       SpanKind
	Attributes map[string]interface{}
}

// StatusCode represents span status codes
type StatusCode int

const (
	StatusCodeUnset StatusCode = iota
	StatusCodeOK
	StatusCodeError
)

// SpanKind represents the kind of span
type SpanKind int

const (
	SpanKindInternal SpanKind = iota
	SpanKindServer
	SpanKindClient
	SpanKindProducer
	SpanKindConsumer
)

// EventOption represents event configuration options
type EventOption interface {
	Apply(*EventConfig)
}

// EventConfig represents event configuration
type EventConfig struct {
	Attributes map[string]interface{}
}

// Metrics defines the interface for application metrics
type Metrics interface {
	Counter(name string) Counter
	Histogram(name string) Histogram
	Gauge(name string) Gauge
}

// Counter represents a counter metric
type Counter interface {
	Add(ctx context.Context, value int64, attributes ...Attribute)
}

// Histogram represents a histogram metric
type Histogram interface {
	Record(ctx context.Context, value float64, attributes ...Attribute)
}

// Gauge represents a gauge metric
type Gauge interface {
	Set(ctx context.Context, value float64, attributes ...Attribute)
}

// Attribute represents a metric attribute
type Attribute struct {
	Key   string
	Value interface{}
}

// HealthChecker defines the interface for health checking
type HealthChecker interface {
	Check(ctx context.Context) error
}

// RateLimiter defines the interface for rate limiting
type RateLimiter interface {
	Allow(ctx context.Context, key string) error
	Reset(ctx context.Context, key string) error
}

// Cache defines the interface for caching
type Cache interface {
	Get(ctx context.Context, key string) (interface{}, error)
	Set(ctx context.Context, key string, value interface{}, ttl time.Duration) error
	Delete(ctx context.Context, key string) error
	Clear(ctx context.Context) error
}
