// src/modes/general/navigation.rs

use crossterm::event::KeyEvent;
use crate::config::binds::config::Config;
use crate::state::app::state::AppState;
use crate::pages::routing::{Router, Page};
use crate::pages::forms::FormState;
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::DataProvider;
use anyhow::Result;

pub async fn handle_navigation_event(
    key: KeyEvent,
    config: &Config,
    app_state: &mut AppState,
    router: &mut Router,
    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 {
            "up" => {
                up(app_state, router);
                return Ok(EventOutcome::Ok(String::new()));
            }
            "down" => {
                down(app_state, router);
                return Ok(EventOutcome::Ok(String::new()));
            }
            "next_option" => {
                next_option(app_state, router);
                return Ok(EventOutcome::Ok(String::new()));
            }
            "previous_option" => {
                previous_option(app_state, router);
                return Ok(EventOutcome::Ok(String::new()));
            }
            "next_field" => {
                if let Page::Form(path) = &router.current {
                    if let Some(fs) = app_state.form_state_for_path(path) {
                        next_field(fs);
                    }
                }
                return Ok(EventOutcome::Ok(String::new()));
            }
            "prev_field" => {
                if let Page::Form(path) = &router.current {
                    if let Some(fs) = app_state.form_state_for_path(path) {
                        prev_field(fs);
                    }
                }
                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) = match &router.current {
                    Page::Intro(state) => (UiContext::Intro, state.selected_option),
                    Page::Login(_) if app_state.ui.focus_outside_canvas => {
                        (UiContext::Login, app_state.focused_button_index)
                    }
                    Page::Register(_) if app_state.ui.focus_outside_canvas => {
                        (UiContext::Register, app_state.focused_button_index)
                    }
                    Page::Admin(state) => {
                        (UiContext::Admin, state.get_selected_index().unwrap_or(0))
                    }
                    _ if app_state.ui.dialog.dialog_show => {
                        (UiContext::Dialog, app_state.ui.dialog.dialog_active_button_index)
                    }
                    _ => return Ok(EventOutcome::Ok("Select (No Action)".to_string())),
                };
                return Ok(EventOutcome::ButtonSelected { context, index });
            }
            _ => {}
        }
    }
    Ok(EventOutcome::Ok(String::new()))
}

pub fn up(app_state: &mut AppState, router: &mut Router) {
    match &mut router.current {
        Page::Login(page) if app_state.ui.focus_outside_canvas => {
            if app_state.focused_button_index == 0 {
                app_state.ui.focus_outside_canvas = false;
                let last_field_index = page.state.field_count().saturating_sub(1);
                page.state.set_current_field(last_field_index);
            } else {
                app_state.focused_button_index =
                    app_state.focused_button_index.saturating_sub(1);
            }
        }
        Page::Register(state) if app_state.ui.focus_outside_canvas => {
            if app_state.focused_button_index == 0 {
                app_state.ui.focus_outside_canvas = false;
                let last_field_index = state.state.field_count().saturating_sub(1);
                state.set_current_field(last_field_index);
            } else {
                app_state.focused_button_index =
                    app_state.focused_button_index.saturating_sub(1);
            }
        }
        Page::Intro(state) => state.previous_option(),
        Page::Admin(state) => state.previous(),
        _ => {}
    }
}

pub fn down(app_state: &mut AppState, router: &mut Router) {
    match &mut router.current {
        Page::Login(_) | Page::Register(_) if app_state.ui.focus_outside_canvas => {
            let num_general_elements = 2;
            if app_state.focused_button_index < num_general_elements - 1 {
                app_state.focused_button_index += 1;
            }
        }
        Page::Intro(state) => state.next_option(),
        Page::Admin(state) => state.next(),
        _ => {}
    }
}

pub fn next_option(app_state: &mut AppState, router: &mut Router) {
    match &mut router.current {
        Page::Intro(state) => state.next_option(),
        Page::Admin(_) => {
            let option_count = app_state.profile_tree.profiles.len();
            if option_count > 0 {
                app_state.focused_button_index =
                    (app_state.focused_button_index + 1) % option_count;
            }
        }
        _ => {}
    }
}

pub fn previous_option(app_state: &mut AppState, router: &mut Router) {
    match &mut router.current {
        Page::Intro(state) => state.previous_option(),
        Page::Admin(_) => {
            let option_count = app_state.profile_tree.profiles.len();
            if option_count > 0 {
                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();
}
