// src/modes/handlers/event.rs
use crate::config::binds::config::Config;
use crate::config::binds::key_sequences::KeySequenceTracker;
use crate::functions::common::buffer;
use crate::functions::modes::navigation::add_logic_nav;
use crate::functions::modes::navigation::add_logic_nav::SaveLogicResultSender;
use crate::functions::modes::navigation::add_table_nav::SaveTableResultSender;
use crate::functions::modes::navigation::{add_table_nav, admin_nav};
use crate::modes::general::command_navigation::{
    handle_command_navigation_event, NavigationState,
};
use crate::modes::{
    canvas::{common_mode, edit, read_only},
    common::{command_mode, commands::CommandHandler},
    general::{dialog, navigation},
    handlers::mode_manager::{AppMode, ModeManager},
};
use crate::state::pages::canvas_state::CanvasState as LegacyCanvasState;
use crate::services::auth::AuthClient;
use crate::services::grpc_client::GrpcClient;
use canvas::{canvas::CanvasAction, dispatcher::ActionDispatcher};
use canvas::canvas::CanvasState as LibraryCanvasState;
use super::event_helper::*;
use crate::state::{
    app::{
        buffer::{AppView, BufferState},
        highlight::HighlightState,
        search::SearchState, // Correctly imported
        state::AppState,
    },
    pages::{
        admin::AdminState,
        auth::{AuthState, LoginState, RegisterState},
        canvas_state::CanvasState,
        form::FormState,
        intro::IntroState,
    },
};
use crate::tui::functions::common::login::LoginResult;
use crate::tui::functions::common::register::RegisterResult;
use crate::tui::{
    functions::common::{form::SaveOutcome, login, register},
    terminal::core::TerminalCore,
    {admin, intro},
};
use crate::ui::handlers::context::UiContext;
use crate::ui::handlers::rat_state::UiStateHandler;
use anyhow::Result;
use common::proto::komp_ac::search::search_response::Hit;
use crossterm::cursor::SetCursorStyle;
use crossterm::event::{Event, KeyCode, KeyEvent};
use tokio::sync::mpsc;
use tokio::sync::mpsc::unbounded_channel;
use tracing::{error, info};

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum EventOutcome {
    Ok(String),
    Exit(String),
    DataSaved(SaveOutcome, String),
    ButtonSelected { context: UiContext, index: usize },
    TableSelected { path: String },
}

impl EventOutcome {
    pub fn get_message_if_ok(&self) -> String {
        match self {
            EventOutcome::Ok(msg) => msg.clone(),
            _ => String::new(),
        }
    }
}

pub struct EventHandler {
    pub command_mode: bool,
    pub command_input: String,
    pub command_message: String,
    pub is_edit_mode: bool,
    pub highlight_state: HighlightState,
    pub edit_mode_cooldown: bool,
    pub ideal_cursor_column: usize,
    pub key_sequence_tracker: KeySequenceTracker,
    pub auth_client: AuthClient,
    pub grpc_client: GrpcClient,
    pub login_result_sender: mpsc::Sender<LoginResult>,
    pub register_result_sender: mpsc::Sender<RegisterResult>,
    pub save_table_result_sender: SaveTableResultSender,
    pub save_logic_result_sender: SaveLogicResultSender,
    pub navigation_state: NavigationState,
    pub search_result_sender: mpsc::UnboundedSender<Vec<Hit>>,
    pub search_result_receiver: mpsc::UnboundedReceiver<Vec<Hit>>,
    // --- ADDED FOR LIVE AUTOCOMPLETE ---
    pub autocomplete_result_sender: mpsc::UnboundedSender<Vec<Hit>>,
    pub autocomplete_result_receiver: mpsc::UnboundedReceiver<Vec<Hit>>,
}

impl EventHandler {
    pub async fn new(
        login_result_sender: mpsc::Sender<LoginResult>,
        register_result_sender: mpsc::Sender<RegisterResult>,
        save_table_result_sender: SaveTableResultSender,
        save_logic_result_sender: SaveLogicResultSender,
        grpc_client: GrpcClient,
    ) -> Result<Self> {
        let (search_tx, search_rx) = unbounded_channel();
        let (autocomplete_tx, autocomplete_rx) = unbounded_channel(); // ADDED
        Ok(EventHandler {
            command_mode: false,
            command_input: String::new(),
            command_message: String::new(),
            is_edit_mode: false,
            highlight_state: HighlightState::Off,
            edit_mode_cooldown: false,
            ideal_cursor_column: 0,
            key_sequence_tracker: KeySequenceTracker::new(400),
            auth_client: AuthClient::new().await?,
            grpc_client,
            login_result_sender,
            register_result_sender,
            save_table_result_sender,
            save_logic_result_sender,
            navigation_state: NavigationState::new(),
            search_result_sender: search_tx,
            search_result_receiver: search_rx,
            // --- ADDED ---
            autocomplete_result_sender: autocomplete_tx,
            autocomplete_result_receiver: autocomplete_rx,
        })
    }

    pub fn is_navigation_active(&self) -> bool {
        self.navigation_state.active
    }

    pub fn activate_find_file(&mut self, options: Vec<String>) {
        self.navigation_state.activate_find_file(options);
    }

    // This function handles state changes.
    async fn handle_search_palette_event(
        &mut self,
        key_event: KeyEvent,
        form_state: &mut FormState,
        app_state: &mut AppState,
    ) -> Result<EventOutcome> {
        let mut should_close = false;
        let mut outcome_message = String::new();
        let mut trigger_search = false;

        if let Some(search_state) = app_state.search_state.as_mut() {
            match key_event.code {
                KeyCode::Esc => {
                    should_close = true;
                    outcome_message = "Search cancelled".to_string();
                }
                KeyCode::Enter => {
                    if let Some(selected_hit) =
                        search_state.results.get(search_state.selected_index)
                    {
                        if let Ok(data) = serde_json::from_str::<
                            std::collections::HashMap<String, String>,
                        >(&selected_hit.content_json)
                        {
                            let detached_pos = form_state.total_count + 2;
                            form_state
                                .update_from_response(&data, detached_pos);
                        }
                        should_close = true;
                        outcome_message =
                            format!("Loaded record ID {}", selected_hit.id);
                    }
                }
                KeyCode::Up => search_state.previous_result(),
                KeyCode::Down => search_state.next_result(),
                KeyCode::Char(c) => {
                    search_state
                        .input
                        .insert(search_state.cursor_position, c);
                    search_state.cursor_position += 1;
                    trigger_search = true;
                }
                KeyCode::Backspace => {
                    if search_state.cursor_position > 0 {
                        search_state.cursor_position -= 1;
                        search_state.input.remove(search_state.cursor_position);
                        trigger_search = true;
                    }
                }
                KeyCode::Left => {
                    search_state.cursor_position =
                        search_state.cursor_position.saturating_sub(1);
                }
                KeyCode::Right => {
                    if search_state.cursor_position < search_state.input.len()
                    {
                        search_state.cursor_position += 1;
                    }
                }
                _ => {}
            }

            // --- START CORRECTED LOGIC ---
            if trigger_search {
                search_state.is_loading = true;
                search_state.results.clear();
                search_state.selected_index = 0;

                let query = search_state.input.clone();
                let table_name = search_state.table_name.clone();
                let sender = self.search_result_sender.clone();
                let mut grpc_client = self.grpc_client.clone();

                info!(
                    "--- 1. Spawning search task for query: '{}' ---",
                    query
                );
                // We now move the grpc_client into the task, just like with login.
                tokio::spawn(async move {
                    info!("--- 2. Background task started. ---");
                    match grpc_client.search_table(table_name, query).await {
                        Ok(response) => {
                            info!(
                                "--- 3a. gRPC call successful. Found {} hits. ---",
                                response.hits.len()
                            );
                            let _ = sender.send(response.hits);
                        }
                        Err(e) => {
                            // THE FIX: Use the debug formatter `{:?}` to print the full error chain.
                            error!("--- 3b. gRPC call failed: {:?} ---", e);
                            let _ = sender.send(vec![]);
                        }
                    }
                });
            }
        }

        // The borrow on `app_state.search_state` ends here.
        // Now we can safely modify the Option itself.
        if should_close {
            app_state.search_state = None;
            app_state.ui.show_search_palette = false;
            app_state.ui.focus_outside_canvas = false;
        }

        Ok(EventOutcome::Ok(outcome_message))
    }

    #[allow(clippy::too_many_arguments)]
    pub async fn handle_event(
        &mut self,
        event: Event,
        config: &Config,
        terminal: &mut TerminalCore,
        command_handler: &mut CommandHandler,
        form_state: &mut FormState,
        auth_state: &mut AuthState,
        login_state: &mut LoginState,
        register_state: &mut RegisterState,
        intro_state: &mut IntroState,
        admin_state: &mut AdminState,
        buffer_state: &mut BufferState,
        app_state: &mut AppState,
    ) -> Result<EventOutcome> {
        if app_state.ui.show_search_palette {
            if let Event::Key(key_event) = event {
                // The call no longer passes grpc_client
                return self
                    .handle_search_palette_event(
                        key_event,
                        form_state,
                        app_state,
                    )
                    .await;
            }
            return Ok(EventOutcome::Ok(String::new()));
        }

        let mut current_mode =
            ModeManager::derive_mode(app_state, self, admin_state);

        if current_mode == AppMode::General && self.navigation_state.active {
            if let Event::Key(key_event) = event {
                let outcome = handle_command_navigation_event(
                    &mut self.navigation_state,
                    key_event,
                    config,
                )
                .await?;

                if !self.navigation_state.active {
                    self.command_message = outcome.get_message_if_ok();
                    current_mode =
                        ModeManager::derive_mode(app_state, self, admin_state);
                }
                app_state.update_mode(current_mode);
                return Ok(outcome);
            }
            app_state.update_mode(current_mode);
            return Ok(EventOutcome::Ok(String::new()));
        }

        app_state.update_mode(current_mode);

        let current_view = {
            let ui = &app_state.ui;
            if ui.show_intro {
                AppView::Intro
            } else if ui.show_login {
                AppView::Login
            } else if ui.show_register {
                AppView::Register
            } else if ui.show_admin {
                AppView::Admin
            } else if ui.show_add_logic {
                AppView::AddLogic
            } else if ui.show_add_table {
                AppView::AddTable
            } else if ui.show_form {
                AppView::Form
            } else {
                AppView::Scratch
            }
        };
        buffer_state.update_history(current_view);

        if app_state.ui.dialog.dialog_show {
            if let Event::Key(key_event) = event {
                if let Some(dialog_result) = dialog::handle_dialog_event(
                    &Event::Key(key_event),
                    config,
                    app_state,
                    login_state,
                    register_state,
                    buffer_state,
                    admin_state,
                )
                .await
                {
                    return dialog_result;
                }
            } else if let Event::Resize(_, _) = event {
            }
            return Ok(EventOutcome::Ok(String::new()));
        }

        if let Event::Key(key_event) = event {
            let key_code = key_event.code;
            let modifiers = key_event.modifiers;

            if UiStateHandler::toggle_sidebar(
                &mut app_state.ui,
                config,
                key_code,
                modifiers,
            ) {
                let message = format!(
                    "Sidebar {}",
                    if app_state.ui.show_sidebar {
                        "shown"
                    } else {
                        "hidden"
                    }
                );
                return Ok(EventOutcome::Ok(message));
            }
            if UiStateHandler::toggle_buffer_list(
                &mut app_state.ui,
                config,
                key_code,
                modifiers,
            ) {
                let message = format!(
                    "Buffer {}",
                    if app_state.ui.show_buffer_list {
                        "shown"
                    } else {
                        "hidden"
                    }
                );
                return Ok(EventOutcome::Ok(message));
            }

            if !matches!(current_mode, AppMode::Edit | AppMode::Command) {
                if let Some(action) = config.get_action_for_key_in_mode(
                    &config.keybindings.global,
                    key_code,
                    modifiers,
                ) {
                    match action {
                        "next_buffer" => {
                            if buffer::switch_buffer(buffer_state, true) {
                                return Ok(EventOutcome::Ok(
                                    "Switched to next buffer".to_string(),
                                ));
                            }
                        }
                        "previous_buffer" => {
                            if buffer::switch_buffer(buffer_state, false) {
                                return Ok(EventOutcome::Ok(
                                    "Switched to previous buffer".to_string(),
                                ));
                            }
                        }
                        "close_buffer" => {
                            let current_table_name =
                                app_state.current_view_table_name.as_deref();
                            let message = buffer_state
                                .close_buffer_with_intro_fallback(
                                    current_table_name,
                                );
                            return Ok(EventOutcome::Ok(message));
                        }
                        _ => {}
                    }
                }

                if let Some(action) =
                    config.get_general_action(key_code, modifiers)
                {
                    if action == "open_search" {
                        if app_state.ui.show_form {
                            if let Some(table_name) =
                                app_state.current_view_table_name.clone()
                            {
                                app_state.ui.show_search_palette = true;
                                app_state.search_state =
                                    Some(SearchState::new(table_name));
                                app_state.ui.focus_outside_canvas = true;
                                return Ok(EventOutcome::Ok(
                                    "Search palette opened".to_string(),
                                ));
                            }
                        }
                    }
                }
            }

            match current_mode {
                AppMode::General => {
                    if app_state.ui.show_admin
                        && auth_state.role.as_deref() == Some("admin")
                    {
                        if admin_nav::handle_admin_navigation(
                            key_event,
                            config,
                            app_state,
                            admin_state,
                            buffer_state,
                            &mut self.command_message,
                        ) {
                            return Ok(EventOutcome::Ok(
                                self.command_message.clone(),
                            ));
                        }
                    }

                    if app_state.ui.show_add_logic {
                        let client_clone = self.grpc_client.clone();
                        let sender_clone = self.save_logic_result_sender.clone();
                        if add_logic_nav::handle_add_logic_navigation(
                            key_event,
                            config,
                            app_state,
                            &mut admin_state.add_logic_state,
                            &mut self.is_edit_mode,
                            buffer_state,
                            client_clone,
                            sender_clone,
                            &mut self.command_message,
                        ) {
                            return Ok(EventOutcome::Ok(
                                self.command_message.clone(),
                            ));
                        }
                    }

                    if app_state.ui.show_add_table {
                        let client_clone = self.grpc_client.clone();
                        let sender_clone = self.save_table_result_sender.clone();
                        if add_table_nav::handle_add_table_navigation(
                            key_event,
                            config,
                            app_state,
                            &mut admin_state.add_table_state,
                            client_clone,
                            sender_clone,
                            &mut self.command_message,
                        ) {
                            return Ok(EventOutcome::Ok(
                                self.command_message.clone(),
                            ));
                        }
                    }

                    let nav_outcome = navigation::handle_navigation_event(
                        key_event,
                        config,
                        form_state,
                        app_state,
                        login_state,
                        register_state,
                        intro_state,
                        admin_state,
                        &mut self.command_mode,
                        &mut self.command_input,
                        &mut self.command_message,
                        &mut self.navigation_state,
                    )
                    .await;

                    match nav_outcome {
                        Ok(EventOutcome::ButtonSelected { context, index }) => {
                            let message = match context {
                                UiContext::Intro => {
                                    intro::handle_intro_selection(
                                        app_state,
                                        buffer_state,
                                        index,
                                    );
                                    if app_state.ui.show_admin
                                        && !app_state
                                            .profile_tree
                                            .profiles
                                            .is_empty()
                                    {
                                        admin_state
                                            .profile_list_state
                                            .select(Some(0));
                                    }
                                    format!("Intro Option {} selected", index)
                                }
                                UiContext::Login => match index {
                                    0 => login::initiate_login(
                                        login_state,
                                        app_state,
                                        self.auth_client.clone(),
                                        self.login_result_sender.clone(),
                                    ),
                                    1 => login::back_to_main(
                                        login_state,
                                        app_state,
                                        buffer_state,
                                    )
                                    .await,
                                    _ => "Invalid Login Option".to_string(),
                                },
                                UiContext::Register => match index {
                                    0 => register::initiate_registration(
                                        register_state,
                                        app_state,
                                        self.auth_client.clone(),
                                        self.register_result_sender.clone(),
                                    ),
                                    1 => register::back_to_login(
                                        register_state,
                                        app_state,
                                        buffer_state,
                                    )
                                    .await,
                                    _ => "Invalid Login Option".to_string(),
                                },
                                UiContext::Admin => {
                                    admin::handle_admin_selection(
                                        app_state,
                                        admin_state,
                                    );
                                    format!("Admin Option {} selected", index)
                                }
                                UiContext::Dialog => "Internal error: Unexpected dialog state"
                                    .to_string(),
                            };
                            return Ok(EventOutcome::Ok(message));
                        }
                        other => return other,
                    }
                }

                AppMode::ReadOnly => {
                    // Handle highlight mode transitions
                    if config.get_read_only_action_for_key(key_code, modifiers) == Some("enter_highlight_mode_linewise")
                        && ModeManager::can_enter_highlight_mode(current_mode)
                    {
                        let current_field_index = get_current_field_for_state(
                            app_state,
                            login_state,
                            register_state,
                            form_state
                        );
                        self.highlight_state = HighlightState::Linewise {
                            anchor_line: current_field_index
                        };
                        self.command_message = "-- LINE HIGHLIGHT --".to_string();
                        return Ok(EventOutcome::Ok(self.command_message.clone()));
                    }
                    else if config.get_read_only_action_for_key(key_code, modifiers) == Some("enter_highlight_mode")
                        && ModeManager::can_enter_highlight_mode(current_mode)
                    {
                        let current_field_index = get_current_field_for_state(
                            app_state,
                            login_state,
                            register_state,
                            form_state
                        );
                        let current_cursor_pos = get_current_cursor_pos_for_state(
                            app_state,
                            login_state,
                            register_state,
                            form_state
                        );
                        let anchor = (current_field_index, current_cursor_pos);
                        self.highlight_state = HighlightState::Characterwise { anchor };
                        self.command_message = "-- HIGHLIGHT --".to_string();
                        return Ok(EventOutcome::Ok(self.command_message.clone()));
                    }

                    // Handle edit mode transitions
                    else if config.get_read_only_action_for_key(key_code, modifiers).as_deref() == Some("enter_edit_mode_before")
                        && ModeManager::can_enter_edit_mode(current_mode)
                    {
                        self.is_edit_mode = true;
                        self.edit_mode_cooldown = true;
                        self.command_message = "Edit mode".to_string();
                        terminal.set_cursor_style(SetCursorStyle::BlinkingBar)?;
                        return Ok(EventOutcome::Ok(self.command_message.clone()));
                    }
                    else if config.get_read_only_action_for_key(key_code, modifiers).as_deref() == Some("enter_edit_mode_after")
                        && ModeManager::can_enter_edit_mode(current_mode)
                    {
                        let current_input = get_current_input_for_state(
                            app_state,
                            login_state,
                            register_state,
                            form_state
                        );
                        let current_cursor_pos = get_cursor_pos_for_mixed_state(
                            app_state,
                            login_state,
                            form_state
                        );

                        // Move cursor forward if possible
                        if !current_input.is_empty() && current_cursor_pos < current_input.len() {
                            let new_cursor_pos = current_cursor_pos + 1;
                            set_current_cursor_pos_for_state(
                                app_state,
                                login_state,
                                register_state,
                                form_state,
                                new_cursor_pos
                            );
                            self.ideal_cursor_column = get_current_cursor_pos_for_state(
                                app_state,
                                login_state,
                                register_state,
                                form_state
                            );
                        }

                        self.is_edit_mode = true;
                        self.edit_mode_cooldown = true;
                        app_state.ui.focus_outside_canvas = false;
                        self.command_message = "Edit mode (after cursor)".to_string();
                        terminal.set_cursor_style(SetCursorStyle::BlinkingBar)?;
                        return Ok(EventOutcome::Ok(self.command_message.clone()));
                    }
                    else if config.get_read_only_action_for_key(key_code, modifiers) == Some("enter_command_mode")
                        && ModeManager::can_enter_command_mode(current_mode)
                    {
                        self.command_mode = true;
                        self.command_input.clear();
                        self.command_message.clear();
                        return Ok(EventOutcome::Ok(String::new()));
                    }

                    // Handle common actions (save, quit, etc.)
                    if let Some(action) = config.get_common_action(key_code, modifiers) {
                        match action {
                            "save" | "force_quit" | "save_and_quit" | "revert" => {
                                return common_mode::handle_core_action(
                                    action,
                                    form_state,
                                    auth_state,
                                    login_state,
                                    register_state,
                                    &mut self.grpc_client,
                                    &mut self.auth_client,
                                    terminal,
                                    app_state,
                                )
                                .await;
                            }
                            _ => {}
                        }
                    }

                    // Try canvas action for form first (NEW: Canvas library integration)
                    if app_state.ui.show_form {
                        if let Ok(Some(canvas_message)) = self.handle_form_canvas_action(
                            key_event,
                            config,
                            form_state,
                            false, // not edit mode
                        ).await {
                            return Ok(EventOutcome::Ok(canvas_message));
                        }
                    }

                    // Fallback to legacy read-only event handling
                    let (_should_exit, message) = read_only::handle_read_only_event(
                        app_state,
                        key_event,
                        config,
                        form_state,
                        login_state,
                        register_state,
                        &mut admin_state.add_table_state,
                        &mut admin_state.add_logic_state,
                        &mut self.key_sequence_tracker,
                        &mut self.grpc_client,
                        &mut self.command_message,
                        &mut self.edit_mode_cooldown,
                        &mut self.ideal_cursor_column,
                    )
                    .await?;

                    return Ok(EventOutcome::Ok(message));
                }

                AppMode::Highlight => {
                    if config.get_highlight_action_for_key(key_code, modifiers) == Some("exit_highlight_mode") {
                        self.highlight_state = HighlightState::Off;
                        self.command_message = "Exited highlight mode".to_string();
                        terminal.set_cursor_style(SetCursorStyle::SteadyBlock)?;
                        return Ok(EventOutcome::Ok(self.command_message.clone()));
                    } else if config.get_highlight_action_for_key(key_code, modifiers) == Some("enter_highlight_mode_linewise") {
                        if let HighlightState::Characterwise { anchor } = self.highlight_state {
                            self.highlight_state = HighlightState::Linewise { anchor_line: anchor.0 };
                            self.command_message = "-- LINE HIGHLIGHT --".to_string();
                            return Ok(EventOutcome::Ok(self.command_message.clone()));
                        }
                        return Ok(EventOutcome::Ok("".to_string()));
                    }

                    let (_should_exit, message) =
                        read_only::handle_read_only_event(
                            app_state,
                            key_event,
                            config,
                            form_state,
                            login_state,
                            register_state,
                            &mut admin_state.add_table_state,
                            &mut admin_state.add_logic_state,
                            &mut self.key_sequence_tracker,
                            &mut self.grpc_client, // <-- FIX 2
                            &mut self.command_message,
                            &mut self.edit_mode_cooldown,
                            &mut self.ideal_cursor_column,
                        )
                        .await?;
                    return Ok(EventOutcome::Ok(message));
                }

                AppMode::Edit => {
                    // Handle common actions (save, quit, etc.)
                    if let Some(action) = config.get_common_action(key_code, modifiers) {
                        match action {
                            "save" | "force_quit" | "save_and_quit" | "revert" => {
                                return common_mode::handle_core_action(
                                    action,
                                    form_state,
                                    auth_state,
                                    login_state,
                                    register_state,
                                    &mut self.grpc_client,
                                    &mut self.auth_client,
                                    terminal,
                                    app_state,
                                )
                                .await;
                            }
                            _ => {}
                        }
                    }

                    // Try canvas action for form first (NEW: Canvas library integration)
                    if app_state.ui.show_form {
                        if let Ok(Some(canvas_message)) = self.handle_form_canvas_action(
                            key_event,
                            config,
                            form_state,
                            true, // edit mode
                        ).await {
                            if !canvas_message.is_empty() {
                                self.command_message = canvas_message.clone();
                            }
                            return Ok(EventOutcome::Ok(canvas_message));
                        }
                    }

                    // Handle legacy edit events
                    let mut current_position = form_state.current_position;
                    let total_count = form_state.total_count;

                    let edit_result = edit::handle_edit_event(
                        key_event,
                        config,
                        form_state,
                        login_state,
                        register_state,
                        admin_state,
                        &mut current_position,
                        total_count,
                        self,
                        app_state,
                    )
                    .await;

                    match edit_result {
                        Ok(edit::EditEventOutcome::ExitEditMode) => {
                            self.is_edit_mode = false;
                            self.edit_mode_cooldown = true;

                            // Check for unsaved changes across all states
                            let has_changes = get_has_unsaved_changes_for_state(
                                app_state,
                                login_state,
                                register_state,
                                form_state
                            );

                            // Set appropriate message based on changes
                            self.command_message = if has_changes {
                                "Exited edit mode (unsaved changes remain)".to_string()
                            } else {
                                "Read-only mode".to_string()
                            };

                            terminal.set_cursor_style(SetCursorStyle::SteadyBlock)?;

                            // Get current input and cursor position
                            let current_input = get_current_input_for_state(
                                app_state,
                                login_state,
                                register_state,
                                form_state
                            );
                            let current_cursor_pos = get_current_cursor_pos_for_state(
                                app_state,
                                login_state,
                                register_state,
                                form_state
                            );

                            // Adjust cursor if it's beyond the input length
                            if !current_input.is_empty() && current_cursor_pos >= current_input.len() {
                                let new_pos = current_input.len() - 1;
                                set_current_cursor_pos_for_state(
                                    app_state,
                                    login_state,
                                    register_state,
                                    form_state,
                                    new_pos
                                );
                                self.ideal_cursor_column = new_pos;
                            }

                            return Ok(EventOutcome::Ok(self.command_message.clone()));
                        }

                        Ok(edit::EditEventOutcome::Message(msg)) => {
                            if !msg.is_empty() {
                                self.command_message = msg;
                            }
                            self.key_sequence_tracker.reset();
                            return Ok(EventOutcome::Ok(self.command_message.clone()));
                        }

                        Err(e) => {
                            return Err(e.into());
                        }
                    }
                }

                AppMode::Command => {
                    if config.is_exit_command_mode(key_code, modifiers) {
                        self.command_input.clear();
                        self.command_message.clear();
                        self.command_mode = false;
                        self.key_sequence_tracker.reset();
                        return Ok(EventOutcome::Ok(
                            "Exited command mode".to_string(),
                        ));
                    }

                    if config.is_command_execute(key_code, modifiers) {
                        let mut current_position = form_state.current_position;
                        let total_count = form_state.total_count;
                        let outcome = command_mode::handle_command_event(
                            key_event,
                            config,
                            app_state,
                            login_state,
                            register_state,
                            form_state,
                            &mut self.command_input,
                            &mut self.command_message,
                            &mut self.grpc_client, // <-- FIX 5
                            command_handler,
                            terminal,
                            &mut current_position,
                            total_count,
                        )
                        .await?;
                        form_state.current_position = current_position;
                        self.command_mode = false;
                        self.key_sequence_tracker.reset();
                        let new_mode = ModeManager::derive_mode(
                            app_state,
                            self,
                            admin_state,
                        );
                        app_state.update_mode(new_mode);
                        return Ok(outcome);
                    }

                    if key_code == KeyCode::Backspace {
                        self.command_input.pop();
                        self.key_sequence_tracker.reset();
                        return Ok(EventOutcome::Ok(String::new()));
                    }

                    if let KeyCode::Char(c) = key_code {
                        if c == 'f' {
                            self.key_sequence_tracker.add_key(key_code);
                            let sequence =
                                self.key_sequence_tracker.get_sequence();

                            if config.matches_key_sequence_generalized(
                                &sequence,
                            ) == Some("find_file_palette_toggle")
                            {
                                if app_state.ui.show_form
                                    || app_state.ui.show_intro
                                {
                                    let mut all_table_paths: Vec<String> =
                                        app_state
                                            .profile_tree
                                            .profiles
                                            .iter()
                                            .flat_map(|profile| {
                                                profile.tables.iter().map(
                                                    move |table| {
                                                        format!(
                                                            "{}/{}",
                                                            profile.name,
                                                            table.name
                                                        )
                                                    },
                                                )
                                            })
                                            .collect();
                                    all_table_paths.sort();

                                    self.navigation_state
                                        .activate_find_file(all_table_paths);

                                    self.command_mode = false;
                                    self.command_input.clear();
                                    self.command_message.clear();
                                    self.key_sequence_tracker.reset();
                                    return Ok(EventOutcome::Ok(
                                        "Table selection palette activated"
                                            .to_string(),
                                    ));
                                } else {
                                    self.key_sequence_tracker.reset();
                                    self.command_input.push('f');
                                    if sequence.len() > 1
                                        && sequence[0] == KeyCode::Char('f')
                                    {
                                        self.command_input.push('f');
                                    }
                                    self.command_message = "Find File not available in this view."
                                        .to_string();
                                    return Ok(EventOutcome::Ok(
                                        self.command_message.clone(),
                                    ));
                                }
                            }

                            if config.is_key_sequence_prefix(&sequence) {
                                return Ok(EventOutcome::Ok(String::new()));
                            }
                        }

                        if c != 'f'
                            && !self.key_sequence_tracker.current_sequence.is_empty()
                        {
                            self.key_sequence_tracker.reset();
                        }

                        self.command_input.push(c);
                        return Ok(EventOutcome::Ok(String::new()));
                    }

                    self.key_sequence_tracker.reset();
                    return Ok(EventOutcome::Ok(String::new()));
                }
            }
        } else if let Event::Resize(_, _) = event {
            return Ok(EventOutcome::Ok("Resized".to_string()));
        }

        self.edit_mode_cooldown = false;
        Ok(EventOutcome::Ok(self.command_message.clone()))
    }

    fn is_processed_command(&self, command: &str) -> bool {
        matches!(command, "w" | "q" | "q!" | "wq" | "r")
    }

    async fn handle_form_canvas_action(
        &mut self,
        key_event: KeyEvent,
        _config: &Config, // Not used anymore - canvas has its own config
        form_state: &mut FormState,
        is_edit_mode: bool,
    ) -> Result<Option<String>> {
        // Load canvas config (canvas_config.toml or vim defaults)
        let canvas_config = canvas::config::CanvasConfig::load();

        // Handle suggestion actions first if suggestions are active
        if form_state.autocomplete_active {
            if let Some(action_str) = canvas_config.get_suggestion_action(key_event.code, key_event.modifiers) {
                let canvas_action = CanvasAction::from_string(&action_str);
                match ActionDispatcher::dispatch(canvas_action, form_state, &mut self.ideal_cursor_column).await {
                    Ok(result) => return Ok(Some(result.message().unwrap_or("").to_string())),
                    Err(_) => return Ok(Some("Suggestion action failed".to_string())),
                }
            }

            // Fallback hardcoded suggestion handling
            match key_event.code {
                KeyCode::Up => {
                    if let Ok(result) = ActionDispatcher::dispatch(
                        CanvasAction::SuggestionUp,
                        form_state,
                        &mut self.ideal_cursor_column,
                    ).await {
                        return Ok(Some(result.message().unwrap_or("").to_string()));
                    }
                }
                KeyCode::Down => {
                    if let Ok(result) = ActionDispatcher::dispatch(
                        CanvasAction::SuggestionDown,
                        form_state,
                        &mut self.ideal_cursor_column,
                    ).await {
                        return Ok(Some(result.message().unwrap_or("").to_string()));
                    }
                }
                KeyCode::Enter => {
                    if let Ok(result) = ActionDispatcher::dispatch(
                        CanvasAction::SelectSuggestion,
                        form_state,
                        &mut self.ideal_cursor_column,
                    ).await {
                        return Ok(Some(result.message().unwrap_or("").to_string()));
                    }
                }
                KeyCode::Esc => {
                    if let Ok(result) = ActionDispatcher::dispatch(
                        CanvasAction::ExitSuggestions,
                        form_state,
                        &mut self.ideal_cursor_column,
                    ).await {
                        return Ok(Some(result.message().unwrap_or("").to_string()));
                    }
                }
                _ => {}
            }
        }

        // FIXED: Use canvas config instead of client config
        let action_str = canvas_config.get_action_for_key(
            key_event.code,
            key_event.modifiers,
            is_edit_mode,
            form_state.autocomplete_active
        );

        if let Some(action_str) = action_str {
            // Filter out mode transition actions - let legacy handlers deal with these
            if Self::is_mode_transition_action(action_str) {
                return Ok(None); // Let legacy handler handle mode transitions
            }

            let canvas_action = CanvasAction::from_string(&action_str);
            match ActionDispatcher::dispatch(
                canvas_action,
                form_state,
                &mut self.ideal_cursor_column,
            ).await {
                Ok(result) => {
                    return Ok(Some(result.message().unwrap_or("").to_string()));
                }
                Err(_) => {
                    return Ok(Some("Canvas action failed".to_string()));
                }
            }
        }

        // Fallback to automatic key handling for edit mode
        if is_edit_mode {
            if let Some(canvas_action) = CanvasAction::from_key(key_event.code) {
                match ActionDispatcher::dispatch(
                    canvas_action,
                    form_state,
                    &mut self.ideal_cursor_column,
                ).await {
                    Ok(result) => {
                        return Ok(Some(result.message().unwrap_or("").to_string()));
                    }
                    Err(_) => {
                        return Ok(Some("Auto action failed".to_string()));
                    }
                }
            }
        } else {
            // In read-only mode, only handle non-character keys
            let canvas_action = match key_event.code {
                // Only handle special keys that don't conflict with vim bindings
                KeyCode::Left => Some(CanvasAction::MoveLeft),
                KeyCode::Right => Some(CanvasAction::MoveRight),
                KeyCode::Up => Some(CanvasAction::MoveUp),
                KeyCode::Down => Some(CanvasAction::MoveDown),
                KeyCode::Home => Some(CanvasAction::MoveLineStart),
                KeyCode::End => Some(CanvasAction::MoveLineEnd),
                KeyCode::Tab => Some(CanvasAction::NextField),
                KeyCode::BackTab => Some(CanvasAction::PrevField),
                KeyCode::Delete => Some(CanvasAction::DeleteForward),
                KeyCode::Backspace => Some(CanvasAction::DeleteBackward),
                _ => None,
            };

            if let Some(canvas_action) = canvas_action {
                match ActionDispatcher::dispatch(
                    canvas_action,
                    form_state,
                    &mut self.ideal_cursor_column,
                ).await {
                    Ok(result) => {
                        return Ok(Some(result.message().unwrap_or("").to_string()));
                    }
                    Err(_) => {
                        return Ok(Some("Action failed".to_string()));
                    }
                }
            }
        }

        Ok(None)
    }

    // ADDED: Helper function to identify mode transition actions
    fn is_mode_transition_action(action: &str) -> bool {
        matches!(action,
            "exit" |
            "exit_edit_mode" |
            "enter_edit_mode_before" |
            "enter_edit_mode_after" |
            "enter_command_mode" |
            "exit_command_mode" |
            "enter_highlight_mode" |
            "enter_highlight_mode_linewise" |
            "exit_highlight_mode" |
            "save" |
            "quit" |
            "force_quit" |
            "save_and_quit" |
            "revert" |
            "enter_decider" |  // This is also handled specially by legacy system
            "trigger_autocomplete" |  // This is handled specially by legacy system
            "suggestion_up" |  // These are handled above in suggestion logic
            "suggestion_down" |
            "previous_entry" |  // Navigation between records
            "next_entry" |
            "toggle_sidebar" |
            "toggle_buffer_list" |
            "next_buffer" |
            "previous_buffer" |
            "close_buffer" |
            "open_search" |
            "find_file_palette_toggle"
        )
    }
}
