use ratatui::layout::Rect;
use ratatui::style::{Modifier, Style};
use ratatui::text::{Line, Span};
use ratatui::widgets::{Block, BorderType, Clear, Padding, Paragraph};
use ratatui::Frame;
use crate::app::state::AppState;
use crate::tui::layout::centered;
use crate::tui::theme::Theme;
const VISIBLE_ROWS: usize = 12;
pub fn render(frame: &mut Frame, area: Rect, theme: &Theme, state: &AppState) {
let colors = &theme.colors;
let width = area.width.saturating_sub(8).clamp(40, 72);
let visible = VISIBLE_ROWS.min(state.servers.len().max(1));
let popup = centered(area, width, visible as u16 + 4);
frame.render_widget(Clear, popup);
let block = Block::bordered()
.border_type(BorderType::Rounded)
.border_style(Style::default().fg(colors.accent))
.style(Style::default().bg(colors.overlay))
.padding(Padding::new(2, 2, 1, 1))
.title(Line::from(Span::styled(
" Select Server ",
Style::default()
.fg(colors.text)
.add_modifier(Modifier::BOLD),
)));
let inner = block.inner(popup);
frame.render_widget(block, popup);
if state.servers.is_empty() {
frame.render_widget(
Paragraph::new(Line::from(Span::styled(
"No servers available",
Style::default().fg(colors.muted),
))),
inner,
);
return;
}
let first = state
.server_cursor
.saturating_sub(visible.saturating_sub(1));
let lines: Vec<Line> = state
.servers
.iter()
.enumerate()
.skip(first)
.take(visible)
.map(|(index, server)| {
let is_cursor = index == state.server_cursor;
let is_active = index == state.server_index;
let marker = if is_cursor { "▸ " } else { " " };
let active_mark = if is_active { " ●" } else { "" };
let name_style = if is_cursor {
Style::default()
.fg(colors.accent)
.add_modifier(Modifier::BOLD)
} else {
Style::default().fg(colors.text)
};
Line::from(vec![
Span::styled(marker, Style::default().fg(colors.accent)),
Span::styled(server.name.clone(), name_style),
Span::styled(
format!(" {}", server.description),
Style::default().fg(colors.muted),
),
Span::styled(active_mark, Style::default().fg(colors.success)),
])
})
.collect();
frame.render_widget(Paragraph::new(lines), inner);
}