use std::time::Duration;

use crate::observability::{
    MetricsRegistry, RedisDegradationLabels, RedisEventLabels, RedisMetricLabels,
};

/// Records a Redis command without exposing Redis keys.
pub fn record_redis_command(
    metrics: Option<&MetricsRegistry>,
    command: &str,
    shard: &str,
    result: &str,
    duration: Duration,
) {
    if let Some(metrics) = metrics {
        metrics.record_redis_command(RedisMetricLabels::new(command, shard, result), duration);
    }
    let span = tracing::debug_span!(
        "rs_zero.redis.command",
        command = command,
        shard = shard,
        result = result,
        duration_ms = duration.as_millis()
    );
    let _entered = span.enter();
    tracing::debug!("redis command recorded");
}

/// Records a low-cardinality Redis event without exposing Redis keys.
pub fn record_redis_event(
    metrics: Option<&MetricsRegistry>,
    event: &str,
    shard: &str,
    result: &str,
) {
    if let Some(metrics) = metrics {
        metrics.record_redis_event(RedisEventLabels::new(event, shard, result));
    }
    tracing::debug!(event, shard, result, "redis event recorded");
}

/// Records an explicit Redis degradation event.
pub fn record_redis_degradation(
    metrics: Option<&MetricsRegistry>,
    operation: &str,
    action: &str,
    shard: &str,
) {
    if let Some(metrics) = metrics {
        metrics.record_redis_degradation(RedisDegradationLabels::new(operation, action, shard));
    }
    tracing::debug!(operation, action, shard, "redis degradation recorded");
}
