//! Generation UI components - confirmation, progress, and results

use ratatui::{
    layout::{Alignment, Constraint, Direction, Layout, Rect},
    style::{Color, Modifier, Style},
    text::{Line, Span},
    widgets::{Block, Borders, Clear, Gauge, List, ListItem, Paragraph, Wrap},
    Frame,
};

use crate::manager::app::{App, GenerationState};

/// Render generation overlays (confirmation, progress, results)
pub fn render_generation_overlay(frame: &mut Frame, area: Rect, app: &App) {
    match &app.generation_state {
        GenerationState::Form => {
            // No overlay - show normal form
        }
        GenerationState::ConfirmDialog => {
            render_confirmation_dialog(frame, area, app);
        }
        GenerationState::InProgress { .. } => {
            render_progress_dialog(frame, area, app);
        }
        GenerationState::Success { .. } | GenerationState::Error { .. } => {
            render_results_dialog(frame, area, app);
        }
    }
}

/// Render confirmation dialog before generation
fn render_confirmation_dialog(frame: &mut Frame, area: Rect, app: &App) {
    // Make dialog larger and ensure minimum size
    let dialog_area = centered_rect(75, 65, area);

    // Clear background
    frame.render_widget(Clear, dialog_area);

    let block = Block::default()
        .borders(Borders::ALL)
        .border_style(Style::default().fg(Color::Yellow))
        .title(" Confirm Generation ");

    let inner_area = block.inner(dialog_area);
    frame.render_widget(block, dialog_area);

    // Create layout for dialog content with padding
    let chunks = Layout::default()
        .direction(Direction::Vertical)
        .constraints([
            Constraint::Length(1), // Top padding
            Constraint::Min(0),    // Main content
            Constraint::Length(1), // Middle padding
            Constraint::Length(3), // Buttons
            Constraint::Length(1), // Bottom padding
        ])
        .split(inner_area);

    // Main content
    let selected_langs = app.selected_languages();
    let lang_list = if selected_langs.len() > 3 {
        format!(
            "{} and {} more",
            selected_langs[..2].join(", "),
            selected_langs.len() - 2
        )
    } else {
        selected_langs.join(", ")
    };

    let content = vec![
        Line::from(vec![
            Span::styled("Ready to generate page: ", Style::default()),
            Span::styled(
                &app.page_name,
                Style::default()
                    .fg(Color::Cyan)
                    .add_modifier(Modifier::BOLD),
            ),
        ]),
        Line::from(""),
        Line::from(vec![
            Span::styled("Template: ", Style::default()),
            Span::styled(
                app.selected_template.name(),
                Style::default().fg(Color::Green),
            ),
        ]),
        Line::from(vec![
            Span::styled("Route: ", Style::default()),
            Span::styled(&app.route_path, Style::default().fg(Color::Blue)),
        ]),
        Line::from(vec![
            Span::styled("Languages: ", Style::default()),
            Span::styled(&lang_list, Style::default().fg(Color::Magenta)),
        ]),
        Line::from(vec![
            Span::styled("Priority: ", Style::default()),
            Span::styled(
                format!("{:.1}", app.priority),
                Style::default().fg(Color::Yellow),
            ),
        ]),
        Line::from(""),
        Line::from("This will create the following files:"),
        Line::from(vec![
            Span::styled("• ", Style::default().fg(Color::Green)),
            Span::raw("Route configuration (TOML)"),
        ]),
    ];

    let mut content_lines = content;

    if app.auto_scaffold {
        content_lines.push(Line::from(vec![
            Span::styled("• ", Style::default().fg(Color::Green)),
            Span::raw("Component files (Rust)"),
        ]));
    }

    for lang in selected_langs.iter().take(3) {
        content_lines.push(Line::from(vec![
            Span::styled("• ", Style::default().fg(Color::Green)),
            Span::raw(format!("Translation file ({})", lang)),
        ]));
    }

    if selected_langs.len() > 3 {
        content_lines.push(Line::from(vec![
            Span::styled("• ", Style::default().fg(Color::Green)),
            Span::raw(format!(
                "...and {} more translation files",
                selected_langs.len() - 3
            )),
        ]));
    }

    let paragraph = Paragraph::new(content_lines).wrap(Wrap { trim: true });

    frame.render_widget(paragraph, chunks[1]); // Use chunks[1] for main content (after top padding)

    // Buttons (use chunks[3] after middle padding)
    render_confirmation_buttons(frame, chunks[3]);
}

/// Render confirmation buttons
fn render_confirmation_buttons(frame: &mut Frame, area: Rect) {
    let button_layout = Layout::default()
        .direction(Direction::Horizontal)
        .constraints([
            Constraint::Length(2), // Left padding
            Constraint::Min(0),    // Generate button
            Constraint::Length(2), // Middle spacing
            Constraint::Min(0),    // Cancel button
            Constraint::Length(2), // Right padding
        ])
        .split(area);

    // Generate button (focused)
    let generate_button = Paragraph::new("[ Generate ]")
        .alignment(Alignment::Center)
        .style(
            Style::default()
                .bg(Color::Green)
                .fg(Color::Black)
                .add_modifier(Modifier::BOLD),
        )
        .block(Block::default().borders(Borders::ALL));

    frame.render_widget(generate_button, button_layout[1]);

    // Cancel button
    let cancel_button = Paragraph::new("[ Cancel ]")
        .alignment(Alignment::Center)
        .style(Style::default().fg(Color::Red).add_modifier(Modifier::BOLD))
        .block(Block::default().borders(Borders::ALL));

    frame.render_widget(cancel_button, button_layout[3]);
}

/// Render progress dialog during generation
fn render_progress_dialog(frame: &mut Frame, area: Rect, app: &App) {
    if let GenerationState::InProgress {
        current_step,
        completed_steps,
        total_steps,
        files_processed,
    } = &app.generation_state
    {
        let dialog_area = centered_rect(80, 60, area);

        // Clear background
        frame.render_widget(Clear, dialog_area);

        let block = Block::default()
            .borders(Borders::ALL)
            .border_style(Style::default().fg(Color::Blue))
            .title("Generating Page...");

        let inner_area = block.inner(dialog_area);
        frame.render_widget(block, dialog_area);

        // Create layout
        let chunks = Layout::default()
            .direction(Direction::Vertical)
            .constraints([
                Constraint::Length(3), // Progress bar
                Constraint::Length(3), // Current step
                Constraint::Min(0),    // File list
            ])
            .split(inner_area);

        // Progress bar
        let progress = (*completed_steps as f64 / *total_steps as f64) * 100.0;
        let progress_bar = Gauge::default()
            .block(Block::default().borders(Borders::ALL).title("Progress"))
            .gauge_style(
                Style::default()
                    .fg(Color::Blue)
                    .add_modifier(Modifier::BOLD),
            )
            .percent(progress as u16)
            .label(format!("{}/{} steps", completed_steps, total_steps));

        frame.render_widget(progress_bar, chunks[0]);

        // Current step
        let step_text = Paragraph::new(vec![Line::from(vec![
            Span::styled("Current step: ", Style::default()),
            Span::styled(
                current_step,
                Style::default()
                    .fg(Color::Yellow)
                    .add_modifier(Modifier::BOLD),
            ),
        ])])
        .block(Block::default().borders(Borders::ALL));

        frame.render_widget(step_text, chunks[1]);

        // File list
        let file_items: Vec<ListItem> = files_processed
            .iter()
            .map(|file| {
                ListItem::new(Line::from(vec![
                    Span::styled("✓ ", Style::default().fg(Color::Green)),
                    Span::raw(file),
                ]))
            })
            .collect();

        let file_list = List::new(file_items).block(
            Block::default()
                .borders(Borders::ALL)
                .title("Files Processed"),
        );

        frame.render_widget(file_list, chunks[2]);
    }
}

/// Render results dialog (success or error)
fn render_results_dialog(frame: &mut Frame, area: Rect, app: &App) {
    let dialog_area = centered_rect(85, 75, area);

    // Clear background
    frame.render_widget(Clear, dialog_area);

    match &app.generation_state {
        GenerationState::Success {
            files_created,
            files_updated,
            generation_time,
        } => {
            render_success_dialog(
                frame,
                dialog_area,
                files_created,
                files_updated,
                generation_time,
            );
        }
        GenerationState::Error {
            error_message,
            files_rolled_back,
        } => {
            render_error_dialog(frame, dialog_area, error_message, files_rolled_back);
        }
        _ => {}
    }
}

/// Render success results dialog
fn render_success_dialog(
    frame: &mut Frame,
    area: Rect,
    files_created: &[String],
    files_updated: &[String],
    duration: &std::time::Duration,
) {
    let block = Block::default()
        .borders(Borders::ALL)
        .border_style(Style::default().fg(Color::Green))
        .title("✅ Generation Successful!");

    let inner_area = block.inner(area);
    frame.render_widget(block, area);

    // Create layout
    let chunks = Layout::default()
        .direction(Direction::Vertical)
        .constraints([
            Constraint::Length(5), // Summary
            Constraint::Min(0),    // File lists
            Constraint::Length(3), // Actions
        ])
        .split(inner_area);

    // Summary
    let total_files = files_created.len() + files_updated.len();
    let summary = vec![
        Line::from(vec![Span::styled(
            "🎉 Page generation completed successfully!",
            Style::default()
                .fg(Color::Green)
                .add_modifier(Modifier::BOLD),
        )]),
        Line::from(""),
        Line::from(vec![
            Span::styled("Files processed: ", Style::default()),
            Span::styled(
                format!("{}", total_files),
                Style::default()
                    .fg(Color::Cyan)
                    .add_modifier(Modifier::BOLD),
            ),
        ]),
        Line::from(vec![
            Span::styled("Generation time: ", Style::default()),
            Span::styled(
                format!("{:.2}s", duration.as_secs_f64()),
                Style::default()
                    .fg(Color::Yellow)
                    .add_modifier(Modifier::BOLD),
            ),
        ]),
    ];

    let summary_paragraph =
        Paragraph::new(summary).block(Block::default().borders(Borders::ALL).title("Summary"));

    frame.render_widget(summary_paragraph, chunks[0]);

    // File lists
    render_file_lists(frame, chunks[1], files_created, files_updated);

    // Action buttons
    render_result_actions(frame, chunks[2], true);
}

/// Render error results dialog
fn render_error_dialog(
    frame: &mut Frame,
    area: Rect,
    error_message: &str,
    rolled_back_files: &[String],
) {
    let block = Block::default()
        .borders(Borders::ALL)
        .border_style(Style::default().fg(Color::Red))
        .title("❌ Generation Failed");

    let inner_area = block.inner(area);
    frame.render_widget(block, area);

    // Create layout
    let chunks = Layout::default()
        .direction(Direction::Vertical)
        .constraints([
            Constraint::Min(0),    // Error details
            Constraint::Length(3), // Actions
        ])
        .split(inner_area);

    // Error details
    let mut error_lines = vec![
        Line::from(vec![Span::styled(
            "💥 Generation failed with error:",
            Style::default().fg(Color::Red).add_modifier(Modifier::BOLD),
        )]),
        Line::from(""),
        Line::from(error_message),
        Line::from(""),
    ];

    if !rolled_back_files.is_empty() {
        error_lines.push(Line::from(vec![Span::styled(
            "🔄 Rolled back files:",
            Style::default()
                .fg(Color::Yellow)
                .add_modifier(Modifier::BOLD),
        )]));
        for file in rolled_back_files {
            error_lines.push(Line::from(vec![
                Span::styled("  • ", Style::default().fg(Color::Yellow)),
                Span::raw(file),
            ]));
        }
        error_lines.push(Line::from(""));
    }

    error_lines.push(Line::from(vec![
        Span::styled("💡 ", Style::default().fg(Color::Blue)),
        Span::raw("Please check the error and try again."),
    ]));

    let error_paragraph = Paragraph::new(error_lines).wrap(Wrap { trim: true }).block(
        Block::default()
            .borders(Borders::ALL)
            .title("Error Details"),
    );

    frame.render_widget(error_paragraph, chunks[0]);

    // Action buttons
    render_result_actions(frame, chunks[1], false);
}

/// Render file lists (created and updated)
fn render_file_lists(
    frame: &mut Frame,
    area: Rect,
    files_created: &[String],
    files_updated: &[String],
) {
    if files_created.is_empty() && files_updated.is_empty() {
        return;
    }

    let list_layout = Layout::default()
        .direction(Direction::Horizontal)
        .constraints([Constraint::Percentage(50), Constraint::Percentage(50)])
        .split(area);

    // Created files
    if !files_created.is_empty() {
        let created_items: Vec<ListItem> = files_created
            .iter()
            .map(|file| {
                ListItem::new(Line::from(vec![
                    Span::styled("+ ", Style::default().fg(Color::Green)),
                    Span::raw(file),
                ]))
            })
            .collect();

        let created_list = List::new(created_items).block(
            Block::default()
                .borders(Borders::ALL)
                .title(format!("Created ({})", files_created.len())),
        );

        frame.render_widget(created_list, list_layout[0]);
    }

    // Updated files
    if !files_updated.is_empty() {
        let updated_items: Vec<ListItem> = files_updated
            .iter()
            .map(|file| {
                ListItem::new(Line::from(vec![
                    Span::styled("~ ", Style::default().fg(Color::Blue)),
                    Span::raw(file),
                ]))
            })
            .collect();

        let updated_list = List::new(updated_items).block(
            Block::default()
                .borders(Borders::ALL)
                .title(format!("Updated ({})", files_updated.len())),
        );

        frame.render_widget(updated_list, list_layout[1]);
    }
}

/// Render action buttons in results dialog
fn render_result_actions(frame: &mut Frame, area: Rect, is_success: bool) {
    let button_layout = Layout::default()
        .direction(Direction::Horizontal)
        .constraints([
            Constraint::Percentage(33),
            Constraint::Percentage(33),
            Constraint::Percentage(34),
        ])
        .split(area);

    if is_success {
        // Open Files button
        let open_button = Paragraph::new("Open Files")
            .alignment(Alignment::Center)
            .style(
                Style::default()
                    .bg(Color::Blue)
                    .fg(Color::White)
                    .add_modifier(Modifier::BOLD),
            )
            .block(Block::default().borders(Borders::ALL));

        frame.render_widget(open_button, button_layout[0]);

        // New Page button
        let new_button = Paragraph::new("New Page")
            .alignment(Alignment::Center)
            .style(
                Style::default()
                    .fg(Color::Green)
                    .add_modifier(Modifier::BOLD),
            )
            .block(Block::default().borders(Borders::ALL));

        frame.render_widget(new_button, button_layout[1]);
    } else {
        // Try Again button
        let retry_button = Paragraph::new("Try Again")
            .alignment(Alignment::Center)
            .style(
                Style::default()
                    .fg(Color::Yellow)
                    .add_modifier(Modifier::BOLD),
            )
            .block(Block::default().borders(Borders::ALL));

        frame.render_widget(retry_button, button_layout[1]);
    }

    // Exit button
    let exit_button = Paragraph::new("Exit")
        .alignment(Alignment::Center)
        .style(Style::default().fg(Color::Red).add_modifier(Modifier::BOLD))
        .block(Block::default().borders(Borders::ALL));

    frame.render_widget(exit_button, button_layout[2]);
}

/// Helper function to create a centered rectangle with minimum size constraints
fn centered_rect(percent_x: u16, percent_y: u16, r: Rect) -> Rect {
    // Ensure minimum sizes
    let min_width = 60;
    let min_height = 20;

    let target_width = std::cmp::max(r.width * percent_x / 100, min_width);
    let target_height = std::cmp::max(r.height * percent_y / 100, min_height);

    // Ensure we don't exceed available space
    let width = std::cmp::min(target_width, r.width.saturating_sub(4));
    let height = std::cmp::min(target_height, r.height.saturating_sub(4));

    let x = r.x + (r.width.saturating_sub(width)) / 2;
    let y = r.y + (r.height.saturating_sub(height)) / 2;

    Rect::new(x, y, width, height)
}
