use crate::app::AppState;
use crate::middleware::ActionLogger;
use crate::ui::style::{self, Emphasis};
use ratatui::Frame;
use ratatui::layout::{Constraint, Direction, Layout, Rect};
use ratatui::widgets::{Block, Borders, Clear, List, ListItem, Paragraph};
pub fn render(
frame: &mut Frame,
area: Rect,
state: &AppState,
action_logger: Option<&ActionLogger>,
cache_hit_rate: Option<f64>,
) {
let popup = center_rect(70, 80, area);
frame.render_widget(Clear, popup);
let chunks = Layout::default()
.direction(Direction::Vertical)
.margin(1)
.constraints([
Constraint::Length(3), Constraint::Min(10), Constraint::Length(5), ])
.split(popup);
let header = Paragraph::new("Debug Panel (Press 'd' to close)")
.style(style::text(&state.theme, Emphasis::Normal))
.block(Block::default().borders(Borders::ALL).title("Debug"));
frame.render_widget(header, popup);
if let Some(logger) = action_logger {
let actions: Vec<ListItem> = logger
.recent_actions(15)
.into_iter()
.map(|record| {
let prefix = if record.produced_effect { "[+]" } else { "[ ]" };
let text = format!("{} {:.2?} {}",
prefix,
record.elapsed,
truncate(&record.action, 60)
);
ListItem::new(text).style(style::body_style(&state.theme))
})
.collect();
let action_list = List::new(actions)
.block(Block::default().borders(Borders::ALL).title("Recent Actions"));
frame.render_widget(action_list, chunks[1]);
}
let stats = vec![
format!("Focus: {:?}", state.focus),
format!("Entries: {} status, {} commits, {} branches",
state.status_entries.len(),
state.commits.len(),
state.branches.len()
),
format!("Cache Hit Rate: {:.1}%", cache_hit_rate.unwrap_or(0.0) * 100.0),
];
let stats_text = stats.join(" | ");
let stats_para = Paragraph::new(stats_text)
.style(style::text(&state.theme, Emphasis::Muted))
.block(Block::default().borders(Borders::ALL).title("Stats"));
frame.render_widget(stats_para, chunks[2]);
}
fn truncate(s: &str, max: usize) -> String {
if s.len() <= max {
s.to_string()
} else {
format!("{}...", &s[..max.saturating_sub(3)])
}
}
fn center_rect(percent_x: u16, percent_y: u16, r: Rect) -> Rect {
let popup_layout = Layout::default()
.direction(Direction::Vertical)
.constraints([
Constraint::Percentage((100 - percent_y) / 2),
Constraint::Percentage(percent_y),
Constraint::Percentage((100 - percent_y) / 2),
])
.split(r);
Layout::default()
.direction(Direction::Horizontal)
.constraints([
Constraint::Percentage((100 - percent_x) / 2),
Constraint::Percentage(percent_x),
Constraint::Percentage((100 - percent_x) / 2),
])
.split(popup_layout[1])[1]
}