// src/modes/canvas/read_only.rs

use crate::config::binds::config::Config;
use crate::config::binds::key_sequences::KeySequenceTracker;
use crate::services::grpc_client::GrpcClient;
use crate::state::pages::auth::LoginState;
use crate::state::pages::auth::RegisterState;
use crate::state::pages::canvas_state::CanvasState as LocalCanvasState;
use crate::state::pages::form::FormState;
use crate::state::pages::add_logic::AddLogicState;
use crate::state::pages::add_table::AddTableState;
use crate::state::app::state::AppState;
use crate::functions::modes::read_only::{add_logic_ro, auth_ro, form_ro, add_table_ro};
use canvas::{canvas::{CanvasAction, CanvasState, ActionResult}, dispatcher::ActionDispatcher};
use crossterm::event::KeyEvent;
use anyhow::Result;

pub async fn handle_form_readonly_with_canvas(
    key_event: KeyEvent,
    config: &Config,
    form_state: &mut FormState,
    ideal_cursor_column: &mut usize,
) -> Result<String> {
    // Try canvas action from key first
    if let Some(canvas_action) = CanvasAction::from_key(key_event.code) {
        match ActionDispatcher::dispatch(canvas_action, form_state, ideal_cursor_column).await {
            Ok(ActionResult::Success(msg)) => {
                return Ok(msg.unwrap_or_default());
            }
            Ok(ActionResult::HandledByFeature(msg)) => {
                return Ok(msg);
            }
            Ok(ActionResult::Error(msg)) => {
                return Ok(format!("Error: {}", msg));
            }
            Ok(ActionResult::RequiresContext(msg)) => {
                return Ok(format!("Context needed: {}", msg));
            }
            Err(_) => {
                // Fall through to try config mapping
            }
        }
    }

    // Try config-mapped action
    if let Some(action_str) = config.get_read_only_action_for_key(key_event.code, key_event.modifiers) {
        let canvas_action = CanvasAction::from_string(&action_str);
        match ActionDispatcher::dispatch(canvas_action, form_state, ideal_cursor_column).await {
            Ok(ActionResult::Success(msg)) => {
                return Ok(msg.unwrap_or_default());
            }
            Ok(ActionResult::HandledByFeature(msg)) => {
                return Ok(msg);
            }
            Ok(ActionResult::Error(msg)) => {
                return Ok(format!("Error: {}", msg));
            }
            Ok(ActionResult::RequiresContext(msg)) => {
                return Ok(format!("Context needed: {}", msg));
            }
            Err(e) => {
                return Ok(format!("Action failed: {}", e));
            }
        }
    }

    Ok(String::new())
}

pub async fn handle_read_only_event(
    app_state: &mut AppState,
    key: KeyEvent,
    config: &Config,
    form_state: &mut FormState,
    login_state: &mut LoginState,
    register_state: &mut RegisterState,
    add_table_state: &mut AddTableState,
    add_logic_state: &mut AddLogicState,
    key_sequence_tracker: &mut KeySequenceTracker,
    grpc_client: &mut GrpcClient,
    command_message: &mut String,
    edit_mode_cooldown: &mut bool,
    ideal_cursor_column: &mut usize,
) -> Result<(bool, String)> {
    if config.is_enter_edit_mode_before(key.code, key.modifiers) {
        *edit_mode_cooldown = true;
        *command_message = "Entering Edit mode".to_string();
        return Ok((false, command_message.clone()));
    }

    if config.is_enter_edit_mode_after(key.code, key.modifiers) {
        // Determine target state to adjust cursor

        if app_state.ui.show_login {
            let current_input = login_state.get_current_input();
            let current_pos = login_state.current_cursor_pos();
            if !current_input.is_empty() && current_pos < current_input.len() {
                login_state.set_current_cursor_pos(current_pos + 1);
                *ideal_cursor_column = login_state.current_cursor_pos();
            }
        } else if app_state.ui.show_add_logic {
            let current_input = add_logic_state.get_current_input();
            let current_pos = add_logic_state.current_cursor_pos();
            if !current_input.is_empty() && current_pos < current_input.len() {
                add_logic_state.set_current_cursor_pos(current_pos + 1);
                *ideal_cursor_column = add_logic_state.current_cursor_pos();
            }
        } else if app_state.ui.show_register {
            let current_input = register_state.get_current_input();
            let current_pos = register_state.current_cursor_pos();
            if !current_input.is_empty() && current_pos < current_input.len() {
                register_state.set_current_cursor_pos(current_pos + 1);
                *ideal_cursor_column = register_state.current_cursor_pos();
            }
        } else if app_state.ui.show_add_table {
            let current_input = add_table_state.get_current_input();
            let current_pos = add_table_state.current_cursor_pos();
            if !current_input.is_empty() && current_pos < current_input.len() {
                add_table_state.set_current_cursor_pos(current_pos + 1);
                *ideal_cursor_column = add_table_state.current_cursor_pos();
            }
        } else {
            // Handle FormState (uses library CanvasState)
            use canvas::canvas::CanvasState as LibraryCanvasState;  // Import at the top of the function
            let current_input = form_state.get_current_input();
            let current_pos = form_state.current_cursor_pos();
            if !current_input.is_empty() && current_pos < current_input.len() {
                form_state.set_current_cursor_pos(current_pos + 1);
                *ideal_cursor_column = form_state.current_cursor_pos();
            }
        }

        *edit_mode_cooldown = true;
        *command_message = "Entering Edit mode (after cursor)".to_string();
        return Ok((false, command_message.clone()));
    }

    const CONTEXT_ACTIONS_FORM: &[&str] = &[
        "previous_entry",
        "next_entry",
    ];
    const CONTEXT_ACTIONS_LOGIN: &[&str] = &[
        "previous_entry",
        "next_entry",
    ];

    if key.modifiers.is_empty() {
        key_sequence_tracker.add_key(key.code);
        let sequence = key_sequence_tracker.get_sequence();

        if let Some(action) = config.matches_key_sequence_generalized(&sequence).as_deref() {
            let result = if app_state.ui.show_form && CONTEXT_ACTIONS_FORM.contains(&action) {
                crate::tui::functions::form::handle_action(
                    action,
                    form_state,
                    grpc_client,
                    ideal_cursor_column,
                )
                .await?
            } else if app_state.ui.show_login && CONTEXT_ACTIONS_LOGIN.contains(&action) {
                crate::tui::functions::login::handle_action(action).await?
            } else if app_state.ui.show_add_table {
                add_table_ro::execute_action(
                    action,
                    app_state,
                    add_table_state,
                    ideal_cursor_column,
                    key_sequence_tracker,
                    command_message,
                ).await?
            } else if app_state.ui.show_add_logic {
                add_logic_ro::execute_action(
                    action,
                    app_state,
                    add_logic_state,
                    ideal_cursor_column,
                    key_sequence_tracker,
                    command_message,
                ).await?
            } else if app_state.ui.show_register{
                auth_ro::execute_action(
                    action,
                    app_state,
                    register_state,
                    ideal_cursor_column,
                    key_sequence_tracker,
                    command_message,
                ).await?
            } else if app_state.ui.show_login {
                auth_ro::execute_action(
                    action,
                    app_state,
                    login_state,
                    ideal_cursor_column,
                    key_sequence_tracker,
                    command_message,
                )
                .await?
            } else {
                form_ro::execute_action(
                    action,
                    form_state,
                    ideal_cursor_column,
                    key_sequence_tracker,
                    command_message,
                )
                .await?
            };
            key_sequence_tracker.reset();
            return Ok((false, result));
        }

        if config.is_key_sequence_prefix(&sequence) {
            return Ok((false, command_message.clone()));
        }

        if sequence.len() == 1 && !config.is_key_sequence_prefix(&sequence) {
            if let Some(action) = config.get_read_only_action_for_key(key.code, key.modifiers).as_deref() {
                let result = if app_state.ui.show_form && CONTEXT_ACTIONS_FORM.contains(&action) {
                    crate::tui::functions::form::handle_action(
                        action,
                        form_state,
                        grpc_client,
                        ideal_cursor_column,
                    )
                    .await?
                } else if app_state.ui.show_login && CONTEXT_ACTIONS_LOGIN.contains(&action) {
                    crate::tui::functions::login::handle_action(action).await?
                } else if app_state.ui.show_add_table {
                    add_table_ro::execute_action(
                        action,
                        app_state,
                        add_table_state,
                        ideal_cursor_column,
                        key_sequence_tracker,
                        command_message,
                    ).await?
                } else if app_state.ui.show_add_logic {
                    add_logic_ro::execute_action(
                        action,
                        app_state,
                        add_logic_state,
                        ideal_cursor_column,
                        key_sequence_tracker,
                        command_message,
                    ).await?
                } else if app_state.ui.show_register {
                    auth_ro::execute_action(
                        action,
                        app_state,
                        register_state,
                        ideal_cursor_column,
                        key_sequence_tracker,
                        command_message,
                    ).await?
                } else if app_state.ui.show_login {
                    auth_ro::execute_action(
                        action,
                        app_state,
                        login_state,
                        ideal_cursor_column,
                        key_sequence_tracker,
                        command_message,
                    )
                    .await?
                } else {
                    form_ro::execute_action(
                        action,
                        form_state,
                        ideal_cursor_column,
                        key_sequence_tracker,
                        command_message,
                    )
                    .await?
                };
                key_sequence_tracker.reset();
                return Ok((false, result));
            }
        }
        key_sequence_tracker.reset();
    } else {
        key_sequence_tracker.reset();

        if let Some(action) = config.get_read_only_action_for_key(key.code, key.modifiers).as_deref() {
            let result = if app_state.ui.show_form && CONTEXT_ACTIONS_FORM.contains(&action) {
                crate::tui::functions::form::handle_action(
                    action,
                    form_state,
                    grpc_client,
                    ideal_cursor_column,
                )
                .await?
            } else if app_state.ui.show_login && CONTEXT_ACTIONS_LOGIN.contains(&action) {
                crate::tui::functions::login::handle_action(action).await?
            } else if app_state.ui.show_add_table {
                add_table_ro::execute_action(
                    action,
                    app_state,
                    add_table_state,
                    ideal_cursor_column,
                    key_sequence_tracker,
                    command_message,
                ).await?
            } else if app_state.ui.show_add_logic {
                add_logic_ro::execute_action(
                    action,
                    app_state,
                    add_logic_state,
                    ideal_cursor_column,
                    key_sequence_tracker,
                    command_message,
                ).await?
            } else if app_state.ui.show_register {
                auth_ro::execute_action(
                    action,
                    app_state,
                    register_state,
                    ideal_cursor_column,
                    key_sequence_tracker,
                    command_message,
                ).await?
            } else if app_state.ui.show_login {
                auth_ro::execute_action(
                    action,
                    app_state,
                    login_state,
                    ideal_cursor_column,
                    key_sequence_tracker,
                    command_message,
                )
                .await?
            } else {
                form_ro::execute_action(
                    action,
                    form_state,
                    ideal_cursor_column,
                    key_sequence_tracker,
                    command_message,
                )
                .await?
            };
            return Ok((false, result));
        }
    }

    if !*edit_mode_cooldown {
        let default_key = "i".to_string();
        let edit_key = config
            .keybindings
            .read_only
            .get("enter_edit_mode_before")
            .and_then(|keys| keys.first())
            .map(|k| k.to_string())
            .unwrap_or(default_key);
        *command_message = format!("Read-only mode - press {} to edit", edit_key);
    }

    *edit_mode_cooldown = false;

    Ok((false, command_message.clone()))
}
