//! Configuration Management Metrics
//!
//! Tracks hot-reload events and configuration performance:
//! - PostgreSQL NOTIFY/LISTEN events
//! - Configuration cache hits/misses
//! - Hot-reload latency
//! - NOTIFY listener connection health

use prometheus::{Counter, Histogram, HistogramOpts, IntGauge, Opts, Registry};

/// Configuration and hot-reload metrics
pub struct ConfigMetrics {
    // === NOTIFY/LISTEN Events ===
    /// Total NOTIFY events received
    pub notify_events_total: Counter,
    /// NOTIFY events processed successfully
    pub notify_events_success: Counter,
    /// NOTIFY events failed to process
    pub notify_events_failure: Counter,

    // === Configuration Cache ===
    /// Configuration cache hits
    pub config_cache_hits: Counter,
    /// Configuration cache misses
    pub config_cache_misses: Counter,
    /// Configuration cache entries
    pub config_cache_size: IntGauge,

    // === Hot-Reload Latency ===
    /// Time from NOTIFY to config reload completion
    pub config_reload_duration_ms: Histogram,
    /// Time to fetch config from PostgreSQL
    pub config_fetch_duration_ms: Histogram,

    // === NOTIFY Listener Health ===
    /// NOTIFY listener connection status (0=disconnected, 1=connected)
    pub notify_listener_connected: IntGauge,
    /// NOTIFY listener reconnections
    pub notify_listener_reconnections: Counter,
    /// NOTIFY listener errors
    pub notify_listener_errors: Counter,

    // === Configuration Updates ===
    /// Auth configuration updates
    pub config_updates_auth: Counter,
    /// Routing configuration updates
    pub config_updates_routing: Counter,
    /// Rate limit configuration updates
    pub config_updates_rate_limit: Counter,
    /// Backend endpoint updates
    pub config_updates_backend: Counter,

    // === Configuration Validation ===
    /// Configuration validation successes
    pub config_validation_success: Counter,
    /// Configuration validation failures
    pub config_validation_failure: Counter,
}

impl ConfigMetrics {
    /// Create new config metrics and register with Prometheus
    pub fn new(registry: &Registry) -> Result<Self, prometheus::Error> {
        // === NOTIFY/LISTEN Events ===
        let notify_events_total = Counter::with_opts(Opts::new(
            "api_notify_events_total",
            "Total PostgreSQL NOTIFY events received",
        ))?;
        registry.register(Box::new(notify_events_total.clone()))?;

        let notify_events_success = Counter::with_opts(Opts::new(
            "api_notify_events_success",
            "Successfully processed NOTIFY events",
        ))?;
        registry.register(Box::new(notify_events_success.clone()))?;

        let notify_events_failure = Counter::with_opts(Opts::new(
            "api_notify_events_failure",
            "Failed to process NOTIFY events",
        ))?;
        registry.register(Box::new(notify_events_failure.clone()))?;

        // === Configuration Cache ===
        let config_cache_hits = Counter::with_opts(Opts::new(
            "api_config_cache_hits",
            "Configuration cache hits",
        ))?;
        registry.register(Box::new(config_cache_hits.clone()))?;

        let config_cache_misses = Counter::with_opts(Opts::new(
            "api_config_cache_misses",
            "Configuration cache misses",
        ))?;
        registry.register(Box::new(config_cache_misses.clone()))?;

        let config_cache_size = IntGauge::with_opts(Opts::new(
            "api_config_cache_size",
            "Number of cached configuration entries",
        ))?;
        registry.register(Box::new(config_cache_size.clone()))?;

        // === Hot-Reload Latency ===
        let config_reload_duration_ms = Histogram::with_opts(
            HistogramOpts::new(
                "api_config_reload_duration_milliseconds",
                "Time from NOTIFY to config reload completion in milliseconds",
            )
            .buckets(vec![1.0, 5.0, 10.0, 25.0, 50.0, 100.0, 250.0, 500.0]),
        )?;
        registry.register(Box::new(config_reload_duration_ms.clone()))?;

        let config_fetch_duration_ms = Histogram::with_opts(
            HistogramOpts::new(
                "api_config_fetch_duration_milliseconds",
                "Time to fetch configuration from PostgreSQL in milliseconds",
            )
            .buckets(vec![1.0, 5.0, 10.0, 25.0, 50.0, 100.0]),
        )?;
        registry.register(Box::new(config_fetch_duration_ms.clone()))?;

        // === NOTIFY Listener Health ===
        let notify_listener_connected = IntGauge::with_opts(Opts::new(
            "api_notify_listener_connected",
            "NOTIFY listener connection status (0=disconnected, 1=connected)",
        ))?;
        registry.register(Box::new(notify_listener_connected.clone()))?;

        let notify_listener_reconnections = Counter::with_opts(Opts::new(
            "api_notify_listener_reconnections",
            "Number of NOTIFY listener reconnections",
        ))?;
        registry.register(Box::new(notify_listener_reconnections.clone()))?;

        let notify_listener_errors = Counter::with_opts(Opts::new(
            "api_notify_listener_errors",
            "NOTIFY listener errors",
        ))?;
        registry.register(Box::new(notify_listener_errors.clone()))?;

        // === Configuration Updates ===
        let config_updates_auth = Counter::with_opts(Opts::new(
            "api_config_updates_auth",
            "Auth configuration updates",
        ))?;
        registry.register(Box::new(config_updates_auth.clone()))?;

        let config_updates_routing = Counter::with_opts(Opts::new(
            "api_config_updates_routing",
            "Routing configuration updates",
        ))?;
        registry.register(Box::new(config_updates_routing.clone()))?;

        let config_updates_rate_limit = Counter::with_opts(Opts::new(
            "api_config_updates_rate_limit",
            "Rate limit configuration updates",
        ))?;
        registry.register(Box::new(config_updates_rate_limit.clone()))?;

        let config_updates_backend = Counter::with_opts(Opts::new(
            "api_config_updates_backend",
            "Backend endpoint configuration updates",
        ))?;
        registry.register(Box::new(config_updates_backend.clone()))?;

        // === Configuration Validation ===
        let config_validation_success = Counter::with_opts(Opts::new(
            "api_config_validation_success",
            "Configuration validation successes",
        ))?;
        registry.register(Box::new(config_validation_success.clone()))?;

        let config_validation_failure = Counter::with_opts(Opts::new(
            "api_config_validation_failure",
            "Configuration validation failures",
        ))?;
        registry.register(Box::new(config_validation_failure.clone()))?;

        Ok(Self {
            notify_events_total,
            notify_events_success,
            notify_events_failure,
            config_cache_hits,
            config_cache_misses,
            config_cache_size,
            config_reload_duration_ms,
            config_fetch_duration_ms,
            notify_listener_connected,
            notify_listener_reconnections,
            notify_listener_errors,
            config_updates_auth,
            config_updates_routing,
            config_updates_rate_limit,
            config_updates_backend,
            config_validation_success,
            config_validation_failure,
        })
    }

    /// Record NOTIFY event received
    pub fn record_notify_event(&self, success: bool) {
        self.notify_events_total.inc();
        if success {
            self.notify_events_success.inc();
        } else {
            self.notify_events_failure.inc();
        }
    }

    /// Record configuration reload
    pub fn record_config_reload(&self, config_type: &str, duration_ms: f64) {
        self.config_reload_duration_ms.observe(duration_ms);

        match config_type {
            "auth" => self.config_updates_auth.inc(),
            "routing" => self.config_updates_routing.inc(),
            "rate_limit" => self.config_updates_rate_limit.inc(),
            "backend" => self.config_updates_backend.inc(),
            _ => {},
        }
    }

    /// Update NOTIFY listener connection status
    pub fn update_listener_status(&self, connected: bool) {
        self.notify_listener_connected
            .set(if connected { 1 } else { 0 });
    }

    /// Record NOTIFY listener reconnection
    pub fn record_reconnection(&self) {
        self.notify_listener_reconnections.inc();
    }
}
