// Handles keyboard input and system events for the TUI.
use crate::config::Config;
use crate::model::parser::parse_duration;
use crate::model::{Task, TaskStatus, extract_inline_aliases, validate_alias_integrity};
use crate::storage::LOCAL_CALENDAR_HREF;
use crate::system::SystemEvent;
use crate::tui::action::{Action, AppEvent, SidebarMode};
use crate::tui::state::{AppState, Focus, InputMode};
use chrono::NaiveTime;
use crossterm::event::{KeyCode, KeyEvent};
use std::collections::HashMap;
use tokio::sync::mpsc::Sender;

pub fn handle_app_event(state: &mut AppState, event: AppEvent, default_cal: &Option<String>) {
    match event {
        AppEvent::Status(s) => state.message = s,
        AppEvent::Error(s) => {
            state.message = format!("Error: {}", s);
            state.loading = false;
        }
        AppEvent::CalendarsLoaded(cals) => {
            state.calendars = cals;

            if let Some(def) = default_cal
                && let Some(found) = state
                    .calendars
                    .iter()
                    .find(|c| c.name == *def || c.href == *def)
            {
                if state.hidden_calendars.contains(&found.href) {
                    state.hidden_calendars.remove(&found.href);
                }
                state.active_cal_href = Some(found.href.clone());
            }

            if state.active_cal_href.is_none() {
                state.active_cal_href = Some(LOCAL_CALENDAR_HREF.to_string());
            }
            state.refresh_filtered_view();
        }
        AppEvent::TasksLoaded(results) => {
            for (href, tasks) in results {
                state.store.insert(href, tasks);
            }
            state.refresh_filtered_view();
            state.loading = false;
        }
    }
}

pub async fn handle_key_event(
    key: KeyEvent,
    state: &mut AppState,
    action_tx: &Sender<Action>,
) -> Option<Action> {
    // --- ALARM INTERCEPTION ---
    if let Some((task, alarm_uid)) = state.active_alarm.clone() {
        // If in Snoozing mode, let the input handler deal with it
        if state.mode == InputMode::Snoozing {
            // Fall through to normal input handling below
        } else {
            match key.code {
                KeyCode::Char('D') | KeyCode::Char('d') => {
                    if let Some((t, _)) = state.store.get_task_mut(&task.uid)
                        && t.dismiss_alarm(&alarm_uid)
                    {
                        let t_clone = t.clone();
                        // Update UI
                        state.active_alarm = None;
                        state.refresh_filtered_view();
                        // Push update to backend
                        let _ = action_tx.send(Action::UpdateTask(t_clone.clone())).await;
                        // Push update to alarm actor
                        if let Some(tx) = &state.alarm_actor_tx {
                            let all = state.store.calendars.values().flatten().cloned().collect();
                            let _ = tx.try_send(SystemEvent::UpdateTasks(all));
                        }
                    }
                    return None;
                }
                KeyCode::Char('1') => {
                    // Snooze short preset
                    if let Some((t, _)) = state.store.get_task_mut(&task.uid)
                        && t.snooze_alarm(&alarm_uid, state.snooze_short_mins)
                    {
                        let t_clone = t.clone();
                        state.active_alarm = None;
                        state.refresh_filtered_view();
                        let _ = action_tx.send(Action::UpdateTask(t_clone.clone())).await;
                        if let Some(tx) = &state.alarm_actor_tx {
                            let all = state.store.calendars.values().flatten().cloned().collect();
                            let _ = tx.try_send(SystemEvent::UpdateTasks(all));
                        }
                    }
                    return None;
                }
                KeyCode::Char('2') => {
                    // Snooze long preset
                    if let Some((t, _)) = state.store.get_task_mut(&task.uid)
                        && t.snooze_alarm(&alarm_uid, state.snooze_long_mins)
                    {
                        let t_clone = t.clone();
                        state.active_alarm = None;
                        state.refresh_filtered_view();
                        let _ = action_tx.send(Action::UpdateTask(t_clone.clone())).await;
                        if let Some(tx) = &state.alarm_actor_tx {
                            let all = state.store.calendars.values().flatten().cloned().collect();
                            let _ = tx.try_send(SystemEvent::UpdateTasks(all));
                        }
                    }
                    return None;
                }
                KeyCode::Char('S') | KeyCode::Char('s') => {
                    // Enter custom snooze mode
                    state.mode = InputMode::Snoozing;
                    state.reset_input();
                    return None;
                }
                _ => return None, // Block other input while alarm is ringing
            }
        }
    }
    // --------------------------

    match state.mode {
        InputMode::Creating => match key.code {
            KeyCode::Enter if !state.input_buffer.is_empty() => {
                let (clean_input, new_aliases): (String, HashMap<String, Vec<String>>) =
                    extract_inline_aliases(&state.input_buffer);

                if !new_aliases.is_empty() {
                    for (key, tags) in new_aliases {
                        if let Err(e) = validate_alias_integrity(&key, &tags, &state.tag_aliases) {
                            state.message = format!("Alias Error: {}", e);
                            return None;
                        }

                        state.tag_aliases.insert(key.clone(), tags.clone());
                        let modified = state.store.apply_alias_retroactively(&key, &tags);

                        for t in modified {
                            let _ = action_tx.send(Action::UpdateTask(t)).await;
                        }
                    }
                    if let Ok(mut cfg) = Config::load() {
                        cfg.tag_aliases = state.tag_aliases.clone();
                        let _ = cfg.save();
                    }
                }

                if clean_input.starts_with('#')
                    && !clean_input.trim().contains(' ')
                    && state.creating_child_of.is_none()
                {
                    let was_alias_def = state.input_buffer.contains(":=");

                    if !was_alias_def {
                        let tag = clean_input.trim().trim_start_matches('#').to_string();
                        if !tag.is_empty() {
                            state.sidebar_mode = SidebarMode::Categories;
                            state.selected_categories.clear();
                            state.selected_categories.insert(tag);
                            state.mode = InputMode::Normal;
                            state.reset_input();
                            state.refresh_filtered_view();
                            return None;
                        }
                    } else {
                        state.mode = InputMode::Normal;
                        state.reset_input();
                        state.message = "Alias updated.".to_string();
                        return None;
                    }
                }

                let is_loc = clean_input.starts_with("@@") || clean_input.starts_with("loc:");
                if is_loc && !clean_input.trim().contains(' ') && state.creating_child_of.is_none()
                {
                    let raw = if clean_input.starts_with("@@") {
                        clean_input.trim_start_matches("@@")
                    } else {
                        clean_input.trim_start_matches("loc:")
                    };
                    let loc = crate::model::parser::strip_quotes(raw);

                    if !loc.is_empty() {
                        state.sidebar_mode = SidebarMode::Locations;
                        state.selected_locations.clear();
                        state.selected_locations.insert(loc);
                        state.mode = InputMode::Normal;
                        state.reset_input();
                        state.refresh_filtered_view();
                        return None;
                    }
                }

                let target_href = state
                    .active_cal_href
                    .clone()
                    .or_else(|| state.calendars.first().map(|c| c.href.clone()));

                if let Some(href) = target_href {
                    // Load config to get time
                    let config = Config::load().unwrap_or_default();
                    let def_time =
                        NaiveTime::parse_from_str(&config.default_reminder_time, "%H:%M").ok();

                    let mut task = Task::new(&clean_input, &state.tag_aliases, def_time);
                    task.calendar_href = href.clone();
                    task.parent_uid = state.creating_child_of.clone();

                    let new_uid = task.uid.clone();
                    state.store.add_task(task.clone());
                    state.refresh_filtered_view();

                    if let Some(idx) = state.tasks.iter().position(|t| t.uid == new_uid) {
                        state.list_state.select(Some(idx));
                    }

                    state.mode = InputMode::Normal;
                    state.reset_input();
                    state.creating_child_of = None;
                    return Some(Action::CreateTask(task));
                }
                state.mode = InputMode::Normal;
                state.reset_input();
            }
            KeyCode::Esc => {
                state.mode = InputMode::Normal;
                state.reset_input();
            }
            KeyCode::Char(c) => state.enter_char(c),
            KeyCode::Backspace => state.delete_char(),
            KeyCode::Left => state.move_cursor_left(),
            KeyCode::Right => state.move_cursor_right(),
            _ => {}
        },
        InputMode::Editing => match key.code {
            KeyCode::Enter => {
                let (clean_input, new_aliases): (String, HashMap<String, Vec<String>>) =
                    extract_inline_aliases(&state.input_buffer);
                if !new_aliases.is_empty() {
                    for (k, v) in new_aliases {
                        if let Err(e) = validate_alias_integrity(&k, &v, &state.tag_aliases) {
                            state.message = format!("Alias Error: {}", e);
                            return None;
                        }

                        state.tag_aliases.insert(k.clone(), v.clone());
                        let modified = state.store.apply_alias_retroactively(&k, &v);
                        for mod_t in modified {
                            let _ = action_tx.send(Action::UpdateTask(mod_t)).await;
                        }
                    }
                    if let Ok(mut cfg) = Config::load() {
                        cfg.tag_aliases = state.tag_aliases.clone();
                        let _ = cfg.save();
                    }
                }

                let target_uid: Option<String> = state
                    .editing_index
                    .and_then(|idx| state.tasks.get(idx).map(|t| t.uid.clone()));

                if let Some(uid) = target_uid
                    && let Some((t, _)) = state.store.get_task_mut(&uid)
                {
                    let config = Config::load().unwrap_or_default();
                    let def_time =
                        NaiveTime::parse_from_str(&config.default_reminder_time, "%H:%M").ok();
                    t.apply_smart_input(&clean_input, &state.tag_aliases, def_time);
                    let clone = t.clone();
                    state.refresh_filtered_view();
                    state.mode = InputMode::Normal;
                    state.reset_input();
                    return Some(Action::UpdateTask(clone));
                }
                state.mode = InputMode::Normal;
            }
            KeyCode::Esc => {
                state.mode = InputMode::Normal;
                state.reset_input();
            }
            KeyCode::Char(c) => state.enter_char(c),
            KeyCode::Backspace => state.delete_char(),
            KeyCode::Left => state.move_cursor_left(),
            KeyCode::Right => state.move_cursor_right(),
            _ => {}
        },
        InputMode::EditingDescription => match key.code {
            KeyCode::Enter => {
                if key.modifiers.contains(crossterm::event::KeyModifiers::ALT)
                    || key
                        .modifiers
                        .contains(crossterm::event::KeyModifiers::SHIFT)
                {
                    state.enter_char('\n');
                } else {
                    let target_uid: Option<String> = state
                        .editing_index
                        .and_then(|idx| state.tasks.get(idx).map(|t| t.uid.clone()));

                    if let Some(uid) = target_uid
                        && let Some((t, _)) = state.store.get_task_mut(&uid)
                    {
                        t.description = state.input_buffer.clone();
                        let clone = t.clone();
                        state.refresh_filtered_view();
                        state.mode = InputMode::Normal;
                        state.reset_input();
                        return Some(Action::UpdateTask(clone));
                    }
                    state.mode = InputMode::Normal;
                    state.reset_input();
                }
            }
            KeyCode::Esc => {
                state.mode = InputMode::Normal;
                state.reset_input();
            }
            KeyCode::Char(c) => state.enter_char(c),
            KeyCode::Backspace => state.delete_char(),
            KeyCode::Left => state.move_cursor_left(),
            KeyCode::Right => state.move_cursor_right(),
            _ => {}
        },
        InputMode::Snoozing => match key.code {
            KeyCode::Enter if !state.input_buffer.is_empty() => {
                // Parse custom snooze duration
                if let Some(mins) = parse_duration(&state.input_buffer) {
                    if let Some((task, alarm_uid)) = state.active_alarm.clone()
                        && let Some((t, _)) = state.store.get_task_mut(&task.uid)
                        && t.snooze_alarm(&alarm_uid, mins)
                    {
                        let t_clone = t.clone();
                        state.active_alarm = None;
                        state.mode = InputMode::Normal;
                        state.reset_input();
                        state.refresh_filtered_view();
                        let _ = action_tx.send(Action::UpdateTask(t_clone.clone())).await;
                        if let Some(tx) = &state.alarm_actor_tx {
                            let all = state.store.calendars.values().flatten().cloned().collect();
                            let _ = tx.try_send(SystemEvent::UpdateTasks(all));
                        }
                    }
                } else {
                    state.message = format!("Invalid duration: '{}'", state.input_buffer);
                }
                return None;
            }
            KeyCode::Esc => {
                state.mode = InputMode::Normal;
                state.reset_input();
                // Return to alarm display
                return None;
            }
            KeyCode::Char(c) => {
                state.enter_char(c);
            }
            KeyCode::Backspace => {
                state.delete_char();
            }
            KeyCode::Left => {
                state.move_cursor_left();
            }
            KeyCode::Right => {
                state.move_cursor_right();
            }
            _ => {}
        },
        InputMode::Searching => match key.code {
            KeyCode::Enter => {
                if state.input_buffer.starts_with('#') && !state.input_buffer.contains(' ') {
                    let tag = state.input_buffer.trim_start_matches('#').to_string();
                    state.sidebar_mode = SidebarMode::Categories;
                    state.selected_categories.clear();
                    state.selected_categories.insert(tag);
                    state.active_search_query.clear();
                } else if (state.input_buffer.starts_with("@@")
                    || state.input_buffer.starts_with("loc:"))
                    && !state.input_buffer.contains(' ')
                {
                    let raw = if state.input_buffer.starts_with("@@") {
                        state.input_buffer.trim_start_matches("@@")
                    } else {
                        state.input_buffer.trim_start_matches("loc:")
                    };
                    let loc = crate::model::parser::strip_quotes(raw);

                    state.sidebar_mode = SidebarMode::Locations;
                    state.selected_locations.clear();
                    state.selected_locations.insert(loc);
                    state.active_search_query.clear();
                } else {
                    state.active_search_query = state.input_buffer.clone();
                }

                state.mode = InputMode::Normal;
                state.reset_input();
                state.refresh_filtered_view();
            }
            KeyCode::Esc => {
                state.active_search_query.clear();
                state.mode = InputMode::Normal;
                state.reset_input();
                state.refresh_filtered_view();
            }
            KeyCode::Char(c) => {
                state.enter_char(c);
                state.refresh_filtered_view();
            }
            KeyCode::Backspace => {
                state.delete_char();
                state.refresh_filtered_view();
            }
            KeyCode::Left => state.move_cursor_left(),
            KeyCode::Right => state.move_cursor_right(),
            KeyCode::Down => state.next(),
            KeyCode::Up => state.previous(),
            KeyCode::PageDown => state.jump_forward(10),
            KeyCode::PageUp => state.jump_backward(10),
            _ => {}
        },
        InputMode::Normal => match key.code {
            KeyCode::Esc => {
                let mut needs_refresh = false;
                if state.yanked_uid.is_some() {
                    state.yanked_uid = None;
                    state.message = "Yank cleared.".to_string();
                } else if !state.active_search_query.is_empty() {
                    state.active_search_query.clear();
                    needs_refresh = true;
                } else if !state.selected_categories.is_empty() {
                    state.selected_categories.clear();
                    needs_refresh = true;
                }
                if needs_refresh {
                    state.refresh_filtered_view();
                }
            }
            KeyCode::Char('?') => state.show_full_help = !state.show_full_help,
            KeyCode::Char('q') => return Some(Action::Quit),
            KeyCode::Char('r') => return Some(Action::Refresh),

            KeyCode::Char(' ') => {
                if state.active_focus == Focus::Main {
                    if let Some(uid) = state.get_selected_task().map(|t| t.uid.clone())
                        && let Some(updated) = state.store.toggle_task(&uid)
                    {
                        state.refresh_filtered_view();
                        return Some(Action::ToggleTask(updated));
                    }
                } else if state.active_focus == Focus::Sidebar
                    && state.sidebar_mode == SidebarMode::Calendars
                {
                    let target_cal = if let Some(idx) = state.cal_state.selected() {
                        let filtered = state.get_filtered_calendars();
                        filtered.get(idx).map(|c| c.href.clone())
                    } else {
                        None
                    };

                    if let Some(href) = target_cal
                        && state.active_cal_href.as_ref() != Some(&href)
                    {
                        if state.hidden_calendars.contains(&href) {
                            state.hidden_calendars.remove(&href);
                            let _ = action_tx.send(Action::ToggleCalendarVisibility(href)).await;
                        } else {
                            state.hidden_calendars.insert(href);
                        }
                        state.refresh_filtered_view();
                    }
                }
            }
            KeyCode::Char('s') => {
                if let Some(task) = state.get_selected_task() {
                    let uid = task.uid.clone();
                    let updated_opt = if task.status == TaskStatus::InProcess {
                        state.store.pause_task(&uid)
                    } else {
                        state.store.set_status_in_process(&uid)
                    };

                    if let Some(updated) = updated_opt {
                        state.refresh_filtered_view();
                        return Some(Action::UpdateTask(updated));
                    }
                }
            }
            KeyCode::Char('S') => {
                if let Some(uid) = state.get_selected_task().map(|t| t.uid.clone())
                    && let Some(updated) = state.store.stop_task(&uid)
                {
                    state.refresh_filtered_view();
                    return Some(Action::UpdateTask(updated));
                }
            }
            KeyCode::Char('x') => {
                if let Some(uid) = state.get_selected_task().map(|t| t.uid.clone())
                    && let Some(updated) = state.store.set_status(&uid, TaskStatus::Cancelled)
                {
                    state.refresh_filtered_view();
                    return Some(Action::MarkCancelled(updated));
                }
            }
            KeyCode::Char('+') => {
                if let Some(uid) = state.get_selected_task().map(|t| t.uid.clone())
                    && let Some(updated) = state.store.change_priority(&uid, 1)
                {
                    state.refresh_filtered_view();
                    return Some(Action::UpdateTask(updated));
                }
            }
            KeyCode::Char('-') => {
                if let Some(uid) = state.get_selected_task().map(|t| t.uid.clone())
                    && let Some(updated) = state.store.change_priority(&uid, -1)
                {
                    state.refresh_filtered_view();
                    return Some(Action::UpdateTask(updated));
                }
            }
            KeyCode::Char('d') => {
                if let Some(uid) = state.get_selected_task().map(|t| t.uid.clone())
                    && let Some((deleted, _)) = state.store.delete_task(&uid)
                {
                    state.refresh_filtered_view();
                    return Some(Action::DeleteTask(deleted));
                }
            }
            KeyCode::Char('c') => {
                let data = if let Some(parent_uid) = &state.yanked_uid {
                    state
                        .get_selected_task()
                        .map(|view_task| (view_task.uid.clone(), parent_uid.clone()))
                } else {
                    None
                };

                if let Some((child_uid, parent_uid)) = data {
                    if child_uid == parent_uid {
                        state.message = "Cannot be child of self!".to_string();
                    } else if let Some(updated) =
                        state.store.set_parent(&child_uid, Some(parent_uid))
                    {
                        state.yanked_uid = None;
                        state.refresh_filtered_view();
                        return Some(Action::UpdateTask(updated));
                    }
                }
            }
            KeyCode::Char('C') => {
                if state.active_focus == Focus::Main
                    && let Some(task) = state.get_selected_task()
                {
                    let uid = task.uid.clone();
                    let summary = task.summary.clone();

                    let mut initial_input = String::new();
                    for cat in &task.categories {
                        initial_input.push_str(&format!("#{} ", cat));
                    }

                    state.input_buffer = initial_input;
                    state.cursor_position = state.input_buffer.len();

                    state.mode = InputMode::Creating;
                    state.creating_child_of = Some(uid);
                    state.message = format!("New Child of '{}'...", summary);
                }
            }
            KeyCode::Char('y') => {
                if let Some(t) = state.get_selected_task() {
                    let uid = t.uid.clone();
                    let summary = t.summary.clone();
                    state.yanked_uid = Some(uid);
                    state.message = format!("Yanked: {}", summary);
                }
            }
            KeyCode::Char('b') => {
                let data = if let Some(yanked) = &state.yanked_uid {
                    state
                        .get_selected_task()
                        .map(|current| (current.uid.clone(), yanked.clone()))
                } else {
                    None
                };

                if let Some((curr_uid, yanked_uid)) = data {
                    if curr_uid == yanked_uid {
                        state.message = "Cannot depend on self!".to_string();
                    } else if let Some(updated) = state.store.add_dependency(&curr_uid, yanked_uid)
                    {
                        state.yanked_uid = None;
                        state.refresh_filtered_view();
                        return Some(Action::UpdateTask(updated));
                    }
                }
            }
            KeyCode::Char('l') => {
                let data = if let Some(yanked) = &state.yanked_uid {
                    state
                        .get_selected_task()
                        .map(|current| (current.uid.clone(), yanked.clone()))
                } else {
                    None
                };

                if let Some((curr_uid, yanked_uid)) = data {
                    if curr_uid == yanked_uid {
                        state.message = "Cannot relate to self!".to_string();
                    } else if let Some(updated) = state.store.add_related_to(&curr_uid, yanked_uid)
                    {
                        state.yanked_uid = None;
                        state.refresh_filtered_view();
                        return Some(Action::UpdateTask(updated));
                    }
                }
            }
            KeyCode::Char('.') | KeyCode::Char('>') => {
                if state.active_focus == Focus::Main
                    && let Some(idx) = state.list_state.selected()
                    && idx > 0
                    && idx < state.tasks.len()
                {
                    let parent_uid = state.tasks[idx - 1].uid.clone();
                    let current_uid = state.tasks[idx].uid.clone();
                    if let Some(updated) = state.store.set_parent(&current_uid, Some(parent_uid)) {
                        state.refresh_filtered_view();
                        return Some(Action::UpdateTask(updated));
                    }
                }
            }
            KeyCode::Char(',') | KeyCode::Char('<') => {
                if state.active_focus == Focus::Main
                    && let Some(view_task) = state.get_selected_task()
                    && view_task.parent_uid.is_some()
                {
                    let uid = view_task.uid.clone();
                    if let Some(updated) = state.store.set_parent(&uid, None) {
                        state.refresh_filtered_view();
                        return Some(Action::UpdateTask(updated));
                    }
                }
            }
            KeyCode::Char('X') => {
                // Step 1: Select source local calendar
                state.export_source_calendars = state
                    .calendars
                    .iter()
                    .filter(|c| {
                        c.href.starts_with("local://")
                            && !state.disabled_calendars.contains(&c.href)
                    })
                    .cloned()
                    .collect();
                if !state.export_source_calendars.is_empty() {
                    state.export_source_selection_state.select(Some(0));
                    state.mode = InputMode::SelectingExportSource;
                    state.message = "Select source local calendar to export from.".to_string();
                }
            }
            KeyCode::Char('M') => {
                if let Some(task) = state.get_selected_task() {
                    let current_href = task.calendar_href.clone();
                    state.move_targets = state
                        .calendars
                        .iter()
                        .filter(|c| {
                            c.href != current_href && !state.disabled_calendars.contains(&c.href)
                        })
                        .cloned()
                        .collect();
                    if !state.move_targets.is_empty() {
                        state.move_selection_state.select(Some(0));
                        state.mode = InputMode::Moving;
                        state.message = "Select a calendar and press Enter.".to_string();
                    }
                }
            }
            KeyCode::Down | KeyCode::Char('j') => state.next(),
            KeyCode::Up | KeyCode::Char('k') => state.previous(),
            KeyCode::PageDown => state.jump_forward(10),
            KeyCode::PageUp => state.jump_backward(10),
            KeyCode::Tab => state.toggle_focus(),
            KeyCode::Char('1') => {
                state.sidebar_mode = SidebarMode::Calendars;
                state.refresh_filtered_view();
            }
            KeyCode::Char('2') => {
                state.sidebar_mode = SidebarMode::Categories;
                state.refresh_filtered_view();
            }
            KeyCode::Char('3') => {
                state.sidebar_mode = SidebarMode::Locations;
                state.refresh_filtered_view();
            }
            KeyCode::Char('m') => {
                state.match_all_categories = !state.match_all_categories;
                state.refresh_filtered_view();
            }
            KeyCode::Char('H') => {
                state.hide_completed = !state.hide_completed;
                state.refresh_filtered_view();
            }
            KeyCode::Char('L') => {
                // Enter relationship browsing mode to navigate to linked tasks
                if let Some(task) = state.get_selected_task() {
                    let mut items = Vec::new();

                    // Add blocked-by dependencies
                    for dep_uid in &task.dependencies {
                        let name = state
                            .store
                            .get_summary(dep_uid)
                            .unwrap_or_else(|| "Unknown task".to_string());
                        let is_done = state.store.get_task_status(dep_uid).unwrap_or(false);
                        let check = if is_done { "[x]" } else { "[ ]" };
                        items.push((dep_uid.clone(), format!("⬆ {} {}", check, name)));
                    }

                    // Add outgoing relations
                    for related_uid in &task.related_to {
                        let name = state
                            .store
                            .get_summary(related_uid)
                            .unwrap_or_else(|| "Unknown task".to_string());
                        items.push((related_uid.clone(), format!("→ {}", name)));
                    }

                    // Add incoming relations
                    let incoming_related = state.store.get_tasks_related_to(&task.uid);
                    for (related_uid, related_name) in incoming_related {
                        items.push((related_uid, format!("← {}", related_name)));
                    }

                    if !items.is_empty() {
                        state.relationship_items = items;
                        state.relationship_selection_state.select(Some(0));
                        state.mode = InputMode::RelationshipBrowsing;
                        state.message =
                            "Select task to jump to (Enter) or Esc to cancel".to_string();
                    } else {
                        state.message = "No related tasks to browse.".to_string();
                    }
                }
            }
            KeyCode::Char('*') => {
                if state.active_focus == Focus::Sidebar {
                    match state.sidebar_mode {
                        SidebarMode::Calendars => {
                            let enabled_count = state
                                .calendars
                                .iter()
                                .filter(|c| !state.disabled_calendars.contains(&c.href))
                                .count();
                            let visible_count = state
                                .calendars
                                .iter()
                                .filter(|c| {
                                    !state.disabled_calendars.contains(&c.href)
                                        && !state.hidden_calendars.contains(&c.href)
                                })
                                .count();
                            if visible_count == enabled_count {
                                for cal in &state.calendars {
                                    if state.active_cal_href.as_ref() != Some(&cal.href) {
                                        state.hidden_calendars.insert(cal.href.clone());
                                    }
                                }
                            } else {
                                state.hidden_calendars.clear();
                                let _ = action_tx.send(Action::Refresh).await;
                            }
                        }
                        SidebarMode::Categories => {
                            state.selected_categories.clear();
                        }
                        SidebarMode::Locations => {
                            state.selected_locations.clear();
                        }
                    }
                    state.refresh_filtered_view();
                }
            }
            KeyCode::Right => {
                if state.active_focus == Focus::Sidebar
                    && state.sidebar_mode == SidebarMode::Calendars
                {
                    let target_href = if let Some(idx) = state.cal_state.selected() {
                        let filtered = state.get_filtered_calendars();
                        filtered.get(idx).map(|c| c.href.clone())
                    } else {
                        None
                    };

                    if let Some(href) = target_href {
                        state.active_cal_href = Some(href.clone());
                        state.hidden_calendars.clear();
                        for c in &state.calendars {
                            if c.href != href {
                                state.hidden_calendars.insert(c.href.clone());
                            }
                        }
                        state.refresh_filtered_view();
                        if href != LOCAL_CALENDAR_HREF {
                            return Some(Action::IsolateCalendar(href));
                        }
                    }
                } else if state.mode == InputMode::Editing {
                    state.move_cursor_right();
                }
            }
            KeyCode::Enter => {
                if state.active_focus == Focus::Sidebar {
                    match state.sidebar_mode {
                        SidebarMode::Calendars => {
                            let target_href = if let Some(idx) = state.cal_state.selected() {
                                let filtered = state.get_filtered_calendars();
                                filtered.get(idx).map(|c| c.href.clone())
                            } else {
                                None
                            };

                            if let Some(href) = target_href {
                                state.active_cal_href = Some(href.clone());
                                state.hidden_calendars.remove(&href);
                                state.refresh_filtered_view();
                                if href != LOCAL_CALENDAR_HREF {
                                    return Some(Action::SwitchCalendar(href));
                                }
                            }
                        }
                        SidebarMode::Categories => {
                            let cats = state.store.get_all_categories(
                                state.hide_completed,
                                state.hide_fully_completed_tags,
                                &state.selected_categories,
                                &state.hidden_calendars,
                            );
                            if let Some(idx) = state.cal_state.selected()
                                && let Some((c, _)) = cats.get(idx)
                            {
                                let c_clone = c.clone();
                                if state.selected_categories.contains(&c_clone) {
                                    state.selected_categories.remove(&c_clone);
                                } else {
                                    state.selected_categories.insert(c_clone);
                                }
                                state.refresh_filtered_view();
                            }
                        }
                        SidebarMode::Locations => {
                            let locs = state
                                .store
                                .get_all_locations(state.hide_completed, &state.hidden_calendars);
                            if let Some(idx) = state.cal_state.selected()
                                && let Some((l, _)) = locs.get(idx)
                            {
                                let l_clone = l.clone();
                                if state.selected_locations.contains(&l_clone) {
                                    state.selected_locations.remove(&l_clone);
                                } else {
                                    state.selected_locations.insert(l_clone);
                                }
                                state.refresh_filtered_view();
                            }
                        }
                    }
                }
            }
            KeyCode::Char('/') => {
                state.mode = InputMode::Searching;
                state.reset_input();
            }
            KeyCode::Char('a') => {
                state.mode = InputMode::Creating;
                state.reset_input();
                state.message = "New Task...".to_string();
            }
            KeyCode::Char('e') => {
                if let Some(t) = state.get_selected_task() {
                    state.input_buffer = t.to_smart_string();
                    state.cursor_position = state.input_buffer.len();
                    state.editing_index = state.list_state.selected();
                    state.mode = InputMode::Editing;
                }
            }
            KeyCode::Char('E') => {
                if state.active_focus == Focus::Main
                    && let Some(t) = state.get_selected_task()
                {
                    state.input_buffer = t.description.clone();
                    state.cursor_position = state.input_buffer.len();
                    state.editing_index = state.list_state.selected();
                    state.mode = InputMode::EditingDescription;
                }
            }
            _ => {}
        },
        InputMode::Moving => match key.code {
            KeyCode::Esc => {
                state.mode = InputMode::Normal;
                state.message = String::new();
            }
            KeyCode::Down | KeyCode::Char('j') => state.next_move_target(),
            KeyCode::Up | KeyCode::Char('k') => state.previous_move_target(),
            KeyCode::Enter => {
                let data = if let Some(task) = state.get_selected_task() {
                    if let Some(idx) = state.move_selection_state.selected() {
                        state
                            .move_targets
                            .get(idx)
                            .map(|target_cal| (task.clone(), target_cal.href.clone()))
                    } else {
                        None
                    }
                } else {
                    None
                };

                // Use the atomic store API that returns both the original (pre-mutation)
                // and updated (post-mutation) tasks so we don't rely on separate
                // lookups/clones and avoid races.
                if let Some((ref selected_task, ref target_href)) = data
                    && let Some((original_task, _updated_task)) = state
                        .store
                        .move_task(&selected_task.uid, target_href.clone())
                {
                    state.refresh_filtered_view();
                    state.message = "Moving task...".to_string();
                    state.mode = InputMode::Normal;
                    return Some(Action::MoveTask(original_task, target_href.clone()));
                }
                state.mode = InputMode::Normal;
            }
            _ => {}
        },
        InputMode::SelectingExportSource => match key.code {
            KeyCode::Esc => {
                state.mode = InputMode::Normal;
                state.message = String::new();
            }
            KeyCode::Down | KeyCode::Char('j') => state.next_export_source(),
            KeyCode::Up | KeyCode::Char('k') => state.previous_export_source(),
            KeyCode::Enter => {
                if let Some(idx) = state.export_source_selection_state.selected()
                    && let Some(source) = state.export_source_calendars.get(idx)
                {
                    // Step 2: Now select destination remote calendar
                    state.export_targets = state
                        .calendars
                        .iter()
                        .filter(|c| {
                            !c.href.starts_with("local://")
                                && !state.disabled_calendars.contains(&c.href)
                        })
                        .cloned()
                        .collect();
                    if !state.export_targets.is_empty() {
                        state.export_selection_state.select(Some(0));
                        state.mode = InputMode::Exporting;
                        state.message = format!(
                            "Exporting from '{}'. Select destination calendar.",
                            source.name
                        );
                    } else {
                        state.mode = InputMode::Normal;
                        state.message = "No remote calendars available for export.".to_string();
                    }
                }
            }
            _ => {}
        },
        InputMode::Exporting => match key.code {
            KeyCode::Esc => {
                state.mode = InputMode::Normal;
                state.message = String::new();
            }
            KeyCode::Down | KeyCode::Char('j') => state.next_export_target(),
            KeyCode::Up | KeyCode::Char('k') => state.previous_export_target(),
            KeyCode::Enter => {
                if let Some(source_idx) = state.export_source_selection_state.selected()
                    && let Some(source) = state.export_source_calendars.get(source_idx)
                    && let Some(target_idx) = state.export_selection_state.selected()
                    && let Some(target) = state.export_targets.get(target_idx)
                {
                    let source_href = source.href.clone();
                    let target_href = target.href.clone();
                    state.mode = InputMode::Normal;
                    state.message = String::new();
                    return Some(Action::MigrateLocal(source_href, target_href));
                }
            }
            _ => {}
        },
        InputMode::RelationshipBrowsing => match key.code {
            KeyCode::Esc => {
                state.mode = InputMode::Normal;
                state.message = String::new();
            }
            KeyCode::Down | KeyCode::Char('j') => {
                let len = state.relationship_items.len();
                if len > 0 {
                    let current = state.relationship_selection_state.selected().unwrap_or(0);
                    let next = if current >= len - 1 { 0 } else { current + 1 };
                    state.relationship_selection_state.select(Some(next));
                }
            }
            KeyCode::Up | KeyCode::Char('k') => {
                let len = state.relationship_items.len();
                if len > 0 {
                    let current = state.relationship_selection_state.selected().unwrap_or(0);
                    let prev = if current == 0 { len - 1 } else { current - 1 };
                    state.relationship_selection_state.select(Some(prev));
                }
            }
            KeyCode::Enter => {
                if let Some(idx) = state.relationship_selection_state.selected()
                    && let Some((target_uid, _)) = state.relationship_items.get(idx)
                {
                    // Jump to the target task
                    let target_uid = target_uid.clone();

                    // Find which calendar this task belongs to
                    if let Some(href) = state.store.index.get(&target_uid).cloned() {
                        // Clear filters that might hide the task
                        state.active_search_query.clear();
                        state.selected_categories.clear();
                        state.selected_locations.clear();

                        // Switch calendar if needed and unhide
                        if state.active_cal_href.as_ref() != Some(&href) {
                            state.active_cal_href = Some(href.clone());
                            state.hidden_calendars.remove(&href);
                        }

                        state.refresh_filtered_view();

                        // Find and select the target task in the list
                        if let Some(task_idx) = state.tasks.iter().position(|t| t.uid == target_uid)
                        {
                            state.list_state.select(Some(task_idx));
                        }

                        state.mode = InputMode::Normal;
                        state.message = "Jumped to task".to_string();
                    } else {
                        state.message = "Task not found".to_string();
                        state.mode = InputMode::Normal;
                    }
                }
            }
            _ => {}
        },
    }
    None
}
