//! Modal dialogs for save/load operations, version control, and command
//! templates

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

use crate::manager::app::App;
use crate::manager::version_control::{BackupInfo, CommandTemplate};

/// Modal dialog types
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ModalType {
    /// Save command template modal
    SaveTemplate,
    /// Load command template modal
    LoadTemplate,
    /// Version control backup list
    BackupList,
    /// Confirm action modal
    ConfirmAction,
    /// Command template editor
    TemplateEditor,
    /// Backup restore confirmation
    RestoreBackup,
}

/// Modal dialog state
#[derive(Debug)]
pub struct ModalState {
    pub modal_type: ModalType,
    pub title: String,
    pub message: String,
    pub input_text: String,
    pub selected_index: usize,
    pub items: Vec<String>,
    pub show_input: bool,
    pub template_being_edited: Option<CommandTemplate>,
    pub backup_being_restored: Option<BackupInfo>,
}

impl ModalState {
    pub fn new(modal_type: ModalType, title: String, message: String) -> Self {
        Self {
            modal_type,
            title,
            message,
            input_text: String::new(),
            selected_index: 0,
            items: Vec::new(),
            show_input: false,
            template_being_edited: None,
            backup_being_restored: None,
        }
    }

    pub fn with_input(mut self) -> Self {
        self.show_input = true;
        self
    }

    pub fn with_items(mut self, items: Vec<String>) -> Self {
        self.items = items;
        self
    }

    pub fn with_template(mut self, template: CommandTemplate) -> Self {
        self.template_being_edited = Some(template);
        self
    }

    pub fn with_backup(mut self, backup: BackupInfo) -> Self {
        self.backup_being_restored = Some(backup);
        self
    }

    pub fn next_item(&mut self) {
        if !self.items.is_empty() {
            self.selected_index = (self.selected_index + 1) % self.items.len();
        }
    }

    pub fn previous_item(&mut self) {
        if !self.items.is_empty() {
            if self.selected_index == 0 {
                self.selected_index = self.items.len() - 1;
            } else {
                self.selected_index = self.selected_index.saturating_sub(1);
            }
        }
    }

    pub fn selected_item(&self) -> Option<&String> {
        self.items.get(self.selected_index)
    }
}

/// Render modal overlay
pub fn render_modal(frame: &mut Frame, area: Rect, app: &App, modal_state: &ModalState) {
    match modal_state.modal_type {
        ModalType::SaveTemplate => render_save_template_modal(frame, area, app, modal_state),
        ModalType::LoadTemplate => render_load_template_modal(frame, area, app, modal_state),
        ModalType::BackupList => render_backup_list_modal(frame, area, app, modal_state),
        ModalType::ConfirmAction => render_confirm_action_modal(frame, area, app, modal_state),
        ModalType::TemplateEditor => render_template_editor_modal(frame, area, app, modal_state),
        ModalType::RestoreBackup => render_restore_backup_modal(frame, area, app, modal_state),
    }
}

/// Render save command template modal
fn render_save_template_modal(frame: &mut Frame, area: Rect, app: &App, modal_state: &ModalState) {
    let modal_area = centered_rect(60, 50, area);

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

    let block = Block::default()
        .borders(Borders::ALL)
        .border_style(Style::default().fg(Color::Green))
        .title(" Save Command Template ");

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

    // Layout
    let chunks = Layout::default()
        .direction(Direction::Vertical)
        .constraints([
            Constraint::Length(3), // Instructions
            Constraint::Length(3), // Template name input
            Constraint::Length(3), // Description input
            Constraint::Min(0),    // Current settings preview
            Constraint::Length(3), // Buttons
        ])
        .split(inner_area);

    // Instructions
    let instructions = app
        .translations
        .get("mgr-save-template-instructions")
        .cloned()
        .unwrap_or_else(|| "Enter template name and description:".to_string());

    let instructions_widget = Paragraph::new(instructions)
        .block(Block::default().borders(Borders::ALL).title("Instructions"));
    frame.render_widget(instructions_widget, chunks[0]);

    // Template name input
    let name_text = format!("Name: {}_", modal_state.input_text);
    let name_widget = Paragraph::new(name_text)
        .style(Style::default().fg(Color::Yellow))
        .block(Block::default().borders(Borders::ALL));
    frame.render_widget(name_widget, chunks[1]);

    // Description (auto-generated)
    let description = format!("Auto-generated from page: {}", app.page_name);
    let description_widget = Paragraph::new(description)
        .block(Block::default().borders(Borders::ALL).title("Description"));
    frame.render_widget(description_widget, chunks[2]);

    // Current settings preview
    render_current_settings_preview(frame, chunks[3], app);

    // Buttons
    render_modal_buttons(frame, chunks[4], &["Save", "Cancel"]);
}

/// Render load command template modal
fn render_load_template_modal(frame: &mut Frame, area: Rect, app: &App, modal_state: &ModalState) {
    let modal_area = centered_rect(70, 60, area);

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

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

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

    // Layout
    let chunks = Layout::default()
        .direction(Direction::Vertical)
        .constraints([
            Constraint::Length(2), // Instructions
            Constraint::Min(0),    // Template list
            Constraint::Length(3), // Buttons
        ])
        .split(inner_area);

    // Instructions
    let instructions = app
        .translations
        .get("mgr-load-template-instructions")
        .cloned()
        .unwrap_or_else(|| "Select a command template to load:".to_string());

    let instructions_widget = Paragraph::new(instructions);
    frame.render_widget(instructions_widget, chunks[0]);

    // Template list
    if modal_state.items.is_empty() {
        let no_templates = app
            .translations
            .get("mgr-no-templates")
            .cloned()
            .unwrap_or_else(|| "No command templates found.".to_string());

        let empty_widget = Paragraph::new(no_templates)
            .alignment(Alignment::Center)
            .style(Style::default().fg(Color::Gray))
            .block(Block::default().borders(Borders::ALL));
        frame.render_widget(empty_widget, chunks[1]);
    } else {
        let list_items: Vec<ListItem> = modal_state
            .items
            .iter()
            .enumerate()
            .map(|(i, name)| {
                let is_selected = i == modal_state.selected_index;
                let style = if is_selected {
                    Style::default()
                        .fg(Color::Yellow)
                        .add_modifier(Modifier::BOLD)
                } else {
                    Style::default()
                };

                ListItem::new(Line::from(vec![
                    Span::raw("📄 "),
                    Span::styled(name, style),
                ]))
            })
            .collect();

        let list = List::new(list_items)
            .block(Block::default().borders(Borders::ALL).title("Templates"))
            .highlight_style(Style::default().bg(Color::Blue))
            .highlight_symbol("▶ ");

        frame.render_stateful_widget(
            list,
            chunks[1],
            &mut ratatui::widgets::ListState::default()
                .with_selected(Some(modal_state.selected_index)),
        );
    }

    // Buttons
    let buttons = if modal_state.items.is_empty() {
        vec!["Close"]
    } else {
        vec!["Load", "Edit", "Delete", "Cancel"]
    };
    render_modal_buttons(frame, chunks[2], &buttons);
}

/// Render backup list modal
fn render_backup_list_modal(frame: &mut Frame, area: Rect, app: &App, modal_state: &ModalState) {
    let modal_area = centered_rect(80, 70, area);

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

    let block = Block::default()
        .borders(Borders::ALL)
        .border_style(Style::default().fg(Color::Magenta))
        .title(" Version Control - Backups ");

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

    // Layout
    let chunks = Layout::default()
        .direction(Direction::Vertical)
        .constraints([
            Constraint::Length(2), // Instructions
            Constraint::Min(0),    // Backup list
            Constraint::Length(3), // Buttons
        ])
        .split(inner_area);

    // Instructions
    let instructions = app
        .translations
        .get("mgr-backup-instructions")
        .cloned()
        .unwrap_or_else(|| "Select a backup to restore:".to_string());

    let instructions_widget = Paragraph::new(instructions);
    frame.render_widget(instructions_widget, chunks[0]);

    // Backup list (would be populated with actual backup data)
    if modal_state.items.is_empty() {
        let no_backups = app
            .translations
            .get("mgr-no-backups")
            .cloned()
            .unwrap_or_else(|| "No backups found.".to_string());

        let empty_widget = Paragraph::new(no_backups)
            .alignment(Alignment::Center)
            .style(Style::default().fg(Color::Gray))
            .block(Block::default().borders(Borders::ALL));
        frame.render_widget(empty_widget, chunks[1]);
    } else {
        let list_items: Vec<ListItem> = modal_state
            .items
            .iter()
            .enumerate()
            .map(|(i, backup_info)| {
                let is_selected = i == modal_state.selected_index;
                let style = if is_selected {
                    Style::default()
                        .fg(Color::Yellow)
                        .add_modifier(Modifier::BOLD)
                } else {
                    Style::default()
                };

                ListItem::new(Line::from(vec![
                    Span::raw("💾 "),
                    Span::styled(backup_info, style),
                ]))
            })
            .collect();

        let list = List::new(list_items)
            .block(Block::default().borders(Borders::ALL).title("Backups"))
            .highlight_style(Style::default().bg(Color::Magenta))
            .highlight_symbol("▶ ");

        frame.render_stateful_widget(
            list,
            chunks[1],
            &mut ratatui::widgets::ListState::default()
                .with_selected(Some(modal_state.selected_index)),
        );
    }

    // Buttons
    let buttons = if modal_state.items.is_empty() {
        vec!["Close"]
    } else {
        vec!["Restore", "Delete", "Cancel"]
    };
    render_modal_buttons(frame, chunks[2], &buttons);
}

/// Render confirm action modal
fn render_confirm_action_modal(
    frame: &mut Frame,
    area: Rect,
    _app: &App,
    modal_state: &ModalState,
) {
    let modal_area = centered_rect(50, 30, area);

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

    let block = Block::default()
        .borders(Borders::ALL)
        .border_style(Style::default().fg(Color::Yellow))
        .title(modal_state.title.as_str());

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

    // Layout
    let chunks = Layout::default()
        .direction(Direction::Vertical)
        .constraints([
            Constraint::Min(0),    // Message
            Constraint::Length(3), // Buttons
        ])
        .split(inner_area);

    // Message
    let message_widget = Paragraph::new(modal_state.message.clone())
        .alignment(Alignment::Center)
        .wrap(Wrap { trim: true })
        .block(Block::default().borders(Borders::ALL));
    frame.render_widget(message_widget, chunks[0]);

    // Buttons
    render_modal_buttons(frame, chunks[1], &["Yes", "No"]);
}

/// Render template editor modal
fn render_template_editor_modal(
    frame: &mut Frame,
    area: Rect,
    _app: &App,
    modal_state: &ModalState,
) {
    let modal_area = centered_rect(90, 80, area);

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

    let block = Block::default()
        .borders(Borders::ALL)
        .border_style(Style::default().fg(Color::Cyan))
        .title(" Command Template Editor ");

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

    // This would contain a full editor interface
    let editor_placeholder = format!(
        "Built-in editor for template: {}\n\nThis would show the full command template editor \
         with:\n- Template name editing\n- Description editing\n- Command line preview\n- \
         Save/Cancel options",
        modal_state
            .template_being_edited
            .as_ref()
            .map(|t| &t.name)
            .unwrap_or(&"New Template".to_string())
    );

    let editor_widget = Paragraph::new(editor_placeholder)
        .wrap(Wrap { trim: true })
        .block(Block::default().borders(Borders::ALL).title("Editor"));
    frame.render_widget(editor_widget, inner_area);
}

/// Render restore backup modal
fn render_restore_backup_modal(
    frame: &mut Frame,
    area: Rect,
    _app: &App,
    modal_state: &ModalState,
) {
    let modal_area = centered_rect(60, 40, area);

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

    let block = Block::default()
        .borders(Borders::ALL)
        .border_style(Style::default().fg(Color::Red))
        .title(" Restore Backup ");

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

    let message = if let Some(backup) = &modal_state.backup_being_restored {
        format!(
            "Restore backup from {}?\n\nThis will overwrite current files:\n{}",
            backup.timestamp.format("%Y-%m-%d %H:%M:%S"),
            backup.files_backed_up.join("\n")
        )
    } else {
        "Restore selected backup?".to_string()
    };

    let message_widget = Paragraph::new(message)
        .wrap(Wrap { trim: true })
        .alignment(Alignment::Center);
    frame.render_widget(message_widget, inner_area);
}

/// Render current settings preview
fn render_current_settings_preview(frame: &mut Frame, area: Rect, app: &App) {
    let settings = vec![
        Line::from(vec![
            Span::styled("Page Name: ", Style::default().fg(Color::Blue)),
            Span::styled(&app.page_name, Style::default().fg(Color::White)),
        ]),
        Line::from(vec![
            Span::styled("Template: ", Style::default().fg(Color::Blue)),
            Span::styled(
                format!("{:?}", app.selected_template),
                Style::default().fg(Color::Green),
            ),
        ]),
        Line::from(vec![
            Span::styled("Route: ", Style::default().fg(Color::Blue)),
            Span::styled(&app.route_path, Style::default().fg(Color::Yellow)),
        ]),
        Line::from(vec![
            Span::styled("Languages: ", Style::default().fg(Color::Blue)),
            Span::styled(
                app.selected_languages().join(", "),
                Style::default().fg(Color::Magenta),
            ),
        ]),
    ];

    let preview_widget = Paragraph::new(settings).block(
        Block::default()
            .borders(Borders::ALL)
            .title("Current Settings"),
    );
    frame.render_widget(preview_widget, area);
}

/// Render modal buttons
fn render_modal_buttons(frame: &mut Frame, area: Rect, button_labels: &[&str]) {
    if button_labels.is_empty() {
        return;
    }

    let button_count = button_labels.len();
    let constraints: Vec<Constraint> = (0..button_count)
        .map(|_| Constraint::Percentage(100 / button_count as u16))
        .collect();

    let button_layout = Layout::default()
        .direction(Direction::Horizontal)
        .constraints(constraints)
        .split(area);

    for (i, &label) in button_labels.iter().enumerate() {
        let style = if i == 0 {
            // First button is highlighted (focused)
            Style::default()
                .bg(Color::Blue)
                .fg(Color::White)
                .add_modifier(Modifier::BOLD)
        } else {
            Style::default()
                .fg(Color::White)
                .add_modifier(Modifier::BOLD)
        };

        let button = Paragraph::new(format!("[ {} ]", label))
            .alignment(Alignment::Center)
            .style(style)
            .block(Block::default().borders(Borders::ALL));

        if let Some(area) = button_layout.get(i) {
            frame.render_widget(button, *area);
        }
    }
}

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

    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)
}
