package metrics

import (
	"sync"
	"veza-backend-api/internal/errors"
)

// ErrorMetrics collecte et stocke les métriques d'erreurs pour le monitoring
type ErrorMetrics struct {
	mu                 sync.RWMutex
	errorsByCode       map[errors.ErrorCode]int64
	errorsByHTTPStatus map[int]int64
	totalErrors        int64
	aggregated         *AggregatedMetrics // Agrégation par fenêtres de temps (T0029)
}

// NewErrorMetrics crée une nouvelle instance de ErrorMetrics
func NewErrorMetrics() *ErrorMetrics {
	return &ErrorMetrics{
		errorsByCode:       make(map[errors.ErrorCode]int64),
		errorsByHTTPStatus: make(map[int]int64),
		totalErrors:        0,
		aggregated:         NewAggregatedMetrics(), // Initialiser l'agrégation (T0029)
	}
}

// RecordError enregistre une erreur dans les métriques
func (m *ErrorMetrics) RecordError(code errors.ErrorCode, httpStatus int) {
	m.mu.Lock()
	m.errorsByCode[code]++
	m.errorsByHTTPStatus[httpStatus]++
	m.totalErrors++
	m.mu.Unlock()

	// Enregistrer dans les fenêtres d'agrégation (T0029)
	if m.aggregated != nil {
		m.aggregated.AddError("1m", code, httpStatus)
		m.aggregated.AddError("5m", code, httpStatus)
		m.aggregated.AddError("1h", code, httpStatus)
	}
}

// GetStats retourne les statistiques actuelles des erreurs
func (m *ErrorMetrics) GetStats() map[string]interface{} {
	m.mu.RLock()
	defer m.mu.RUnlock()

	return map[string]interface{}{
		"total_errors":          m.totalErrors,
		"errors_by_code":        m.errorsByCode,
		"errors_by_http_status": m.errorsByHTTPStatus,
	}
}

// Reset réinitialise toutes les métriques (utile pour les tests)
func (m *ErrorMetrics) Reset() {
	m.mu.Lock()
	defer m.mu.Unlock()

	m.errorsByCode = make(map[errors.ErrorCode]int64)
	m.errorsByHTTPStatus = make(map[int]int64)
	m.totalErrors = 0
	// Note: on ne reset pas l'agrégation pour garder l'historique
}

// GetAggregatedMetrics retourne l'instance AggregatedMetrics
func (m *ErrorMetrics) GetAggregatedMetrics() *AggregatedMetrics {
	return m.aggregated
}
