//! Init Wizard TUI with ratatui
//!
//! Provides a 2-column interface for project initialization:
//! - Left: Current step (interactive user input)
//! - Right: Split into 2 rows:
//!   - Top: Current selections
//!   - Bottom: Robot visualization

use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
use ratatui::{
    layout::{Constraint, Direction, Layout},
    style::{Color, Modifier, Style},
    text::{Line, Span},
    widgets::{Block, Borders, List, ListItem, ListState, Paragraph, Wrap},
    Frame,
};

/// Wizard step
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum WizardStep {
    ProjectName,
    RobotType,
    NodeSelection,
    Confirmation,
}

impl WizardStep {
    fn next(&self) -> Option<WizardStep> {
        match self {
            WizardStep::ProjectName => Some(WizardStep::RobotType),
            WizardStep::RobotType => Some(WizardStep::NodeSelection),
            WizardStep::NodeSelection => Some(WizardStep::Confirmation),
            WizardStep::Confirmation => None,
        }
    }

    fn prev(&self) -> Option<WizardStep> {
        match self {
            WizardStep::ProjectName => None,
            WizardStep::RobotType => Some(WizardStep::ProjectName),
            WizardStep::NodeSelection => Some(WizardStep::RobotType),
            WizardStep::Confirmation => Some(WizardStep::NodeSelection),
        }
    }
}

/// Robot template option
#[derive(Debug, Clone)]
pub struct TemplateOption {
    pub id: String,
    pub name: String,
    pub description: String,
}

/// Node option
#[derive(Debug, Clone)]
pub struct NodeOption {
    pub id: String,
    pub name: String,
    pub description: String,
}

/// Wizard state
pub struct InitWizardState {
    pub project_name: String,
    pub selected_template: Option<usize>,
    pub selected_nodes: Vec<bool>,
    pub templates: Vec<TemplateOption>,
    pub nodes: Vec<NodeOption>,
}

impl InitWizardState {
    pub fn new(templates: Vec<TemplateOption>, nodes: Vec<NodeOption>, defaults: Vec<bool>) -> Self {
        Self {
            project_name: String::new(),
            selected_template: None,
            selected_nodes: defaults,
            templates,
            nodes,
        }
    }

    /// Get selected template
    pub fn get_template(&self) -> Option<&TemplateOption> {
        self.selected_template.and_then(|idx| self.templates.get(idx))
    }

    /// Get selected nodes
    pub fn get_selected_nodes(&self) -> Vec<&NodeOption> {
        self.selected_nodes
            .iter()
            .enumerate()
            .filter_map(|(idx, &selected)| if selected { self.nodes.get(idx) } else { None })
            .collect()
    }

    /// Count selected nodes
    pub fn selected_node_count(&self) -> usize {
        self.selected_nodes.iter().filter(|&&s| s).count()
    }
}

/// TUI for init wizard
pub struct InitWizardTui {
    current_step: WizardStep,
    state: InitWizardState,
    // UI state
    selected_index: usize,
    should_quit: bool,
    confirmed: bool,
}

impl InitWizardTui {
    /// Create a new init wizard TUI
    pub fn new(state: InitWizardState) -> Self {
        Self {
            current_step: WizardStep::ProjectName,
            state,
            selected_index: 0,
            should_quit: false,
            confirmed: false,
        }
    }

    /// Check if should quit
    pub fn should_quit(&self) -> bool {
        self.should_quit
    }

    /// Check if confirmed
    pub fn is_confirmed(&self) -> bool {
        self.confirmed
    }

    /// Get final state
    pub fn into_state(self) -> InitWizardState {
        self.state
    }

    /// Draw the TUI (single frame)
    pub fn draw(&mut self, f: &mut Frame) {
        // Split terminal vertically: content area + footer
        let vertical_chunks = Layout::default()
            .direction(Direction::Vertical)
            .constraints([
                Constraint::Min(10),   // Main content area
                Constraint::Length(3), // Footer
            ])
            .split(f.area());

        // Split main content into 2 columns
        let horizontal_chunks = Layout::default()
            .direction(Direction::Horizontal)
            .constraints([
                Constraint::Percentage(50), // Left: Current step (user input)
                Constraint::Percentage(50), // Right: Selections + Robot visualization
            ])
            .split(vertical_chunks[0]);

        // Split right column into 2 rows
        let right_vertical_chunks = Layout::default()
            .direction(Direction::Vertical)
            .constraints([
                Constraint::Percentage(40), // Top: Selections
                Constraint::Percentage(60), // Bottom: Robot visualization
            ])
            .split(horizontal_chunks[1]);

        // Draw panels
        self.draw_current_step(f, horizontal_chunks[0]);
        self.draw_selections(f, right_vertical_chunks[0]);
        self.draw_robot_visualization(f, right_vertical_chunks[1]);
        self.draw_footer(f, vertical_chunks[1]);
    }

    /// Draw selections panel
    fn draw_selections(&self, f: &mut Frame, area: ratatui::layout::Rect) {
        let mut text = vec![
            Line::from(vec![Span::styled(
                "📋 YOUR SELECTIONS",
                Style::default().fg(Color::Cyan).add_modifier(Modifier::BOLD),
            )]),
            Line::from(""),
        ];

        // Project name
        let name_text = if self.state.project_name.is_empty() {
            Span::styled("<not set>", Style::default().fg(Color::DarkGray))
        } else {
            Span::styled(&self.state.project_name, Style::default().fg(Color::Green))
        };
        text.push(Line::from(vec![
            Span::styled("Project: ", Style::default().add_modifier(Modifier::BOLD)),
            name_text,
        ]));

        // Template
        let template_text = if let Some(template) = self.state.get_template() {
            Span::styled(&template.name, Style::default().fg(Color::Green))
        } else {
            Span::styled("<not selected>", Style::default().fg(Color::DarkGray))
        };
        text.push(Line::from(vec![
            Span::styled("Robot Type: ", Style::default().add_modifier(Modifier::BOLD)),
            template_text,
        ]));

        // Nodes count (only show when user reaches node selection step or later)
        if matches!(self.current_step, WizardStep::NodeSelection | WizardStep::Confirmation) {
            let node_count = self.state.selected_node_count();
            text.push(Line::from(vec![
                Span::styled("Nodes: ", Style::default().add_modifier(Modifier::BOLD)),
                Span::styled(
                    format!("{} selected", node_count),
                    if node_count > 0 {
                        Style::default().fg(Color::Green)
                    } else {
                        Style::default().fg(Color::DarkGray)
                    },
                ),
            ]));
        }

        let paragraph = Paragraph::new(text)
            .block(
                Block::default()
                    .borders(Borders::ALL)
                    .title(" Your Selections ")
                    .border_style(Style::default().fg(Color::Cyan)),
            )
            .wrap(Wrap { trim: true });

        f.render_widget(paragraph, area);
    }

    /// Draw current step panel
    fn draw_current_step(&mut self, f: &mut Frame, area: ratatui::layout::Rect) {
        match self.current_step {
            WizardStep::ProjectName => self.draw_project_name_step(f, area),
            WizardStep::RobotType => self.draw_robot_type_step(f, area),
            WizardStep::NodeSelection => self.draw_node_selection_step(f, area),
            WizardStep::Confirmation => self.draw_confirmation_step(f, area),
        }
    }

    /// Draw project name step
    fn draw_project_name_step(&self, f: &mut Frame, area: ratatui::layout::Rect) {
        let text = vec![
            Line::from(vec![Span::styled(
                "📝 PROJECT NAME",
                Style::default().fg(Color::Cyan).add_modifier(Modifier::BOLD),
            )]),
            Line::from(""),
            Line::from("Enter a name for your robot project."),
            Line::from(""),
            Line::from(vec![
                Span::styled("Name: ", Style::default().add_modifier(Modifier::BOLD)),
                Span::styled(&self.state.project_name, Style::default().fg(Color::Yellow)),
                Span::styled("_", Style::default().fg(Color::Yellow)),
            ]),
            Line::from(""),
            Line::from(vec![Span::styled(
                "Tips:",
                Style::default().add_modifier(Modifier::BOLD),
            )]),
            Line::from("  • Use lowercase letters, numbers, hyphens"),
            Line::from("  • Example: my-robot, rover-bot"),
            Line::from(""),
            Line::from(vec![Span::styled(
                "Press Enter to continue →",
                Style::default().fg(Color::Green),
            )]),
        ];

        let paragraph = Paragraph::new(text)
            .block(
                Block::default()
                    .borders(Borders::ALL)
                    .title(" Step 1/4: Project Name ")
                    .border_style(Style::default().fg(Color::Yellow)),
            )
            .wrap(Wrap { trim: true });

        f.render_widget(paragraph, area);
    }

    /// Draw robot type step
    fn draw_robot_type_step(&mut self, f: &mut Frame, area: ratatui::layout::Rect) {
        let items: Vec<ListItem> = self
            .state
            .templates
            .iter()
            .enumerate()
            .map(|(idx, template)| {
                let is_selected = Some(idx) == self.state.selected_template;
                let is_highlighted = idx == self.selected_index;

                let (prefix, style) = if is_selected {
                    ("◉ ", Style::default().fg(Color::Green).add_modifier(Modifier::BOLD))
                } else if is_highlighted {
                    ("○ ", Style::default().fg(Color::Cyan).add_modifier(Modifier::BOLD))
                } else {
                    ("○ ", Style::default().fg(Color::White))
                };

                let content = vec![
                    Line::from(vec![Span::raw(prefix), Span::styled(&template.name, style)]),
                    Line::from(vec![
                        Span::raw("   "),
                        Span::styled(&template.description, Style::default().fg(Color::DarkGray)),
                    ]),
                ];

                ListItem::new(content)
            })
            .collect();

        let list = List::new(items).block(
            Block::default()
                .borders(Borders::ALL)
                .title(" Step 2/4: Robot Type ")
                .border_style(Style::default().fg(Color::Yellow)),
        );

        let mut state = ListState::default();
        state.select(Some(self.selected_index));

        f.render_stateful_widget(list, area, &mut state);
    }

    /// Draw node selection step
    fn draw_node_selection_step(&mut self, f: &mut Frame, area: ratatui::layout::Rect) {
        let items: Vec<ListItem> = self
            .state
            .nodes
            .iter()
            .enumerate()
            .map(|(idx, node)| {
                let is_selected = self.state.selected_nodes.get(idx).copied().unwrap_or(false);
                let is_highlighted = idx == self.selected_index;

                let checkbox = if is_selected { "[✓]" } else { "[ ]" };

                let style = if is_highlighted {
                    Style::default().fg(Color::Cyan).add_modifier(Modifier::BOLD)
                } else {
                    Style::default().fg(Color::White)
                };

                let content = vec![
                    Line::from(vec![
                        Span::styled(checkbox, style),
                        Span::raw(" "),
                        Span::styled(&node.name, style),
                    ]),
                    Line::from(vec![
                        Span::raw("    "),
                        Span::styled(&node.description, Style::default().fg(Color::DarkGray)),
                    ]),
                ];

                ListItem::new(content)
            })
            .collect();

        let selected_count = self.state.selected_node_count();
        let title = format!(" Step 3/4: Nodes ({} selected) ", selected_count);

        let list = List::new(items).block(
            Block::default()
                .borders(Borders::ALL)
                .title(title)
                .border_style(Style::default().fg(Color::Yellow)),
        );

        let mut state = ListState::default();
        state.select(Some(self.selected_index));

        f.render_stateful_widget(list, area, &mut state);
    }

    /// Draw confirmation step
    fn draw_confirmation_step(&self, f: &mut Frame, area: ratatui::layout::Rect) {
        let template_name = self.state.get_template().map(|t| t.name.as_str()).unwrap_or("<none>");

        let mut text = vec![
            Line::from(vec![Span::styled(
                "✅ CONFIRMATION",
                Style::default().fg(Color::Green).add_modifier(Modifier::BOLD),
            )]),
            Line::from(""),
            Line::from("Review your selections:"),
            Line::from(""),
            Line::from(vec![
                Span::styled("Project: ", Style::default().add_modifier(Modifier::BOLD)),
                Span::styled(&self.state.project_name, Style::default().fg(Color::Cyan)),
            ]),
            Line::from(vec![
                Span::styled("Type: ", Style::default().add_modifier(Modifier::BOLD)),
                Span::styled(template_name, Style::default().fg(Color::Cyan)),
            ]),
            Line::from(vec![
                Span::styled("Nodes: ", Style::default().add_modifier(Modifier::BOLD)),
                Span::styled(
                    format!("{} selected", self.state.selected_node_count()),
                    Style::default().fg(Color::Cyan),
                ),
            ]),
            Line::from(""),
        ];

        if self.state.selected_node_count() > 0 {
            for node in self.state.get_selected_nodes() {
                text.push(Line::from(vec![
                    Span::raw("  ✓ "),
                    Span::styled(&node.name, Style::default().fg(Color::Yellow)),
                ]));
            }
            text.push(Line::from(""));
        }

        text.extend(vec![
            Line::from(""),
            Line::from(vec![Span::styled(
                "Press Enter to create project",
                Style::default().fg(Color::Green).add_modifier(Modifier::BOLD),
            )]),
            Line::from(vec![Span::styled(
                "Press Backspace to go back",
                Style::default().fg(Color::Yellow),
            )]),
        ]);

        let paragraph = Paragraph::new(text)
            .block(
                Block::default()
                    .borders(Borders::ALL)
                    .title(" Step 4/4: Confirmation ")
                    .border_style(Style::default().fg(Color::Yellow)),
            )
            .wrap(Wrap { trim: true });

        f.render_widget(paragraph, area);
    }

    /// Draw robot visualization panel
    fn draw_robot_visualization(&self, f: &mut Frame, area: ratatui::layout::Rect) {
        // Isometric ASCII art rover robot (top-left view)
        let rover_art = vec![
            Line::from(""),
            Line::from(""),
            Line::from(vec![
                Span::raw("        "),
                Span::styled("_______________", Style::default().fg(Color::Cyan)),
            ]),
            Line::from(vec![
                Span::raw("       "),
                Span::styled("/", Style::default().fg(Color::Cyan)),
                Span::raw("               "),
                Span::styled("/|", Style::default().fg(Color::Blue)),
            ]),
            Line::from(vec![
                Span::raw("      "),
                Span::styled("/", Style::default().fg(Color::Cyan)),
                Span::raw("               "),
                Span::styled("/ |", Style::default().fg(Color::Blue)),
            ]),
            Line::from(vec![
                Span::raw("     "),
                Span::styled("/_______________/", Style::default().fg(Color::Cyan)),
                Span::raw("  "),
                Span::styled("|", Style::default().fg(Color::Blue)),
            ]),
            Line::from(vec![
                Span::raw("    "),
                Span::styled("|", Style::default().fg(Color::Cyan)),
                Span::raw("               "),
                Span::styled("|", Style::default().fg(Color::Cyan)),
                Span::raw("  "),
                Span::styled("|", Style::default().fg(Color::Blue)),
            ]),
            Line::from(vec![
                Span::raw("    "),
                Span::styled("|", Style::default().fg(Color::Cyan)),
                Span::raw("               "),
                Span::styled("|", Style::default().fg(Color::Cyan)),
                Span::raw(" "),
                Span::styled("/", Style::default().fg(Color::Blue)),
            ]),
            Line::from(vec![
                Span::raw("    "),
                Span::styled("|_______________|", Style::default().fg(Color::Cyan)),
                Span::styled("/", Style::default().fg(Color::Blue)),
            ]),
            Line::from(vec![
                Span::raw("   "),
                Span::styled("/|", Style::default().fg(Color::Yellow)),
                Span::raw("   "),
                Span::styled("●", Style::default().fg(Color::DarkGray)),
                Span::raw("       "),
                Span::styled("●", Style::default().fg(Color::DarkGray)),
                Span::raw("  "),
                Span::styled("|", Style::default().fg(Color::Yellow)),
                Span::styled("/", Style::default().fg(Color::Blue)),
            ]),
            Line::from(vec![
                Span::raw("  "),
                Span::styled("/ |", Style::default().fg(Color::Yellow)),
                Span::raw("  "),
                Span::styled("(_)", Style::default().fg(Color::DarkGray)),
                Span::raw("     "),
                Span::styled("(_)", Style::default().fg(Color::DarkGray)),
                Span::raw(" "),
                Span::styled("|", Style::default().fg(Color::Yellow)),
                Span::styled("/", Style::default().fg(Color::Blue)),
            ]),
            Line::from(vec![
                Span::raw(" "),
                Span::styled("|", Style::default().fg(Color::Yellow)),
                Span::raw("  "),
                Span::styled("|_______________|", Style::default().fg(Color::Yellow)),
                Span::styled("/", Style::default().fg(Color::Blue)),
            ]),
            Line::from(vec![
                Span::raw(" "),
                Span::styled("●", Style::default().fg(Color::DarkGray)),
                Span::styled("/", Style::default().fg(Color::Yellow)),
                Span::raw("               "),
                Span::raw("\\"),
                Span::styled("●", Style::default().fg(Color::DarkGray)),
            ]),
            Line::from(vec![
                Span::styled("(_)", Style::default().fg(Color::DarkGray)),
                Span::raw("                 "),
                Span::styled("(_)", Style::default().fg(Color::DarkGray)),
            ]),
            Line::from(""),
        ];

        let paragraph = Paragraph::new(rover_art)
            .block(
                Block::default()
                    .borders(Borders::ALL)
                    .title(" Robot Preview ")
                    .border_style(Style::default().fg(Color::Green)),
            )
            .wrap(Wrap { trim: true });

        f.render_widget(paragraph, area);
    }

    /// Draw footer
    fn draw_footer(&self, f: &mut Frame, area: ratatui::layout::Rect) {
        let footer_text = vec![Line::from(vec![
            Span::raw("  "),
            Span::styled("↑/↓:", Style::default().fg(Color::Cyan).add_modifier(Modifier::BOLD)),
            Span::raw(" Navigate  "),
            Span::styled(
                "Space:",
                Style::default().fg(Color::Yellow).add_modifier(Modifier::BOLD),
            ),
            Span::raw(" Select  "),
            Span::styled("Enter:", Style::default().fg(Color::Green).add_modifier(Modifier::BOLD)),
            Span::raw(" Next  "),
            Span::styled(
                "Backspace:",
                Style::default().fg(Color::Yellow).add_modifier(Modifier::BOLD),
            ),
            Span::raw(" Back  "),
            Span::styled("Esc:", Style::default().fg(Color::Red).add_modifier(Modifier::BOLD)),
            Span::raw(" Cancel"),
        ])];

        let footer = Paragraph::new(footer_text).block(
            Block::default()
                .borders(Borders::ALL)
                .border_style(Style::default().fg(Color::DarkGray)),
        );

        f.render_widget(footer, area);
    }

    /// Handle keyboard input
    pub fn handle_key(&mut self, key: KeyEvent) {
        match key.code {
            // Quit
            KeyCode::Esc => {
                self.should_quit = true;
            }
            KeyCode::Char('c') if key.modifiers.contains(KeyModifiers::CONTROL) => {
                self.should_quit = true;
            }

            // Handle based on current step
            _ => match self.current_step {
                WizardStep::ProjectName => self.handle_project_name_key(key),
                WizardStep::RobotType => self.handle_robot_type_key(key),
                WizardStep::NodeSelection => self.handle_node_selection_key(key),
                WizardStep::Confirmation => self.handle_confirmation_key(key),
            },
        }
    }

    /// Handle project name step keys
    fn handle_project_name_key(&mut self, key: KeyEvent) {
        match key.code {
            KeyCode::Char(c) => {
                self.state.project_name.push(c);
            }
            KeyCode::Backspace => {
                self.state.project_name.pop();
            }
            KeyCode::Enter => {
                if !self.state.project_name.is_empty() {
                    if let Some(next_step) = self.current_step.next() {
                        self.current_step = next_step;
                        self.selected_index = 0;
                    }
                }
            }
            _ => {}
        }
    }

    /// Handle robot type step keys
    fn handle_robot_type_key(&mut self, key: KeyEvent) {
        match key.code {
            KeyCode::Up => {
                if self.selected_index > 0 {
                    self.selected_index -= 1;
                }
            }
            KeyCode::Down => {
                if self.selected_index < self.state.templates.len().saturating_sub(1) {
                    self.selected_index += 1;
                }
            }
            KeyCode::Enter => {
                self.state.selected_template = Some(self.selected_index);
                if let Some(next_step) = self.current_step.next() {
                    self.current_step = next_step;
                    self.selected_index = 0;
                }
            }
            KeyCode::Backspace => {
                if let Some(prev_step) = self.current_step.prev() {
                    self.current_step = prev_step;
                }
            }
            _ => {}
        }
    }

    /// Handle node selection step keys
    fn handle_node_selection_key(&mut self, key: KeyEvent) {
        match key.code {
            KeyCode::Up => {
                if self.selected_index > 0 {
                    self.selected_index -= 1;
                }
            }
            KeyCode::Down => {
                if self.selected_index < self.state.nodes.len().saturating_sub(1) {
                    self.selected_index += 1;
                }
            }
            KeyCode::Char(' ') => {
                if let Some(selected) = self.state.selected_nodes.get_mut(self.selected_index) {
                    *selected = !*selected;
                }
            }
            KeyCode::Enter => {
                if let Some(next_step) = self.current_step.next() {
                    self.current_step = next_step;
                }
            }
            KeyCode::Backspace => {
                if let Some(prev_step) = self.current_step.prev() {
                    self.current_step = prev_step;
                }
            }
            _ => {}
        }
    }

    /// Handle confirmation step keys
    fn handle_confirmation_key(&mut self, key: KeyEvent) {
        match key.code {
            KeyCode::Enter => {
                self.confirmed = true;
            }
            KeyCode::Backspace => {
                if let Some(prev_step) = self.current_step.prev() {
                    self.current_step = prev_step;
                }
            }
            _ => {}
        }
    }
}
