//! Visualization command implementations
//!
//! This module contains all visualization-related CLI commands extracted from main.rs.

#![cfg(feature = "native")]

use crate::ansi_colors::Colorize;
use crate::viz;

/// Viz subcommand
#[derive(Debug, Clone, clap::Subcommand)]
pub enum VizCommand {
    /// Display visualization frameworks ecosystem tree
    Tree {
        /// Filter by framework (gradio, streamlit, panel, dash)
        #[arg(long)]
        framework: Option<String>,

        /// Show PAIML replacement mappings
        #[arg(long)]
        integration: bool,

        /// Output format (ascii, json)
        #[arg(long, default_value = "ascii")]
        format: String,
    },

    /// Launch monitoring dashboard with Presentar
    Dashboard {
        /// Data source (trueno-db://metrics, prometheus://localhost:9090)
        #[arg(long, default_value = "trueno-db://metrics")]
        source: String,

        /// Dashboard port
        #[arg(long, default_value = "3000")]
        port: u16,

        /// Dashboard theme (light, dark)
        #[arg(long, default_value = "dark")]
        theme: String,

        /// Output config file instead of launching
        #[arg(long)]
        output: Option<String>,
    },
}

/// Main viz command dispatcher
pub fn cmd_viz(command: VizCommand) -> anyhow::Result<()> {
    match command {
        VizCommand::Tree {
            framework,
            integration,
            format,
        } => {
            cmd_viz_tree(framework.as_deref(), integration, &format)?;
        }
        VizCommand::Dashboard {
            source,
            port,
            theme,
            output,
        } => {
            cmd_viz_dashboard(&source, port, &theme, output.as_deref())?;
        }
    }
    Ok(())
}

fn cmd_viz_tree(framework: Option<&str>, integration: bool, format: &str) -> anyhow::Result<()> {
    use viz::tree::{
        build_dash_tree, build_gradio_tree, build_integration_mappings, build_panel_tree,
        build_streamlit_tree, format_all_frameworks, format_framework_tree,
        format_integration_mappings,
    };

    if integration {
        // Show PAIML replacement mappings
        let output = match format {
            "json" => {
                let mappings = build_integration_mappings();
                serde_json::to_string_pretty(&mappings)?
            }
            _ => format_integration_mappings(),
        };
        println!("{}", output);
    } else if let Some(framework_name) = framework {
        // Show specific framework tree
        let fw = framework_name.to_lowercase();
        let tree = match fw.as_str() {
            "gradio" => build_gradio_tree(),
            "streamlit" => build_streamlit_tree(),
            "panel" => build_panel_tree(),
            "dash" => build_dash_tree(),
            _ => {
                anyhow::bail!(
                    "Unknown framework: {}. Valid options: gradio, streamlit, panel, dash",
                    framework_name
                );
            }
        };
        let output = match format {
            "json" => serde_json::to_string_pretty(&tree)?,
            _ => format_framework_tree(&tree),
        };
        println!("{}", output);
    } else {
        // Show all frameworks
        let output = match format {
            "json" => {
                let trees = vec![
                    build_gradio_tree(),
                    build_streamlit_tree(),
                    build_panel_tree(),
                    build_dash_tree(),
                ];
                serde_json::to_string_pretty(&trees)?
            }
            _ => format_all_frameworks(),
        };
        println!("{}", output);
    }

    Ok(())
}

/// Generate Presentar dashboard configuration for monitoring
fn cmd_viz_dashboard(
    source: &str,
    port: u16,
    theme: &str,
    output: Option<&str>,
) -> anyhow::Result<()> {
    use std::path::Path;

    // Parse data source URI
    let (source_type, source_path) = if let Some(rest) = source.strip_prefix("trueno-db://") {
        ("trueno-db", rest)
    } else if let Some(rest) = source.strip_prefix("prometheus://") {
        ("prometheus", rest)
    } else {
        ("file", source)
    };

    // Generate Presentar dashboard configuration
    let config = format!(
        r#"# Presentar Monitoring Dashboard
# Generated by: batuta viz dashboard

app:
  name: "Realizar Monitoring"
  version: "1.0.0"
  port: {port}
  theme: "{theme}"

data_source:
  type: "{source_type}"
  path: "{source_path}"
  refresh_interval_ms: 1000

panels:
  - id: "inference_latency"
    title: "Inference Latency"
    type: "timeseries"
    query: |
      SELECT time, p50, p95, p99
      FROM realizar_metrics
      WHERE metric = 'inference_latency_ms'
      ORDER BY time DESC
      LIMIT 100
    y_axis: "Latency (ms)"

  - id: "throughput"
    title: "Token Throughput"
    type: "gauge"
    query: |
      SELECT avg(tokens_per_second) as tps
      FROM realizar_metrics
      WHERE metric = 'throughput'
      AND time > now() - interval '1 minute'
    max: 1000
    thresholds:
      - value: 100
        color: "red"
      - value: 500
        color: "yellow"
      - value: 800
        color: "green"

  - id: "model_requests"
    title: "Requests by Model"
    type: "bar"
    query: |
      SELECT model_name, count(*) as requests
      FROM realizar_metrics
      WHERE metric = 'request_count'
      GROUP BY model_name
      ORDER BY requests DESC
      LIMIT 10

  - id: "error_rate"
    title: "Error Rate"
    type: "stat"
    query: |
      SELECT
        (count(*) FILTER (WHERE status = 'error')) * 100.0 / count(*) as error_pct
      FROM realizar_metrics
      WHERE time > now() - interval '5 minutes'
    unit: "%"
    thresholds:
      - value: 1
        color: "green"
      - value: 5
        color: "yellow"
      - value: 10
        color: "red"

  - id: "ab_tests"
    title: "A/B Test Results"
    type: "table"
    query: |
      SELECT
        test_name,
        variant,
        requests,
        success_rate,
        avg_latency_ms
      FROM ab_test_results
      ORDER BY test_name, variant

layout:
  rows:
    - height: "300px"
      panels: ["inference_latency", "throughput"]
    - height: "250px"
      panels: ["model_requests", "error_rate"]
    - height: "200px"
      panels: ["ab_tests"]
"#,
        port = port,
        theme = theme,
        source_type = source_type,
        source_path = source_path,
    );

    if let Some(output_path) = output {
        std::fs::write(Path::new(output_path), &config)?;
        println!("Dashboard config written to: {}", output_path);
    } else {
        println!("{}", config);
        println!();
        println!("{}", "To launch dashboard:".cyan());
        println!("  presentar serve dashboard.yaml --port {}", port);
    }

    Ok(())
}
