use ratatui::Frame;
use ratatui::layout::{Constraint, Layout};
use ratatui::style::{Modifier, Style};
use ratatui::text::{Line, Span};
use ratatui::widgets::{List, ListItem, ListState, Paragraph};
use crate::app::state::AppState;
use crate::ui::theme::Theme;
use crate::ui::primitives::molecules::render_modal;
pub struct TablePicker;
impl TablePicker {
pub fn render(frame: &mut Frame, state: &mut AppState) {
let filtered_count = state.filtered_tables().len();
let (_, inner) = render_modal(
frame,
Constraint::Percentage(60),
Constraint::Percentage(70),
" Table Picker ",
&format!(" {} tables │ ↑↓ Navigate │ Enter Select ", filtered_count),
);
let [filter_area, list_area] =
Layout::vertical([Constraint::Length(1), Constraint::Min(1)]).areas(inner);
state.ui.picker_pane_height = list_area.height;
let filter_line = Line::from(vec![
Span::styled(" > ", Style::default().fg(Theme::MODAL_TITLE)),
Span::raw(&state.ui.filter_input),
Span::styled(
"█",
Style::default()
.fg(Theme::CURSOR_FG)
.add_modifier(Modifier::SLOW_BLINK),
),
]);
frame.render_widget(Paragraph::new(filter_line), filter_area);
let filtered = state.filtered_tables();
let items: Vec<ListItem> = filtered
.iter()
.map(|t| {
let content = format!(" {}", t.qualified_name());
ListItem::new(content).style(Style::default().fg(Theme::TEXT_SECONDARY))
})
.collect();
let list = List::new(items)
.highlight_style(
Style::default()
.bg(Theme::COMPLETION_SELECTED_BG)
.fg(Theme::TEXT_PRIMARY)
.add_modifier(Modifier::BOLD),
)
.highlight_symbol("▸ ");
let selected = if filtered_count > 0 {
Some(state.ui.picker_selected)
} else {
None
};
let mut list_state = ListState::default()
.with_selected(selected)
.with_offset(state.ui.picker_scroll_offset);
frame.render_stateful_widget(list, list_area, &mut list_state);
}
}