// Provider Cost Prometheus Metrics
// Phase 7: Metrics for provider analytics and cost optimization

use lazy_static::lazy_static;
use prometheus::{GaugeVec, Histogram, HistogramOpts, IntCounterVec, IntGauge, Opts};

lazy_static! {
    /// Cost per provider in cents (labeled by provider name)
    pub static ref PROVIDER_COST_CENTS: IntCounterVec = IntCounterVec::new(
        Opts::new("vapora_provider_cost_cents_total", "Total cost per provider in cents"),
        &["provider"],
    )
    .expect("metric creation failed");

    /// Success rate per provider (0.0 to 1.0)
    pub static ref PROVIDER_SUCCESS_RATE: GaugeVec = GaugeVec::new(
        Opts::new("vapora_provider_success_rate", "Success rate per provider"),
        &["provider"],
    )
    .expect("metric creation failed");

    /// Efficiency score per provider (quality * cost_efficiency)
    pub static ref PROVIDER_EFFICIENCY_SCORE: GaugeVec = GaugeVec::new(
        Opts::new("vapora_provider_efficiency_score", "Efficiency score per provider (quality/cost ratio)"),
        &["provider"],
    )
    .expect("metric creation failed");

    /// Provider efficiency rank (1 = most efficient)
    pub static ref PROVIDER_EFFICIENCY_RANK: IntCounterVec = IntCounterVec::new(
        Opts::new("vapora_provider_efficiency_rank", "Efficiency rank per provider (1 = highest)"),
        &["provider"],
    )
    .expect("metric creation failed");

    /// Task count per provider
    pub static ref PROVIDER_TASK_COUNT: IntCounterVec = IntCounterVec::new(
        Opts::new("vapora_provider_task_count", "Total tasks executed per provider"),
        &["provider"],
    )
    .expect("metric creation failed");

    /// Average cost per task by provider
    pub static ref PROVIDER_AVG_COST_PER_TASK: GaugeVec = GaugeVec::new(
        Opts::new("vapora_provider_avg_cost_per_task_cents", "Average cost per task in cents by provider"),
        &["provider"],
    )
    .expect("metric creation failed");

    /// Input tokens per provider
    pub static ref PROVIDER_INPUT_TOKENS: IntCounterVec = IntCounterVec::new(
        Opts::new("vapora_provider_input_tokens_total", "Total input tokens per provider"),
        &["provider"],
    )
    .expect("metric creation failed");

    /// Output tokens per provider
    pub static ref PROVIDER_OUTPUT_TOKENS: IntCounterVec = IntCounterVec::new(
        Opts::new("vapora_provider_output_tokens_total", "Total output tokens per provider"),
        &["provider"],
    )
    .expect("metric creation failed");

    /// Cost per million tokens by provider
    pub static ref PROVIDER_COST_PER_1M_TOKENS: GaugeVec = GaugeVec::new(
        Opts::new("vapora_provider_cost_per_1m_tokens", "Cost per 1M tokens by provider"),
        &["provider"],
    )
    .expect("metric creation failed");

    /// Projected weekly cost by provider
    pub static ref PROVIDER_PROJECTED_WEEKLY_COST: IntCounterVec = IntCounterVec::new(
        Opts::new("vapora_provider_projected_weekly_cost_cents", "Projected weekly cost per provider in cents"),
        &["provider"],
    )
    .expect("metric creation failed");

    /// Projected monthly cost by provider
    pub static ref PROVIDER_PROJECTED_MONTHLY_COST: IntCounterVec = IntCounterVec::new(
        Opts::new("vapora_provider_projected_monthly_cost_cents", "Projected monthly cost per provider in cents"),
        &["provider"],
    )
    .expect("metric creation failed");

    /// Cost trend per provider (stable/increasing/decreasing)
    pub static ref PROVIDER_COST_TREND_COUNTER: IntCounterVec = IntCounterVec::new(
        Opts::new("vapora_provider_cost_trend_changes_total", "Cost trend changes per provider"),
        &["provider", "trend"],
    )
    .expect("metric creation failed");

    /// Forecast confidence per provider (0.0 to 1.0)
    pub static ref PROVIDER_FORECAST_CONFIDENCE: GaugeVec = GaugeVec::new(
        Opts::new("vapora_provider_forecast_confidence", "Forecast confidence per provider"),
        &["provider"],
    )
    .expect("metric creation failed");

    /// Cost breakdown by task type per provider
    pub static ref PROVIDER_TASK_TYPE_COST: IntCounterVec = IntCounterVec::new(
        Opts::new("vapora_provider_task_type_cost_cents", "Cost per task type per provider"),
        &["provider", "task_type"],
    )
    .expect("metric creation failed");

    /// Success rate by task type per provider
    pub static ref PROVIDER_TASK_TYPE_SUCCESS_RATE: GaugeVec = GaugeVec::new(
        Opts::new("vapora_provider_task_type_success_rate", "Success rate per task type per provider"),
        &["provider", "task_type"],
    )
    .expect("metric creation failed");

    /// Average duration per task type per provider (milliseconds)
    pub static ref PROVIDER_TASK_TYPE_AVG_DURATION_MS: Histogram = {
        let opts = HistogramOpts::new("vapora_provider_task_type_duration_ms", "Task duration in ms per task type per provider");
        Histogram::with_opts(opts).expect("metric creation failed")
    };

    /// Cost optimization: provider selection count (tracks which providers are selected)
    pub static ref PROVIDER_SELECTION_COUNT: IntCounterVec = IntCounterVec::new(
        Opts::new("vapora_provider_selection_total", "Number of times provider was selected"),
        &["provider", "reason"],
    )
    .expect("metric creation failed");

    /// Total providers tracked
    pub static ref TOTAL_PROVIDERS: IntGauge = IntGauge::new(
        "vapora_total_providers_tracked",
        "Total number of providers being tracked"
    )
    .expect("metric creation failed");
}

/// Register all provider metrics
pub fn register_provider_metrics() {
    let _ = prometheus::register(Box::new(PROVIDER_COST_CENTS.clone()));
    let _ = prometheus::register(Box::new(PROVIDER_SUCCESS_RATE.clone()));
    let _ = prometheus::register(Box::new(PROVIDER_EFFICIENCY_SCORE.clone()));
    let _ = prometheus::register(Box::new(PROVIDER_EFFICIENCY_RANK.clone()));
    let _ = prometheus::register(Box::new(PROVIDER_TASK_COUNT.clone()));
    let _ = prometheus::register(Box::new(PROVIDER_AVG_COST_PER_TASK.clone()));
    let _ = prometheus::register(Box::new(PROVIDER_INPUT_TOKENS.clone()));
    let _ = prometheus::register(Box::new(PROVIDER_OUTPUT_TOKENS.clone()));
    let _ = prometheus::register(Box::new(PROVIDER_COST_PER_1M_TOKENS.clone()));
    let _ = prometheus::register(Box::new(PROVIDER_PROJECTED_WEEKLY_COST.clone()));
    let _ = prometheus::register(Box::new(PROVIDER_PROJECTED_MONTHLY_COST.clone()));
    let _ = prometheus::register(Box::new(PROVIDER_COST_TREND_COUNTER.clone()));
    let _ = prometheus::register(Box::new(PROVIDER_FORECAST_CONFIDENCE.clone()));
    let _ = prometheus::register(Box::new(PROVIDER_TASK_TYPE_COST.clone()));
    let _ = prometheus::register(Box::new(PROVIDER_TASK_TYPE_SUCCESS_RATE.clone()));
    let _ = prometheus::register(Box::new(PROVIDER_TASK_TYPE_AVG_DURATION_MS.clone()));
    let _ = prometheus::register(Box::new(PROVIDER_SELECTION_COUNT.clone()));
    let _ = prometheus::register(Box::new(TOTAL_PROVIDERS.clone()));
}
