package audit

import (
	"sync"
	"time"
)

const defaultMaxEvents = 500

// Store retains recent governance events for dashboard APIs (in-memory MVP).
type Store struct {
	mu     sync.RWMutex
	events []Event
	max    int
}

// NewStore creates an in-memory event ring buffer.
func NewStore(max int) *Store {
	if max <= 0 {
		max = defaultMaxEvents
	}
	return &Store{max: max}
}

// Add appends an event, dropping oldest when at capacity.
func (s *Store) Add(e Event) {
	s.mu.Lock()
	defer s.mu.Unlock()
	if e.Timestamp.IsZero() {
		e.Timestamp = time.Now().UTC()
	}
	s.events = append(s.events, e)
	if len(s.events) > s.max {
		s.events = s.events[len(s.events)-s.max:]
	}
}

// List returns the most recent events, newest first.
func (s *Store) List(limit int) []Event {
	s.mu.RLock()
	defer s.mu.RUnlock()
	n := len(s.events)
	if n == 0 {
		return nil
	}
	if limit <= 0 || limit > n {
		limit = n
	}
	out := make([]Event, limit)
	for i := 0; i < limit; i++ {
		out[i] = s.events[n-1-i]
	}
	return out
}

// Summary holds aggregate governance metrics for the dashboard.
type Summary struct {
	TotalEvents   int     `json:"total_events"`
	AllowCount    int     `json:"allow_count"`
	DenyCount     int     `json:"deny_count"`
	EscalateCount int     `json:"escalate_count"`
	AllowPct      float64 `json:"allow_pct"`
	DenyPct       float64 `json:"deny_pct"`
	EscalatePct   float64 `json:"escalate_pct"`
	ActiveAgents  int     `json:"active_agents"`
	HighRiskCount int     `json:"high_risk_count"`
}

// Metrics computes summary stats from stored events.
func (s *Store) Metrics() Summary {
	s.mu.RLock()
	defer s.mu.RUnlock()
	var sum Summary
	sum.TotalEvents = len(s.events)
	agents := make(map[string]struct{})
	for _, e := range s.events {
		agents[e.AgentID] = struct{}{}
		switch e.Decision {
		case "allow":
			sum.AllowCount++
		case "deny":
			sum.DenyCount++
		case "escalate":
			sum.EscalateCount++
		}
		if e.RiskScore != nil && *e.RiskScore > 0.8 {
			sum.HighRiskCount++
		}
	}
	sum.ActiveAgents = len(agents)
	if sum.TotalEvents > 0 {
		sum.AllowPct = float64(sum.AllowCount) / float64(sum.TotalEvents) * 100
		sum.DenyPct = float64(sum.DenyCount) / float64(sum.TotalEvents) * 100
		sum.EscalatePct = float64(sum.EscalateCount) / float64(sum.TotalEvents) * 100
	}
	return sum
}
