package metrics

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

	"github.com/sirupsen/logrus"
)

type Metrics struct {
	ActiveConnections int64
	TotalRequests     int64
	FailedRequests    int64
	BytesTransferred  int64
	StartTime         time.Time
	mu                sync.RWMutex
	logger            *logrus.Logger
}

func NewMetrics(logger *logrus.Logger) *Metrics {
	return &Metrics{
		StartTime: time.Now(),
		logger:    logger,
	}
}

func (m *Metrics) IncActiveConnections() {
	atomic.AddInt64(&m.ActiveConnections, 1)
	m.logger.WithField("active_connections", atomic.LoadInt64(&m.ActiveConnections)).Debug("Connection opened")
}

func (m *Metrics) DecActiveConnections() {
	atomic.AddInt64(&m.ActiveConnections, -1)
	m.logger.WithField("active_connections", atomic.LoadInt64(&m.ActiveConnections)).Debug("Connection closed")
}

func (m *Metrics) IncTotalRequests() {
	atomic.AddInt64(&m.TotalRequests, 1)
}

func (m *Metrics) IncFailedRequests() {
	atomic.AddInt64(&m.FailedRequests, 1)
}

func (m *Metrics) AddBytesTransferred(bytes int64) {
	atomic.AddInt64(&m.BytesTransferred, bytes)
}

func (m *Metrics) GetStats() map[string]interface{} {
	uptime := time.Since(m.StartTime)

	return map[string]interface{}{
		"active_connections": atomic.LoadInt64(&m.ActiveConnections),
		"total_requests":     atomic.LoadInt64(&m.TotalRequests),
		"failed_requests":    atomic.LoadInt64(&m.FailedRequests),
		"bytes_transferred":  atomic.LoadInt64(&m.BytesTransferred),
		"uptime_seconds":     uptime.Seconds(),
		"start_time":         m.StartTime.Format(time.RFC3339),
	}
}

func (m *Metrics) LogStats() {
	stats := m.GetStats()
	m.logger.WithFields(logrus.Fields(stats)).Info("Server metrics")
}

// StartPeriodicLogging starts logging metrics at regular intervals
func (m *Metrics) StartPeriodicLogging(interval time.Duration) {
	ticker := time.NewTicker(interval)
	go func() {
		for range ticker.C {
			m.LogStats()
		}
	}()
}
