// src/modes/general/navigation.rs

use crossterm::event::KeyEvent;
use crate::config::binds::config::Config;
use crate::state::app::state::AppState;
use crate::state::pages::form::FormState;
use crate::state::pages::auth::LoginState;
use crate::state::pages::auth::RegisterState;
use crate::state::pages::intro::IntroState;
use crate::state::pages::admin::AdminState;
use crate::ui::handlers::context::UiContext;
use crate::modes::handlers::event::EventOutcome;
use crate::modes::general::command_navigation::{handle_command_navigation_event, NavigationState};
use canvas::canvas::CanvasState;
use anyhow::Result;

pub async fn handle_navigation_event(
    key: KeyEvent,
    config: &Config,
    form_state: &mut FormState,
    app_state: &mut AppState,
    login_state: &mut LoginState,
    register_state: &mut RegisterState,
    intro_state: &mut IntroState,
    admin_state: &mut AdminState,
    command_mode: &mut bool,
    command_input: &mut String,
    command_message: &mut String,
    navigation_state: &mut NavigationState,
) -> Result<EventOutcome> {
    // Handle command navigation first if active
    if navigation_state.active {
        return handle_command_navigation_event(navigation_state, key, config).await;
    }

    if let Some(action) = config.get_general_action(key.code, key.modifiers) {
        match action {
            "move_up" => {
                move_up(app_state, login_state, register_state, intro_state, admin_state);
                return Ok(EventOutcome::Ok(String::new()));
            }
            "move_down" => {
                move_down(app_state, intro_state, admin_state);
                return Ok(EventOutcome::Ok(String::new()));
            }
            "next_option" => {
                next_option(app_state, intro_state);
                return Ok(EventOutcome::Ok(String::new()));
            }
            "previous_option" => {
                previous_option(app_state, intro_state);
                return Ok(EventOutcome::Ok(String::new()));
            }
            "next_field" => {
                next_field(form_state);
                return Ok(EventOutcome::Ok(String::new()));
            }
            "prev_field" => {
                prev_field(form_state);
                return Ok(EventOutcome::Ok(String::new()));
            }
            "enter_command_mode" => {
                handle_enter_command_mode(command_mode, command_input, command_message);
                return Ok(EventOutcome::Ok(String::new()));
            }
            "select" => {
                let (context, index) = if app_state.ui.show_intro {
                    (UiContext::Intro, intro_state.selected_option)
                } else if app_state.ui.show_login && app_state.ui.focus_outside_canvas {
                    (UiContext::Login, app_state.focused_button_index)
                } else if app_state.ui.show_register && app_state.ui.focus_outside_canvas {
                    (UiContext::Register, app_state.focused_button_index)
                } else if app_state.ui.show_admin {
                    (UiContext::Admin, admin_state.get_selected_index().unwrap_or(0))
                } else if app_state.ui.dialog.dialog_show {
                     (UiContext::Dialog, app_state.ui.dialog.dialog_active_button_index)
                } else {
                    return Ok(EventOutcome::Ok("Select (No Action)".to_string()));
                };
                return Ok(EventOutcome::ButtonSelected { context, index });
            }
            _ => {}
        }
    }
    Ok(EventOutcome::Ok(String::new()))
}

pub fn move_up(app_state: &mut AppState, login_state: &mut LoginState, register_state: &mut RegisterState, intro_state: &mut IntroState, admin_state: &mut AdminState) {
    if app_state.ui.focus_outside_canvas && app_state.ui.show_login || app_state.ui.show_register{
        if app_state.focused_button_index == 0 {
            app_state.ui.focus_outside_canvas = false;
            if app_state.ui.show_login {
                let last_field_index = login_state.fields().len().saturating_sub(1);
                login_state.set_current_field(last_field_index);
            } else {
                let last_field_index = register_state.fields().len().saturating_sub(1);
                register_state.set_current_field(last_field_index);
            }
        } else {
            app_state.focused_button_index = app_state.focused_button_index.saturating_sub(1);
        }
    } else if app_state.ui.show_intro {
        intro_state.previous_option();
    } else if app_state.ui.show_admin {
        admin_state.previous();
    }
}

pub fn move_down(app_state: &mut AppState, intro_state: &mut IntroState, admin_state: &mut AdminState) {
    if app_state.ui.focus_outside_canvas && app_state.ui.show_login || app_state.ui.show_register {
        let num_general_elements = 2;
        if app_state.focused_button_index < num_general_elements - 1 {
            app_state.focused_button_index += 1;
        }
    } else if app_state.ui.show_intro {
        intro_state.next_option();
    } else if app_state.ui.show_admin {
        admin_state.next();
    }
}

pub fn next_option(app_state: &mut AppState, intro_state: &mut IntroState) { 
    if app_state.ui.show_intro {
        intro_state.next_option();
    } else {
        // Get option count from state instead of parameter
        let option_count = app_state.profile_tree.profiles.len();
        app_state.focused_button_index = (app_state.focused_button_index + 1) % option_count;
    }
}

pub fn previous_option(app_state: &mut AppState, intro_state: &mut IntroState) {
    if app_state.ui.show_intro {
        intro_state.previous_option();
    } else {
        let option_count = app_state.profile_tree.profiles.len();
        app_state.focused_button_index = if app_state.focused_button_index == 0 {
            option_count.saturating_sub(1)
        } else {
            app_state.focused_button_index - 1
        };
    }
}

pub fn next_field(form_state: &mut FormState) {
    if !form_state.fields.is_empty() {
        form_state.current_field = (form_state.current_field + 1) % form_state.fields.len();
    }
}

pub fn prev_field(form_state: &mut FormState) {
    if !form_state.fields.is_empty() {
        if form_state.current_field == 0 {
            form_state.current_field = form_state.fields.len() - 1;
        } else {
            form_state.current_field -= 1;
        }
    }
}

pub fn handle_enter_command_mode(
    command_mode: &mut bool,
    command_input: &mut String,
    command_message: &mut String
) {
    *command_mode = true;
    command_input.clear();
    command_message.clear();
}
