#![deny(warnings)]
#![allow(dead_code)]
//! [TSM.ID].[11031972] -- Platform X Ecosystem
//! xcu-tui -- Terminal Dashboard for System Monitoring
use std::fmt::Write;

#[derive(Debug)]
pub enum TuiError { RenderFailed(String) }
impl std::fmt::Display for TuiError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Self::RenderFailed(e) => write!(f, "Render: {e}") } }
}
impl std::error::Error for TuiError {}

pub struct Dashboard { panels: Vec<Panel>, width: usize }
pub struct Panel { pub title: String, pub content: PanelContent }

pub enum PanelContent {
    Table { headers: Vec<String>, rows: Vec<Vec<String>> },
    BarChart { labels: Vec<String>, values: Vec<f64>, max_val: f64 },
    KeyValue(Vec<(String, String)>),
    StatusGrid { items: Vec<(String, bool)> },
}

impl Dashboard {
    pub fn new(width: usize) -> Self { Self { panels: Vec::new(), width } }
    pub fn add_panel(&mut self, panel: Panel) { self.panels.push(panel); }

    pub fn render(&self) -> Result<String, TuiError> {
        let mut out = String::new();
        for panel in &self.panels {
            self.render_border(&mut out, &panel.title);
            match &panel.content {
                PanelContent::Table { headers, rows } => self.render_table(&mut out, headers, rows),
                PanelContent::BarChart { labels, values, max_val } => self.render_bars(&mut out, labels, values, *max_val),
                PanelContent::KeyValue(pairs) => self.render_kv(&mut out, pairs),
                PanelContent::StatusGrid { items } => self.render_status(&mut out, items),
            }
            let _ = writeln!(out, "{}", "═".repeat(self.width));
        }
        Ok(out)
    }

    fn render_border(&self, out: &mut String, title: &str) {
        let pad = self.width.saturating_sub(title.len() + 4);
        let _ = writeln!(out, "╔═ {} {}╗", title, "═".repeat(pad));
    }

    fn render_table(&self, out: &mut String, headers: &[String], rows: &[Vec<String>]) {
        let _ = writeln!(out, "║ {}", headers.join(" │ "));
        let _ = writeln!(out, "║ {}", "─".repeat(self.width - 4));
        for row in rows { let _ = writeln!(out, "║ {}", row.join(" │ ")); }
    }

    fn render_bars(&self, out: &mut String, labels: &[String], values: &[f64], max_val: f64) {
        let bar_width = self.width.saturating_sub(20);
        for (label, &val) in labels.iter().zip(values.iter()) {
            let filled = if max_val > 0.0 { (val / max_val * bar_width as f64) as usize } else { 0 };
            let bar: String = "█".repeat(filled.min(bar_width));
            let empty: String = "░".repeat(bar_width.saturating_sub(filled));
            let _ = writeln!(out, "║ {:>8} │{}{} {:>6.1}", label, bar, empty, val);
        }
    }

    fn render_kv(&self, out: &mut String, pairs: &[(String, String)]) {
        for (k, v) in pairs { let _ = writeln!(out, "║ {:>16}: {}", k, v); }
    }

    fn render_status(&self, out: &mut String, items: &[(String, bool)]) {
        for (name, ok) in items {
            let icon = if *ok { "●" } else { "○" };
            let status = if *ok { "ONLINE" } else { "OFFLINE" };
            let _ = writeln!(out, "║ {} {:>16} [{}]", icon, name, status);
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn test_render() {
        let mut d = Dashboard::new(60);
        d.add_panel(Panel { title: "CPU".into(), content: PanelContent::BarChart {
            labels: vec!["alpha".into(), "beta".into(), "gamma".into()],
            values: vec![45.0, 72.0, 30.0], max_val: 100.0 } });
        d.add_panel(Panel { title: "Nodes".into(), content: PanelContent::StatusGrid {
            items: vec![("alpha".into(), true), ("beta".into(), true), ("gamma".into(), false)] } });
        let output = d.render().unwrap();
        assert!(output.contains("alpha"));
        assert!(output.contains("█"));
        assert!(output.contains("ONLINE"));
        assert!(output.contains("OFFLINE"));
    }
}
