//! Input event handling for the TUI

use anyhow::Result;
use crossterm::event::{self, Event, KeyCode, KeyModifiers, KeyEvent};
use std::time::Duration;

use crate::app::{App, Focus, PageTemplate, GenerationState};
use crate::generation::generate_page;

/// Handle keyboard input events
pub fn handle_events(app: &mut App) -> Result<()> {
    if event::poll(Duration::from_millis(50))? {
        if let Event::Key(key) = event::read()? {
            match key.code {
                KeyCode::Char('q') | KeyCode::Char('Q') if key.modifiers.contains(KeyModifiers::CONTROL) => {
                    app.quit();
                }
                KeyCode::Esc => {
                    if app.show_help {
                        app.toggle_help();
                    } else if app.chat_focused {
                        app.chat_focused = false; // Exit chat without submitting
                        app.chat_input.clear();
                    } else {
                        handle_escape(app);
                    }
                }
                KeyCode::Char('?') => {
                    app.toggle_help();
                }
                KeyCode::Tab => {
                    if !app.show_help {
                        // Only allow tab navigation in normal form state
                        if matches!(app.generation_state, crate::app::GenerationState::Form) {
                            if key.modifiers.contains(KeyModifiers::SHIFT) {
                                app.previous_focus();
                            } else {
                                app.next_focus();
                            }
                        }
                    }
                }
                KeyCode::Enter => {
                    if !app.show_help {
                        if app.chat_focused {
                            let _input = app.submit_chat();
                            app.chat_focused = false; // Exit chat after submitting
                        } else {
                            handle_enter(app);
                        }
                    }
                }
                KeyCode::Char(' ') => {
                    if !app.show_help {
                        handle_space(app);
                    }
                }
                KeyCode::Up => {
                    if !app.show_help {
                        handle_up(app);
                    }
                }
                KeyCode::Down => {
                    if !app.show_help {
                        handle_down(app);
                    }
                }
                KeyCode::Left => {
                    if !app.show_help && app.focus == Focus::Preview {
                        app.previous_preview_tab();
                    }
                }
                KeyCode::Right => {
                    if !app.show_help && app.focus == Focus::Preview {
                        app.next_preview_tab();
                    }
                }
                KeyCode::BackTab => {
                    // Alternative for Shift+Tab in terminals that support BackTab
                    if !app.show_help && matches!(app.generation_state, crate::app::GenerationState::Form) {
                        app.previous_focus();
                    }
                }
                KeyCode::Char('+') | KeyCode::Char('=') => {
                    if !app.show_help && app.focus == Focus::Priority {
                        app.update_priority(app.priority + 0.1);
                    }
                }
                KeyCode::Char('-') => {
                    if !app.show_help && app.focus == Focus::Priority {
                        app.update_priority(app.priority - 0.1);
                    }
                }
                KeyCode::Backspace => {
                    if !app.show_help {
                        if app.chat_focused {
                            app.chat_backspace();
                        } else {
                            handle_backspace(app);
                        }
                    }
                }
                KeyCode::Char('w') if key.modifiers.contains(KeyModifiers::CONTROL) => {
                    if !app.show_help {
                        handle_delete_word(app);
                    }
                }
                KeyCode::Char('u') if key.modifiers.contains(KeyModifiers::CONTROL) => {
                    if !app.show_help {
                        handle_clear_field(app);
                    }
                }
                KeyCode::Char(c) => {
                    if !app.show_help && !key.modifiers.contains(KeyModifiers::CONTROL) {
                        if app.chat_focused {
                            app.chat_input_char(c);
                        } else if c == '/' || c == ':' {
                            // Quick way to start typing in chat (/ or :)
                            app.toggle_chat_focus();
                        } else {
                            handle_char_input(app, c);
                        }
                    }
                }
                _ => {}
            }
        }
    }
    Ok(())
}

/// Handle Enter key press
fn handle_enter(app: &mut App) {
    match app.focus {
        Focus::Template => {
            // Cycle through templates
            let templates = PageTemplate::all();
            let current_index = templates.iter().position(|&t| t == app.selected_template).unwrap_or(0);
            let next_index = (current_index + 1) % templates.len();
            app.set_template(templates[next_index]);
        }
        Focus::Languages => {
            // Toggle currently highlighted language
            app.toggle_current_language();
        }
        Focus::AutoScaffold => {
            app.toggle_auto_scaffold();
        }
        Focus::ReplaceExisting => {
            app.toggle_replace_existing();
        }
        Focus::GenerateButton => {
            if app.is_valid() {
                // Start confirmation dialog
                app.start_generation_confirmation();
            }
        }
        Focus::ConfirmGenerate => {
            // User confirmed generation in dialog
            handle_page_generation(app);
        }
        Focus::GenerationProgress => {
            // Do nothing - generation in progress
        }
        Focus::GenerationResults => {
            // Handle result actions (Open Files, New Page, Exit, etc.)
            handle_result_actions(app);
        }
        Focus::PreviewButton => {
            // Jump to preview pane for live preview
            if app.is_valid() {
                app.focus = Focus::Preview;
            }
        }
        Focus::CancelButton => {
            app.quit();
        }
        _ => {}
    }
}

/// Handle Space key press
fn handle_space(app: &mut App) {
    match app.focus {
        Focus::Template => {
            // Same as Enter for template selection
            handle_enter(app);
        }
        Focus::Languages => {
            // Toggle currently highlighted language
            app.toggle_current_language();
        }
        Focus::AutoScaffold => {
            app.toggle_auto_scaffold();
        }
        Focus::ReplaceExisting => {
            app.toggle_replace_existing();
        }
        Focus::Preview => {
            // When in preview pane, Space switches back to configuration pane
            app.focus = Focus::PageName; // Return to first form field
        }
        _ => {
            // For all other focuses (configuration form fields), Space switches to preview pane
            if is_configuration_focus(app.focus) {
                app.focus = Focus::Preview;
            }
        }
    }
}

/// Check if the current focus is part of the configuration form (not preview or buttons)
fn is_configuration_focus(focus: Focus) -> bool {
    matches!(focus,
        Focus::LanguageSelector |
        Focus::PageName |
        Focus::Template |
        Focus::Languages |
        Focus::RoutePath |
        Focus::Priority |
        Focus::AutoScaffold |
        Focus::ReplaceExisting
    )
}

/// Handle Up arrow key
fn handle_up(app: &mut App) {
    match app.focus {
        Focus::LanguageSelector => {
            app.previous_language_selection();
        }
        Focus::Template => {
            let templates = PageTemplate::all();
            let current_index = templates.iter().position(|&t| t == app.selected_template).unwrap_or(0);
            let prev_index = if current_index == 0 { templates.len() - 1 } else { current_index - 1 };
            app.set_template(templates[prev_index]);
        }
        Focus::Languages => {
            app.previous_language();
        }
        Focus::Priority => {
            app.update_priority(app.priority + 0.1);
        }
        _ => {}
    }
}

/// Handle Down arrow key
fn handle_down(app: &mut App) {
    match app.focus {
        Focus::LanguageSelector => {
            app.next_language_selection();
        }
        Focus::Template => {
            let templates = PageTemplate::all();
            let current_index = templates.iter().position(|&t| t == app.selected_template).unwrap_or(0);
            let next_index = (current_index + 1) % templates.len();
            app.set_template(templates[next_index]);
        }
        Focus::Languages => {
            app.next_language();
        }
        Focus::Priority => {
            app.update_priority(app.priority - 0.1);
        }
        _ => {}
    }
}

/// Handle backspace key
fn handle_backspace(app: &mut App) {
    match app.focus {
        Focus::PageName => {
            let mut name = app.page_name.clone();
            name.pop();
            app.update_page_name(name);
        }
        Focus::RoutePath => {
            let mut path = app.route_path.clone();
            path.pop();
            app.update_route_path(path);
        }
        _ => {}
    }
}

/// Handle Ctrl+W (delete word)
fn handle_delete_word(app: &mut App) {
    match app.focus {
        Focus::PageName => {
            let name = app.page_name.clone();
            let new_name = delete_last_word(&name);
            app.update_page_name(new_name);
        }
        Focus::RoutePath => {
            let path = app.route_path.clone();
            let new_path = delete_last_word(&path);
            app.update_route_path(new_path);
        }
        _ => {}
    }
}

/// Handle Ctrl+U (clear field)
fn handle_clear_field(app: &mut App) {
    match app.focus {
        Focus::PageName => {
            app.update_page_name(String::new());
        }
        Focus::RoutePath => {
            app.update_route_path(String::new());
        }
        _ => {}
    }
}

/// Handle character input
fn handle_char_input(app: &mut App, c: char) {
    match app.focus {
        Focus::PageName => {
            // Only allow alphanumeric characters for page names
            if c.is_alphanumeric() {
                let mut name = app.page_name.clone();
                name.push(c);
                app.update_page_name(name);
            }
        }
        Focus::RoutePath => {
            // Allow path characters
            if c.is_ascii() && (c.is_alphanumeric() || "/-._%".contains(c)) {
                let mut path = app.route_path.clone();
                path.push(c);
                app.update_route_path(path);
            }
        }
        Focus::Priority => {
            // Handle numeric input for priority
            if c.is_ascii_digit() || c == '.' {
                let current_str = format!("{:.1}", app.priority);
                let mut new_str = current_str;
                new_str.push(c);

                if let Ok(new_priority) = new_str.parse::<f32>() {
                    app.update_priority(new_priority);
                }
            }
        }
        _ => {}
    }
}

/// Delete the last word from a string
fn delete_last_word(s: &str) -> String {
    let trimmed = s.trim_end();
    if let Some(last_space) = trimmed.rfind(' ') {
        trimmed[..=last_space].trim_end().to_string()
    } else {
        String::new()
    }
}

/// Handle escape key based on current state
fn handle_escape(app: &mut App) {
    match &app.generation_state {
        GenerationState::Form => {
            app.quit();
        }
        GenerationState::ConfirmDialog => {
            app.cancel_generation();
        }
        GenerationState::InProgress { .. } => {
            // Can't cancel during generation
        }
        GenerationState::Success { .. } | GenerationState::Error { .. } => {
            app.quit();
        }
    }
}

/// Handle result actions (Open Files, New Page, Exit)
fn handle_result_actions(app: &mut App) {
    match &app.generation_state {
        GenerationState::Success { .. } => {
            // For now, just quit - we could add file opening functionality here
            app.quit();
        }
        GenerationState::Error { .. } => {
            // Return to form for retry
            app.cancel_generation();
        }
        _ => {}
    }
}

/// Handle page generation with progress updates
fn handle_page_generation(app: &mut App) {
    let start_time = std::time::Instant::now();

    // Start progress tracking
    let total_steps = if app.auto_scaffold { 3 } else { 2 }; // Route + Translations + (optionally) Components
    app.start_generation(total_steps);

    // Simulate some progress updates (in real implementation, this would be called from generation functions)
    app.update_generation_progress("Validating configuration...".to_string(), None);

    // Perform actual generation
    match generate_page(app) {
        Ok(result) => {
            let duration = start_time.elapsed();
            if result.success {
                app.complete_generation(result.files_created, result.files_updated, duration);
            } else {
                let error_msg = result.error.unwrap_or_else(|| "Unknown error".to_string());
                app.fail_generation(error_msg, result.files_created); // files_created represents rolled back files
            }
        }
        Err(e) => {
            let _duration = start_time.elapsed();
            app.fail_generation(e.to_string(), Vec::new());
        }
    }
}

// Note: Generation feedback is now handled via the TUI dialogs instead of terminal output

/// Handle a single key event (for dashboard integration)
pub fn handle_key_event(app: &mut App, key: KeyEvent) -> Result<()> {
    match key.code {
        KeyCode::Char('q') | KeyCode::Char('Q') if key.modifiers.contains(KeyModifiers::CONTROL) => {
            app.quit();
        }
        KeyCode::Esc => {
            if app.show_help {
                app.toggle_help();
            } else if app.chat_focused {
                app.chat_focused = false; // Exit chat without submitting
                app.chat_input.clear();
            } else {
                handle_escape(app);
            }
        }
        KeyCode::Char('?') => {
            app.toggle_help();
        }
        KeyCode::Tab => {
            if !app.show_help {
                // Only allow tab navigation in normal form state
                if matches!(app.generation_state, crate::app::GenerationState::Form) {
                    if key.modifiers.contains(KeyModifiers::SHIFT) {
                        app.previous_focus();
                    } else {
                        app.next_focus();
                    }
                }
            }
        }
        KeyCode::BackTab => {
            // Alternative for Shift+Tab in terminals that support BackTab
            if !app.show_help && matches!(app.generation_state, crate::app::GenerationState::Form) {
                app.previous_focus();
            }
        }
        KeyCode::Enter => {
            if !app.show_help {
                if app.chat_focused {
                    let _input = app.submit_chat();
                    app.chat_focused = false; // Exit chat after submitting
                } else {
                    handle_enter(app);
                }
            }
        }
        KeyCode::Char(' ') => {
            if !app.show_help {
                handle_space(app);
            }
        }
        KeyCode::Up => {
            if !app.show_help {
                handle_up(app);
            }
        }
        KeyCode::Down => {
            if !app.show_help {
                handle_down(app);
            }
        }
        KeyCode::Left => {
            if !app.show_help && app.focus == Focus::Preview {
                app.previous_preview_tab();
            }
        }
        KeyCode::Right => {
            if !app.show_help && app.focus == Focus::Preview {
                app.next_preview_tab();
            }
        }
        KeyCode::Backspace => {
            if !app.show_help {
                if app.chat_focused {
                    app.chat_backspace();
                } else {
                    handle_backspace(app);
                }
            }
        }
        KeyCode::Delete => {
            if !app.show_help {
                handle_delete_word(app);
            }
        }
        KeyCode::Char(c) => {
            if !app.show_help {
                if app.chat_focused {
                    app.chat_input_char(c);
                } else if c == '/' || c == ':' {
                    // Quick way to start typing in chat (/ or :)
                    app.toggle_chat_focus();
                } else {
                    // Handle special characters for priority adjustment
                    match c {
                        '+' | '=' => {
                            if app.focus == Focus::Priority {
                                app.update_priority(app.priority + 0.1);
                            } else {
                                handle_char_input(app, c);
                            }
                        }
                        '-' => {
                            if app.focus == Focus::Priority {
                                app.update_priority(app.priority - 0.1);
                            } else {
                                handle_char_input(app, c);
                            }
                        }
                        ' ' => {
                            // Space is handled above in KeyCode::Char(' '), skip here to avoid double handling
                        }
                        _ => {
                            handle_char_input(app, c);
                        }
                    }
                }
            }
        }
        _ => {}
    }
    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_delete_last_word() {
        assert_eq!(delete_last_word("hello world"), "hello");
        assert_eq!(delete_last_word("hello"), "");
        assert_eq!(delete_last_word("hello world test"), "hello world");
        assert_eq!(delete_last_word(""), "");
        assert_eq!(delete_last_word("   hello   world   "), "hello");
    }
}
