use crate::app::{App, AppMode, FocusedPane, InputMode};
use cctakt::{available_themes, plan::NotifyLevel};
use crossterm::event::{KeyCode, KeyModifiers};
pub fn handle_keybinding(app: &mut App, modifiers: KeyModifiers, code: KeyCode) -> bool {
match (modifiers, code) {
(KeyModifiers::CONTROL, KeyCode::Char('q' | 'Q')) => {
app.should_quit = true;
true
}
(KeyModifiers::CONTROL, KeyCode::Char('t' | 'T')) => {
app.open_theme_picker();
true
}
(KeyModifiers::CONTROL, KeyCode::Char('i' | 'I')) | (_, KeyCode::F(2)) => {
app.open_issue_picker();
true
}
(KeyModifiers::CONTROL, KeyCode::Char('w' | 'W')) => {
app.close_active_agent();
true
}
(KeyModifiers::CONTROL, KeyCode::Char('n' | 'N')) => {
app.agent_manager.next();
true
}
(KeyModifiers::CONTROL, KeyCode::Char('p' | 'P')) => {
app.agent_manager.prev();
true
}
(KeyModifiers::CONTROL, KeyCode::Char('r' | 'R')) => {
match app.restart_conductor() {
Ok(()) => {
app.add_notification(
"Conductor restarted".to_string(),
NotifyLevel::Success,
);
}
Err(e) => {
app.add_notification(
format!("Failed to restart conductor: {e}"),
NotifyLevel::Error,
);
}
}
true
}
(KeyModifiers::CONTROL, KeyCode::Char(c)) if ('1'..='9').contains(&c) => {
let index = (c as usize) - ('1' as usize);
app.agent_manager.switch_to(index);
true
}
(KeyModifiers::ALT, KeyCode::Char(c)) if ('1'..='9').contains(&c) => {
let index = (c as usize) - ('1' as usize);
app.agent_manager.switch_to(index);
true
}
_ => false,
}
}
pub fn handle_theme_picker_input(app: &mut App, code: KeyCode) {
let themes = available_themes();
let theme_count = themes.len();
match code {
KeyCode::Up | KeyCode::Char('k') => {
if app.theme_picker_index > 0 {
app.theme_picker_index -= 1;
} else {
app.theme_picker_index = theme_count.saturating_sub(1);
}
}
KeyCode::Down | KeyCode::Char('j') => {
if app.theme_picker_index < theme_count.saturating_sub(1) {
app.theme_picker_index += 1;
} else {
app.theme_picker_index = 0;
}
}
KeyCode::Enter => {
if let Some((id, _, _)) = themes.get(app.theme_picker_index) {
app.apply_theme(id);
}
app.show_theme_picker = false;
app.mode = AppMode::Normal;
}
KeyCode::Char('q') => {
app.show_theme_picker = false;
app.mode = AppMode::Normal;
}
_ => {}
}
}
pub fn handle_navigation_mode(app: &mut App, code: KeyCode) {
match code {
KeyCode::Char('h') => {
app.focused_pane = FocusedPane::Left;
}
KeyCode::Char('l') => {
app.focused_pane = FocusedPane::Right;
}
KeyCode::Char('j') => {
if app.focused_pane == FocusedPane::Right {
app.agent_manager.switch_to_next_worker();
}
}
KeyCode::Char('k') => {
if app.focused_pane == FocusedPane::Right {
app.agent_manager.switch_to_prev_worker();
}
}
KeyCode::Char('i') | KeyCode::Enter => {
app.input_mode = InputMode::Input;
}
KeyCode::Char(':') => {
app.command_buffer.clear();
app.input_mode = InputMode::Command;
}
_ => {}
}
}
pub fn handle_command_mode(app: &mut App, code: KeyCode) {
match code {
KeyCode::Esc => {
app.command_buffer.clear();
app.input_mode = InputMode::Navigation;
}
KeyCode::Enter => {
let cmd = app.command_buffer.trim().to_lowercase();
match cmd.as_str() {
"q" | "quit" | "exit" => {
app.should_quit = true;
}
"w" => {
app.close_active_agent();
}
_ => {
if !cmd.is_empty() {
app.add_notification(
format!("Unknown command: {}", cmd),
NotifyLevel::Warning,
);
}
}
}
app.command_buffer.clear();
app.input_mode = InputMode::Navigation;
}
KeyCode::Backspace => {
app.command_buffer.pop();
if app.command_buffer.is_empty() {
app.input_mode = InputMode::Navigation;
}
}
KeyCode::Char(c) => {
app.command_buffer.push(c);
}
_ => {}
}
}