// src/dialog/logic.rs

// TODO(dialog-refactor):
// Currently this module (`handle_dialog_event`) contains page-specific logic
// (e.g. Login, Register, Admin, SaveTable). This couples the dialog crate
// to application pages and business logic.
//
// Refactor plan:
// 1. Keep dialog generic: only handle navigation (next/prev/select) and return
//    a `DialogResult` (Dismissed | Selected { purpose, index }).
// 2. Move all page-specific actions (e.g. login::back_to_main, register::back_to_login,
//    handle_delete_selected_columns, buffer_state.update_history) into the
//    respective page or event handler (e.g. modes/handlers/event.rs).
// 3. Dialog crate should only provide state, rendering, and generic navigation.
//    Pages decide what to do when a dialog button is pressed.

use crossterm::event::{Event, KeyCode};
use crate::config::binds::config::Config;
use crate::ui::handlers::context::DialogPurpose;
use crate::state::app::state::AppState;
use crate::buffer::AppView;
use crate::buffer::state::BufferState;
use crate::modes::handlers::event::EventOutcome;
use crate::pages::register;
use crate::pages::login;
use crate::tui::functions::common::add_table::handle_delete_selected_columns;
use crate::pages::routing::{Router, Page};
use anyhow::Result;

/// Handles key events specifically when a dialog is active.
/// Returns Some(Result<EventOutcome, Error>) if the event was handled (consumed),
/// otherwise returns None.
pub async fn handle_dialog_event(
    event: &Event,
    config: &Config,
    app_state: &mut AppState,
    buffer_state: &mut BufferState,
    router: &mut Router,
) -> Option<Result<EventOutcome>> {
    if let Event::Key(key) = event {
        // Always allow Esc to dismiss
        if key.code == KeyCode::Esc {
            app_state.hide_dialog();
            return Some(Ok(EventOutcome::Ok("Dialog dismissed".to_string())));
        }

        // Check general bindings for dialog actions
        if let Some(action) = config.get_general_action(key.code, key.modifiers) {
            match action {
                "move_down" | "next_option" => {
                    let current_index = app_state.ui.dialog.dialog_active_button_index;
                    let num_buttons = app_state.ui.dialog.dialog_buttons.len();
                    if num_buttons > 0 && current_index < num_buttons - 1 {
                        app_state.ui.dialog.dialog_active_button_index += 1;
                    }
                    return Some(Ok(EventOutcome::Ok(String::new())));
                }
                "move_up" | "previous_option" => {
                    let current_index = app_state.ui.dialog.dialog_active_button_index;
                    if current_index > 0 {
                        app_state.ui.dialog.dialog_active_button_index -= 1;
                    }
                    return Some(Ok(EventOutcome::Ok(String::new())));
                }
                "select" => {
                    let selected_index = app_state.ui.dialog.dialog_active_button_index;
                    let purpose = match app_state.ui.dialog.purpose {
                        Some(p) => p,
                        None => {
                            app_state.hide_dialog();
                            return Some(Ok(EventOutcome::Ok(
                                "Internal Error: Dialog context lost".to_string(),
                            )));
                        }
                    };

                    // Handle Dialog Actions Directly Here
                    match purpose {
                        DialogPurpose::LoginSuccess => match selected_index {
                            0 => {
                                // "Menu" button selected
                                app_state.hide_dialog();
                                if let Page::Login(state) = &mut router.current {
                                    let message =
                                        login::back_to_main(state, app_state, buffer_state).await;
                                    return Some(Ok(EventOutcome::Ok(message)));
                                }
                                return Some(Ok(EventOutcome::Ok(
                                    "Login state not active".to_string(),
                                )));
                            }
                            1 => {
                                app_state.hide_dialog();
                                return Some(Ok(EventOutcome::Ok("Exiting dialog".to_string())));
                            }
                            _ => {
                                app_state.hide_dialog();
                                return Some(Ok(EventOutcome::Ok(
                                    "Unknown dialog button selected".to_string(),
                                )));
                            }
                        },
                        DialogPurpose::LoginFailed => match selected_index {
                            0 => {
                                // "OK" button selected
                                app_state.hide_dialog();
                                return Some(Ok(EventOutcome::Ok(
                                    "Login failed dialog dismissed".to_string(),
                                )));
                            }
                            _ => {
                                app_state.hide_dialog();
                                return Some(Ok(EventOutcome::Ok(
                                    "Unknown dialog button selected".to_string(),
                                )));
                            }
                        },
                        DialogPurpose::RegisterSuccess => match selected_index {
                            0 => {
                                // "OK" button for RegisterSuccess
                                app_state.hide_dialog();
                                if let Page::Register(state) = &mut router.current {
                                    let message =
                                        register::back_to_login(state, app_state, buffer_state)
                                            .await;
                                    return Some(Ok(EventOutcome::Ok(message)));
                                }
                                return Some(Ok(EventOutcome::Ok(
                                    "Register state not active".to_string(),
                                )));
                            }
                            _ => {
                                app_state.hide_dialog();
                                return Some(Ok(EventOutcome::Ok(
                                    "Unknown dialog button selected".to_string(),
                                )));
                            }
                        },
                        DialogPurpose::RegisterFailed => match selected_index {
                            0 => {
                                // "OK" button for RegisterFailed
                                app_state.hide_dialog(); // Just dismiss
                                return Some(Ok(EventOutcome::Ok(
                                    "Register failed dialog dismissed".to_string(),
                                )));
                            }
                            _ => {
                                app_state.hide_dialog();
                                return Some(Ok(EventOutcome::Ok(
                                    "Unknown dialog button selected".to_string(),
                                )));
                            }
                        },
                        DialogPurpose::ConfirmDeleteColumns => match selected_index {
                            0 => {
                                // "Confirm" button selected
                                if let Page::Admin(state) = &mut router.current {
                                    let outcome_message =
                                        handle_delete_selected_columns(&mut state.add_table_state);
                                    app_state.hide_dialog();
                                    return Some(Ok(EventOutcome::Ok(outcome_message)));
                                }
                                return Some(Ok(EventOutcome::Ok(
                                    "Admin state not active".to_string(),
                                )));
                            }
                            1 => {
                                // "Cancel" button selected
                                app_state.hide_dialog();
                                return Some(Ok(EventOutcome::Ok("Deletion cancelled.".to_string())));
                            }
                            _ => { /* Handle unexpected index */ }
                        },
                        DialogPurpose::SaveTableSuccess => match selected_index {
                            0 => {
                                // "OK" button selected
                                app_state.hide_dialog();
                                buffer_state.update_history(AppView::Admin); // Navigate back
                                return Some(Ok(EventOutcome::Ok(
                                    "Save success dialog dismissed.".to_string(),
                                )));
                            }
                            _ => { /* Handle unexpected index */ }
                        },
                        DialogPurpose::SaveLogicSuccess => match selected_index {
                            0 => {
                                // "OK" button selected
                                app_state.hide_dialog();
                                buffer_state.update_history(AppView::Admin);
                                return Some(Ok(EventOutcome::Ok(
                                    "Save success dialog dismissed.".to_string(),
                                )));
                            }
                            _ => { /* Handle unexpected index */ }
                        },
                    }
                }
                _ => {} // Ignore other general actions when dialog is shown
            }
        }
        // If it was a key event but not handled above, consume it
        Some(Ok(EventOutcome::Ok(String::new())))
    } else {
        // If it wasn't a key event, consume it too while dialog is active
        Some(Ok(EventOutcome::Ok(String::new())))
    }
}
