use ratatui::Frame;
use ratatui::layout::Rect;
use ratatui::style::{Color, Modifier, Style};
use ratatui::text::{Line, Span};
use ratatui::widgets::{Block, Borders, List, ListItem, ListState};
use crate::tui::app::{App, visible_nodes};
use crate::tui::state::{Pane, SelectionMode};
pub fn render(f: &mut Frame, app: &App, area: Rect) {
let is_active = app.active_pane == Pane::DetailTree
|| app.active_pane == Pane::TreeSearch
|| app.active_pane == Pane::YankPrompt;
let border_style = if is_active {
Style::default().fg(Color::Cyan)
} else {
Style::default().fg(Color::DarkGray)
};
let nodes = app
.selected
.as_ref()
.map(|sel| sel.tree_nodes.as_slice())
.unwrap_or(&[]);
let visible: Vec<(usize, &crate::tui::state::TreeNode)> = visible_nodes(nodes).collect();
let line_sel_range = app.detail_tree.selection.as_ref().and_then(|s| {
if s.mode != SelectionMode::Line {
return None;
}
let a = visible.iter().position(|(i, _)| *i == s.anchor_node)?;
let b = visible
.iter()
.position(|(i, _)| *i == app.detail_tree.selected)?;
let (lo, hi) = if a <= b { (a, b) } else { (b, a) };
Some(lo..=hi)
});
let items: Vec<ListItem> = visible
.iter()
.enumerate()
.map(|(vis_idx, (_, node))| {
let indent = " ".repeat(node.depth);
let icon = if node.children_count > 0 {
if node.expanded {
"\u{25bc} "
} else {
"\u{25b6} "
}
} else {
" "
};
let mut style = if node.is_layer {
Style::default().add_modifier(Modifier::BOLD)
} else {
Style::default()
};
if let Some(ref range) = line_sel_range
&& range.contains(&vis_idx)
{
style = style.bg(Color::DarkGray).fg(Color::White);
}
ListItem::new(Line::from(vec![
Span::raw(indent),
Span::raw(icon.to_string()),
Span::styled(node.label.clone(), style),
]))
})
.collect();
let list = List::new(items)
.block(
Block::default()
.borders(Borders::ALL)
.border_style(border_style)
.title(" Protocol Detail "),
)
.highlight_style(
Style::default()
.add_modifier(Modifier::REVERSED)
.fg(Color::White),
);
let selected_visible_idx = visible
.iter()
.position(|(orig_idx, _)| *orig_idx == app.detail_tree.selected);
let mut state = ListState::default();
state.select(selected_visible_idx);
f.render_stateful_widget(list, area, &mut state);
}