use std::sync::Arc;
use log::{error, info};
use ratatui::crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
use crate::tui::{handlers::tab_navigation_handler, AppEvent};
use super::App;
pub fn normal_mode_handler(app: &mut App, key: KeyEvent) {
match (key.code, key.modifiers) {
(KeyCode::Char('q'), KeyModifiers::NONE) => app.state.should_quit = true,
(
tab @ (KeyCode::Char('1')
| KeyCode::Char('2')
| KeyCode::Char('3')
| KeyCode::Char('4')
| KeyCode::Char('5')),
KeyModifiers::NONE,
) => tab_navigation_handler(app, tab),
(KeyCode::Char('c'), KeyModifiers::NONE) => {
app.state.flightsql_tab.clear_editor(&app.state.config)
}
(KeyCode::Char('e'), KeyModifiers::NONE) => {
info!("Handling");
let editor = app.state.flightsql_tab.editor();
let lines = editor.lines();
let content = lines.join("");
info!("Conent: {}", content);
let default = "Enter a query here.";
if content == default {
info!("Clearing default content");
app.state.flightsql_tab.clear_placeholder();
}
app.state.flightsql_tab.edit();
}
(KeyCode::Down, KeyModifiers::NONE) => {
if let Some(s) = app.state.flightsql_tab.query_results_state() {
info!("Select next");
let mut s = s.borrow_mut();
s.select_next();
}
}
(KeyCode::Up, KeyModifiers::NONE) => {
if let Some(s) = app.state.flightsql_tab.query_results_state() {
info!("Select previous");
let mut s = s.borrow_mut();
s.select_previous();
}
}
(KeyCode::Enter, KeyModifiers::NONE) => {
info!("Executing FlightSQL query");
let sql = app.state.flightsql_tab.sql();
info!("SQL: {}", sql);
let sqls: Vec<String> = sql.split(';').map(|s| s.to_string()).collect();
let execution = Arc::clone(&app.execution);
let _event_tx = app.event_tx();
let handle = tokio::spawn(execution.run_flightsqls(sqls, _event_tx));
app.state.flightsql_tab.set_execution_task(handle);
}
(KeyCode::Right, KeyModifiers::NONE) => {
let _event_tx = app.event_tx();
if let Some(current_page) = app.state.flightsql_tab.current_page() {
let next_page = current_page + 1;
if app
.state
.flightsql_tab
.needs_more_batches_for_page(next_page)
{
info!("Fetching more batches for page {}", next_page);
if let Some(last_query) = app.state.history_tab.history().last() {
let execution = Arc::clone(&app.execution);
let sql = last_query.sql().clone();
tokio::spawn(async move {
execution.next_flightsql_batch(sql, _event_tx).await;
});
}
return; }
}
if let Err(e) = _event_tx.send(AppEvent::FlightSQLExecutionResultsNextPage) {
error!("Error going to next FlightSQL results page: {e}");
}
}
(KeyCode::Left, KeyModifiers::NONE) => {
let _event_tx = app.event_tx();
if let Err(e) = _event_tx.send(AppEvent::FlightSQLExecutionResultsPreviousPage) {
error!("Error going to previous FlightSQL results page: {e}");
}
}
_ => {}
}
}
pub fn editable_handler(app: &mut App, key: KeyEvent) {
match (key.code, key.modifiers) {
(KeyCode::Left, KeyModifiers::ALT) => app.state.flightsql_tab.previous_word(),
(KeyCode::Right, KeyModifiers::ALT) => app.state.flightsql_tab.next_word(),
(KeyCode::Backspace, KeyModifiers::ALT) => app.state.flightsql_tab.delete_word(),
(KeyCode::Esc, _) => app.state.flightsql_tab.exit_edit(),
(KeyCode::Enter, KeyModifiers::ALT) => {
info!("Executing FlightSQL query");
let sql = app.state.flightsql_tab.sql();
info!("SQL: {}", sql);
let sqls: Vec<String> = sql.split(';').map(|s| s.to_string()).collect();
let execution = Arc::clone(&app.execution);
let _event_tx = app.event_tx();
let handle = tokio::spawn(execution.run_flightsqls(sqls, _event_tx));
app.state.flightsql_tab.set_execution_task(handle);
}
_ => app.state.flightsql_tab.update_editor_content(key),
}
}
pub fn app_event_handler(app: &mut App, event: AppEvent) {
match event {
AppEvent::Key(key) => match app.state.flightsql_tab.editor_editable() {
true => editable_handler(app, key),
false => normal_mode_handler(app, key),
},
AppEvent::Error => {}
_ => {}
};
}