// src/functions/modes/navigation/add_table_nav.rs
use crate::config::binds::config::Config;
use crate::state::{
    app::state::AppState,
    pages::add_table::{AddTableFocus, AddTableState},
};
use crossterm::event::{KeyEvent};
use ratatui::widgets::TableState;
use crate::tui::functions::common::add_table::{handle_add_column_action, handle_save_table_action};
use crate::ui::handlers::context::DialogPurpose;
use crate::services::GrpcClient;
use tokio::sync::mpsc;
use anyhow::Result;

pub type SaveTableResultSender = mpsc::Sender<Result<String>>;

fn navigate_table_up(table_state: &mut TableState, item_count: usize) -> bool {
    if item_count == 0 { return false; }
    let current_selection = table_state.selected();
    match current_selection {
        Some(index) => {
            if index > 0 { table_state.select(Some(index - 1)); true }
            else { false }
        }
        None => { table_state.select(Some(0)); true }
    }
}

fn navigate_table_down(table_state: &mut TableState, item_count: usize) -> bool {
     if item_count == 0 { return false; }
    let current_selection = table_state.selected();
    match current_selection {
        Some(index) => {
            if index < item_count - 1 { table_state.select(Some(index + 1)); true }
            else { false }
        }
        None => { table_state.select(Some(0)); true }
    }
}

pub fn handle_add_table_navigation(
    key: KeyEvent,
    config: &Config,
    app_state: &mut AppState,
    add_table_state: &mut AddTableState,
    grpc_client: GrpcClient,
    save_result_sender: SaveTableResultSender,
    command_message: &mut String,
) -> bool {
    let action = config.get_general_action(key.code, key.modifiers);
    let current_focus = add_table_state.current_focus;
    let mut handled = true;
    let mut new_focus = current_focus;

    if matches!(current_focus, AddTableFocus::InsideColumnsTable | AddTableFocus::InsideIndexesTable | AddTableFocus::InsideLinksTable) {
        if matches!(action.as_deref(), Some("next_option") | Some("previous_option")) {
            *command_message = "Press Esc to exit table item navigation first.".to_string();
            return true;
        }
    }

    match action.as_deref() {
       Some("exit_table_scroll") => {
           match current_focus {
               AddTableFocus::InsideColumnsTable => {
                   add_table_state.column_table_state.select(None);
                   new_focus = AddTableFocus::ColumnsTable;
                   // *command_message = "Exited Columns Table".to_string(); // Minimal change: remove message
               }
               AddTableFocus::InsideIndexesTable => {
                   add_table_state.index_table_state.select(None);
                   new_focus = AddTableFocus::IndexesTable;
                   // *command_message = "Exited Indexes Table".to_string();
               }
               AddTableFocus::InsideLinksTable => {
                   add_table_state.link_table_state.select(None);
                   new_focus = AddTableFocus::LinksTable;
                   // *command_message = "Exited Links Table".to_string();
               }
               _ => handled = false,
           }
       }
        Some("move_up") => {
            match current_focus {
                AddTableFocus::InputTableName => {
                    // MINIMAL CHANGE: Do nothing, new_focus remains current_focus
                    // *command_message = "At top of form.".to_string(); // Remove message
                }
                AddTableFocus::InputColumnName => new_focus = AddTableFocus::InputTableName,
                AddTableFocus::InputColumnType => new_focus = AddTableFocus::InputColumnName,
                AddTableFocus::AddColumnButton => new_focus = AddTableFocus::InputColumnType,
                AddTableFocus::ColumnsTable => new_focus = AddTableFocus::AddColumnButton,
                AddTableFocus::IndexesTable => new_focus = AddTableFocus::ColumnsTable,
                AddTableFocus::LinksTable => new_focus = AddTableFocus::IndexesTable,
                AddTableFocus::InsideColumnsTable => { navigate_table_up(&mut add_table_state.column_table_state, add_table_state.columns.len()); }
                AddTableFocus::InsideIndexesTable => { navigate_table_up(&mut add_table_state.index_table_state, add_table_state.indexes.len()); }
                AddTableFocus::InsideLinksTable => { navigate_table_up(&mut add_table_state.link_table_state, add_table_state.links.len()); }
                AddTableFocus::SaveButton => new_focus = AddTableFocus::LinksTable,
                AddTableFocus::DeleteSelectedButton => new_focus = AddTableFocus::SaveButton,
                AddTableFocus::CancelButton => new_focus = AddTableFocus::DeleteSelectedButton,
            }
        }
        Some("move_down") => {
            match current_focus {
                AddTableFocus::InputTableName => new_focus = AddTableFocus::InputColumnName,
                AddTableFocus::InputColumnName => new_focus = AddTableFocus::InputColumnType,
                AddTableFocus::InputColumnType => {
                    add_table_state.last_canvas_field = 2;
                    new_focus = AddTableFocus::AddColumnButton;
                },
                AddTableFocus::AddColumnButton => new_focus = AddTableFocus::ColumnsTable,
                AddTableFocus::ColumnsTable => new_focus = AddTableFocus::IndexesTable,
                AddTableFocus::IndexesTable => new_focus = AddTableFocus::LinksTable,
                AddTableFocus::LinksTable => new_focus = AddTableFocus::SaveButton,
                AddTableFocus::InsideColumnsTable => { navigate_table_down(&mut add_table_state.column_table_state, add_table_state.columns.len()); }
                AddTableFocus::InsideIndexesTable => { navigate_table_down(&mut add_table_state.index_table_state, add_table_state.indexes.len()); }
                AddTableFocus::InsideLinksTable => { navigate_table_down(&mut add_table_state.link_table_state, add_table_state.links.len()); }
                AddTableFocus::SaveButton => new_focus = AddTableFocus::DeleteSelectedButton,
                AddTableFocus::DeleteSelectedButton => new_focus = AddTableFocus::CancelButton,
                AddTableFocus::CancelButton => {
                    // MINIMAL CHANGE: Do nothing, new_focus remains current_focus
                    // *command_message = "At bottom of form.".to_string(); // Remove message
                }
            }
        }
        Some("next_option") => { // This logic should already be non-wrapping
            match current_focus {
                AddTableFocus::InputTableName | AddTableFocus::InputColumnName | AddTableFocus::InputColumnType =>
                    { new_focus = AddTableFocus::AddColumnButton; }
                AddTableFocus::AddColumnButton => new_focus = AddTableFocus::ColumnsTable,
                AddTableFocus::ColumnsTable => new_focus = AddTableFocus::IndexesTable,
                AddTableFocus::IndexesTable => new_focus = AddTableFocus::LinksTable,
                AddTableFocus::LinksTable => new_focus = AddTableFocus::SaveButton,
                AddTableFocus::SaveButton => new_focus = AddTableFocus::DeleteSelectedButton,
                AddTableFocus::DeleteSelectedButton => new_focus = AddTableFocus::CancelButton,
                AddTableFocus::CancelButton => { /* *command_message = "At last focusable area.".to_string(); */ } // No change in focus
                _ => handled = false,
            }
        }
        Some("previous_option") => { // This logic should already be non-wrapping
            match current_focus {
                AddTableFocus::InputTableName | AddTableFocus::InputColumnName | AddTableFocus::InputColumnType =>
                    { /* *command_message = "At first focusable area.".to_string(); */ } // No change in focus
                AddTableFocus::AddColumnButton => new_focus = AddTableFocus::InputColumnType,
                AddTableFocus::ColumnsTable => new_focus = AddTableFocus::AddColumnButton,
                AddTableFocus::IndexesTable => new_focus = AddTableFocus::ColumnsTable,
                AddTableFocus::LinksTable => new_focus = AddTableFocus::IndexesTable,
                AddTableFocus::SaveButton => new_focus = AddTableFocus::LinksTable,
                AddTableFocus::DeleteSelectedButton => new_focus = AddTableFocus::SaveButton,
                AddTableFocus::CancelButton => new_focus = AddTableFocus::DeleteSelectedButton,
                _ => handled = false,
            }
        }
        Some("next_field") => {
            new_focus = match current_focus {
                AddTableFocus::InputTableName => AddTableFocus::InputColumnName, AddTableFocus::InputColumnName => AddTableFocus::InputColumnType, AddTableFocus::InputColumnType => AddTableFocus::AddColumnButton, AddTableFocus::AddColumnButton => AddTableFocus::ColumnsTable,
                AddTableFocus::ColumnsTable | AddTableFocus::InsideColumnsTable => AddTableFocus::IndexesTable, AddTableFocus::IndexesTable | AddTableFocus::InsideIndexesTable => AddTableFocus::LinksTable, AddTableFocus::LinksTable | AddTableFocus::InsideLinksTable => AddTableFocus::SaveButton,
                AddTableFocus::SaveButton => AddTableFocus::DeleteSelectedButton, AddTableFocus::DeleteSelectedButton => AddTableFocus::CancelButton, AddTableFocus::CancelButton => AddTableFocus::InputTableName,
            };
        }
        Some("prev_field") => {
            new_focus = match current_focus {
                AddTableFocus::InputTableName => AddTableFocus::CancelButton, AddTableFocus::InputColumnName => AddTableFocus::InputTableName, AddTableFocus::InputColumnType => AddTableFocus::InputColumnName, AddTableFocus::AddColumnButton => AddTableFocus::InputColumnType,
                AddTableFocus::ColumnsTable | AddTableFocus::InsideColumnsTable => AddTableFocus::AddColumnButton, AddTableFocus::IndexesTable | AddTableFocus::InsideIndexesTable => AddTableFocus::ColumnsTable, AddTableFocus::LinksTable | AddTableFocus::InsideLinksTable => AddTableFocus::IndexesTable,
                AddTableFocus::SaveButton => AddTableFocus::LinksTable, AddTableFocus::DeleteSelectedButton => AddTableFocus::SaveButton, AddTableFocus::CancelButton => AddTableFocus::DeleteSelectedButton,
            };
        }
        Some("select") => {
            match current_focus {
                AddTableFocus::ColumnsTable => { new_focus = AddTableFocus::InsideColumnsTable; if add_table_state.column_table_state.selected().is_none() && !add_table_state.columns.is_empty() { add_table_state.column_table_state.select(Some(0)); } /* Message removed */ }
                AddTableFocus::IndexesTable => { new_focus = AddTableFocus::InsideIndexesTable; if add_table_state.index_table_state.selected().is_none() && !add_table_state.indexes.is_empty() { add_table_state.index_table_state.select(Some(0)); } /* Message removed */ }
                AddTableFocus::LinksTable => { new_focus = AddTableFocus::InsideLinksTable; if add_table_state.link_table_state.selected().is_none() && !add_table_state.links.is_empty() { add_table_state.link_table_state.select(Some(0)); } /* Message removed */ }
                AddTableFocus::InsideColumnsTable => { if let Some(index) = add_table_state.column_table_state.selected() { if let Some(col) = add_table_state.columns.get_mut(index) { col.selected = !col.selected; add_table_state.has_unsaved_changes = true; /* Message removed */ }} /* else { Message removed } */ }
                AddTableFocus::InsideIndexesTable => { if let Some(index) = add_table_state.index_table_state.selected() { if let Some(idx_def) = add_table_state.indexes.get_mut(index) { idx_def.selected = !idx_def.selected; add_table_state.has_unsaved_changes = true; /* Message removed */ }} /* else { Message removed } */ }
                AddTableFocus::InsideLinksTable => { if let Some(index) = add_table_state.link_table_state.selected() { if let Some(link) = add_table_state.links.get_mut(index) { link.selected = !link.selected; add_table_state.has_unsaved_changes = true; /* Message removed */ }} /* else { Message removed } */ }
                AddTableFocus::AddColumnButton => { if let Some(focus_after_add) = handle_add_column_action(add_table_state, command_message) { new_focus = focus_after_add; } else { /* Message already set by handle_add_column_action */ }}
                AddTableFocus::SaveButton => { if add_table_state.table_name.is_empty() { *command_message = "Cannot save: Table name is empty.".to_string(); } else if add_table_state.columns.is_empty() { *command_message = "Cannot save: No columns defined.".to_string(); } else { *command_message = "Saving table...".to_string(); app_state.show_loading_dialog("Saving", "Please wait..."); let mut client_clone = grpc_client.clone(); let state_clone = add_table_state.clone(); let sender_clone = save_result_sender.clone(); tokio::spawn(async move { let result = handle_save_table_action(&mut client_clone, &state_clone).await; let _ = sender_clone.send(result).await; }); }}
                AddTableFocus::DeleteSelectedButton => { let columns_to_delete: Vec<(usize, String, String)> = add_table_state.columns.iter().enumerate().filter(|(_, col)| col.selected).map(|(index, col)| (index, col.name.clone(), col.data_type.clone())).collect(); if columns_to_delete.is_empty() { *command_message = "No columns selected for deletion.".to_string(); } else { let column_details: String = columns_to_delete.iter().map(|(index, name, dtype)| format!("{}. {} ({})", index + 1, name, dtype)).collect::<Vec<String>>().join("\n"); let message = format!("Delete the following columns?\n\n{}", column_details); app_state.show_dialog("Confirm Deletion", &message, vec!["Confirm".to_string(), "Cancel".to_string()], DialogPurpose::ConfirmDeleteColumns); }}
                AddTableFocus::CancelButton => { *command_message = "Action: Cancel Add Table (Not Implemented)".to_string(); }
                _ => { handled = false; }
            }
        }
        _ => handled = false,
    }

    if handled && current_focus != new_focus {
        add_table_state.current_focus = new_focus;
        // Minimal change: Command message update logic can be simplified or removed if not desired
        // For now, let's keep it minimal and only update if it was truly a focus change,
        // and not a boundary message.
        if !command_message.starts_with("At ") && current_focus != new_focus { // Avoid overwriting boundary messages
            // *command_message = format!("Focus: {:?}", add_table_state.current_focus); // Optional: restore if needed
        }


        let new_is_canvas_input_focus = matches!(new_focus,
            AddTableFocus::InputTableName | AddTableFocus::InputColumnName | AddTableFocus::InputColumnType
        );
        app_state.ui.focus_outside_canvas = !new_is_canvas_input_focus;
    }
    // If not handled, command_message remains as it was (e.g., from a deeper function call or previous event)
    // or can be cleared if that's the desired default. For minimal change, we leave it.

    handled
}
