package wire

import (
	"sync"
	"sync/atomic"
	"time"
)

// metricsCollector tracks AgentTeam-specific operational metrics.
// All fields use atomic operations and are safe for concurrent access.
// The zero value is valid and ready to use.
type metricsCollector struct {
	// WebSocket connection
	reconnects  atomic.Uint64
	connectedAt atomic.Int64 // Unix timestamp; 0 if disconnected

	// Inbound
	dedupHits atomic.Uint64

	// Outbound
	sendSuccess atomic.Uint64
	sendErrors  atomic.Uint64
	sendDropped atomic.Uint64 // send buffer full drops

	// Latency tracking (outbound HTTP sends)
	latencyMu        sync.Mutex
	sendLatencySum   time.Duration
	sendLatencyCount uint64

	// API client retries
	apiRetries atomic.Uint64

	// Agent lifecycle
	agentStarts atomic.Uint64
	agentStops  atomic.Uint64
	agentSleeps atomic.Uint64
}

// AgentTeamMetricsSummary holds a snapshot of AgentTeam-specific metrics.
type AgentTeamMetricsSummary struct {
	Reconnects       uint64  `json:"reconnects"`
	ConnectedSince   int64   `json:"connectedSince,omitempty"`
	DedupHits        uint64  `json:"dedupHits"`
	SendSuccess      uint64  `json:"sendSuccess"`
	SendErrors       uint64  `json:"sendErrors"`
	SendDropped      uint64  `json:"sendDropped"`
	AvgSendLatencyMs float64 `json:"avgSendLatencyMs"`
	APIRetries       uint64  `json:"apiRetries"`
	AgentStarts      uint64  `json:"agentStarts"`
	AgentStops       uint64  `json:"agentStops"`
	AgentSleeps      uint64  `json:"agentSleeps"`
}

// Summary returns a snapshot of all AgentTeam-specific metrics.
func (m *metricsCollector) Summary() AgentTeamMetricsSummary {
	m.latencyMu.Lock()
	avgMs := float64(0)
	if m.sendLatencyCount > 0 {
		avgMs = float64(m.sendLatencySum.Milliseconds()) / float64(m.sendLatencyCount)
	}
	m.latencyMu.Unlock()

	return AgentTeamMetricsSummary{
		Reconnects:       m.reconnects.Load(),
		ConnectedSince:   m.connectedAt.Load(),
		DedupHits:        m.dedupHits.Load(),
		SendSuccess:      m.sendSuccess.Load(),
		SendErrors:       m.sendErrors.Load(),
		SendDropped:      m.sendDropped.Load(),
		AvgSendLatencyMs: avgMs,
		APIRetries:       m.apiRetries.Load(),
		AgentStarts:      m.agentStarts.Load(),
		AgentStops:       m.agentStops.Load(),
		AgentSleeps:      m.agentSleeps.Load(),
	}
}

// recordSendLatency records the duration of a successful outbound HTTP send.
func (m *metricsCollector) recordSendLatency(d time.Duration) {
	m.latencyMu.Lock()
	m.sendLatencySum += d
	m.sendLatencyCount++
	m.latencyMu.Unlock()
}

// MetricsSummary returns AgentTeam-specific operational metrics.
func (c *Protocol) MetricsSummary() AgentTeamMetricsSummary {
	return c.metrics.Summary()
}
