//! Quick-connect modal rendering.

use crate::tui::text_edit::{build_edit_value_spans, byte_index_for_char};
use crate::tui::ui::theme;
use crate::tui::{AppState, QuickConnectField, QuickConnectRow};
use ratatui::{
    Frame,
    layout::Rect,
    style::{Modifier, Style},
    text::{Line, Span},
    widgets::{Block, Borders, Clear, Paragraph},
};

impl AppState {
    // Modal rendering.
    pub(crate) fn render_quick_connect_modal(&self, frame: &mut Frame, full_area: Rect) {
        let Some(form) = &self.quick_connect else {
            return;
        };

        let width = full_area.width.clamp(58, 86);
        let height = form.modal_height();
        let area = Self::centered_rect(width, height, full_area);

        frame.render_widget(Clear, area);
        let block = Block::default()
            .borders(Borders::ALL)
            .border_style(Style::default().fg(theme::ansi_cyan()))
            .title(" Quick Connect ");
        let inner = block.inner(area);
        frame.render_widget(block, area);

        let selected_label = Style::default().fg(theme::ansi_yellow()).add_modifier(Modifier::BOLD);
        let normal_label = Style::default().fg(theme::ansi_bright_black());
        let selected_value = Style::default().fg(theme::ansi_bright_white()).add_modifier(Modifier::BOLD);
        let normal_value = Style::default().fg(theme::ansi_bright_white());
        let cursor_value = Style::default().fg(theme::ansi_black()).bg(theme::ansi_cyan()).add_modifier(Modifier::BOLD);
        let host_error_active = form.host_required && form.host.trim().is_empty();
        let host_error_label = Style::default().fg(theme::ansi_red()).add_modifier(Modifier::BOLD);
        let host_error_value = Style::default().fg(theme::ansi_red()).add_modifier(Modifier::BOLD);
        let host_error_cursor = Style::default().fg(theme::ansi_black()).bg(theme::ansi_red()).add_modifier(Modifier::BOLD);
        let selected_region = Style::default()
            .fg(theme::selection_fg())
            .bg(theme::selection_bg())
            .add_modifier(Modifier::BOLD);

        let field_style = |field, selected: QuickConnectField| {
            if field == selected { selected_label } else { normal_label }
        };
        let value_style = |field, selected: QuickConnectField| {
            if field == selected { selected_value } else { normal_value }
        };

        let host_label_style = if host_error_active {
            host_error_label
        } else {
            field_style(QuickConnectField::Host, form.selected)
        };

        let host_base_value = if host_error_active {
            host_error_value
        } else {
            value_style(QuickConnectField::Host, form.selected)
        };

        let host_cursor_style = if host_error_active { host_error_cursor } else { cursor_value };

        let user_value_spans: Vec<Span<'_>> = if form.selected == QuickConnectField::User {
            build_edit_value_spans(
                &form.user,
                form.cursor_for_field(QuickConnectField::User).unwrap_or(0),
                form.selection_for_field(QuickConnectField::User),
                selected_value,
                cursor_value,
                selected_region,
            )
        } else if form.user.is_empty() {
            vec![Span::styled(if form.is_rdp() { "" } else { "(optional)" }, normal_value)]
        } else {
            vec![Span::styled(form.user.as_str(), normal_value)]
        };
        let host_value_spans: Vec<Span<'_>> = if form.selected == QuickConnectField::Host {
            build_edit_value_spans(
                &form.host,
                form.cursor_for_field(QuickConnectField::Host).unwrap_or(0),
                form.selection_for_field(QuickConnectField::Host),
                host_base_value,
                host_cursor_style,
                selected_region,
            )
        } else if form.host.is_empty() {
            vec![Span::styled("", host_base_value)]
        } else {
            vec![Span::styled(form.host.as_str(), host_base_value)]
        };
        let port_value_spans: Vec<Span<'_>> = if form.selected == QuickConnectField::Port {
            build_edit_value_spans(
                &form.port,
                form.cursor_for_field(QuickConnectField::Port).unwrap_or(0),
                form.selection_for_field(QuickConnectField::Port),
                selected_value,
                cursor_value,
                selected_region,
            )
        } else if form.port.is_empty() {
            vec![Span::styled("(optional)", normal_value)]
        } else {
            vec![Span::styled(form.port.as_str(), normal_value)]
        };
        let domain_value_spans: Vec<Span<'_>> = if form.selected == QuickConnectField::Domain {
            build_edit_value_spans(
                &form.domain,
                form.cursor_for_field(QuickConnectField::Domain).unwrap_or(0),
                form.selection_for_field(QuickConnectField::Domain),
                selected_value,
                cursor_value,
                selected_region,
            )
        } else if form.domain.is_empty() {
            vec![Span::styled("(optional)", normal_value)]
        } else {
            vec![Span::styled(form.domain.as_str(), normal_value)]
        };
        let password_value_spans: Vec<Span<'_>> = {
            let masked = form.masked_password();
            if form.selected == QuickConnectField::Password {
                let cursor = form.cursor_for_field(QuickConnectField::Password).unwrap_or(0).min(masked.chars().count());
                if masked.is_empty() {
                    vec![Span::styled(" ".to_string(), cursor_value)]
                } else if cursor < masked.chars().count() {
                    let start = byte_index_for_char(&masked, cursor);
                    let end = byte_index_for_char(&masked, cursor + 1);
                    vec![
                        Span::styled(masked[..start].to_string(), selected_value),
                        Span::styled(masked[start..end].to_string(), cursor_value),
                        Span::styled(masked[end..].to_string(), selected_value),
                    ]
                } else {
                    vec![Span::styled(masked, selected_value), Span::styled(" ".to_string(), cursor_value)]
                }
            } else if masked.is_empty() {
                vec![Span::styled("(optional)", normal_value)]
            } else {
                vec![Span::styled(masked, normal_value)]
            }
        };
        let profile_text = form.selected_profile_label();
        let mut profile_list_spans = vec![Span::styled("Profiles: ", Style::default().fg(theme::ansi_bright_black()))];
        for (idx, profile_name) in form.profile_options.iter().enumerate() {
            if idx > 0 {
                profile_list_spans.push(Span::styled(" | ", Style::default().fg(theme::ansi_bright_black())));
            }
            let style = if idx == form.profile_index {
                Style::default().fg(theme::ansi_cyan()).add_modifier(Modifier::BOLD)
            } else {
                Style::default().fg(theme::ansi_white())
            };
            profile_list_spans.push(Span::styled(profile_name.as_str(), style));
        }

        let logging_mark = if form.ssh_logging { "[x]" } else { "[ ]" };
        let connect_style = if form.selected == QuickConnectField::Connect {
            Style::default().fg(theme::ansi_green()).add_modifier(Modifier::BOLD)
        } else {
            Style::default().fg(theme::ansi_bright_black())
        };
        let cancel_style = if form.selected == QuickConnectField::Cancel {
            Style::default().fg(theme::ansi_red()).add_modifier(Modifier::BOLD)
        } else {
            Style::default().fg(theme::ansi_bright_black())
        };

        let mut user_line_spans = vec![Span::styled("User: ", field_style(QuickConnectField::User, form.selected))];
        user_line_spans.extend(user_value_spans);

        let mut host_line_spans = vec![Span::styled("Host: ", host_label_style)];
        host_line_spans.extend(host_value_spans);

        let mut port_line_spans = vec![Span::styled("Port: ", field_style(QuickConnectField::Port, form.selected))];
        port_line_spans.extend(port_value_spans);

        let mut domain_line_spans = vec![Span::styled("Domain: ", field_style(QuickConnectField::Domain, form.selected))];
        domain_line_spans.extend(domain_value_spans);

        let mut password_line_spans = vec![Span::styled("Password: ", field_style(QuickConnectField::Password, form.selected))];
        password_line_spans.extend(password_value_spans);

        let message_line = if let Some(error) = &form.error {
            Line::from(vec![Span::styled(
                error.clone(),
                Style::default().fg(theme::ansi_red()).add_modifier(Modifier::BOLD),
            )])
        } else if form.is_rdp() {
            Line::from(vec![Span::styled(
                "Leave password blank to use the FreeRDP password prompt.",
                Style::default().fg(theme::ansi_bright_black()),
            )])
        } else {
            Line::from(vec![Span::styled(
                "Profiles and SSH logging apply only to SSH quick connects.",
                Style::default().fg(theme::ansi_bright_black()),
            )])
        };

        let lines: Vec<Line<'_>> = form
            .modal_rows()
            .into_iter()
            .map(|row| match row {
                QuickConnectRow::Field(QuickConnectField::Protocol) => Line::from(vec![
                    Span::styled("Protocol: ", field_style(QuickConnectField::Protocol, form.selected)),
                    Span::styled(form.protocol_display_name(), value_style(QuickConnectField::Protocol, form.selected)),
                ]),
                QuickConnectRow::Field(QuickConnectField::User) => Line::from(user_line_spans.clone()),
                QuickConnectRow::Field(QuickConnectField::Host) => Line::from(host_line_spans.clone()),
                QuickConnectRow::Field(QuickConnectField::Port) => Line::from(port_line_spans.clone()),
                QuickConnectRow::Field(QuickConnectField::Domain) => Line::from(domain_line_spans.clone()),
                QuickConnectRow::Field(QuickConnectField::Password) => Line::from(password_line_spans.clone()),
                QuickConnectRow::Field(QuickConnectField::Profile) => Line::from(vec![
                    Span::styled("Profile: ", field_style(QuickConnectField::Profile, form.selected)),
                    Span::styled(profile_text, value_style(QuickConnectField::Profile, form.selected)),
                ]),
                QuickConnectRow::Field(QuickConnectField::Logging) => Line::from(vec![
                    Span::styled("SSH Logging: ", field_style(QuickConnectField::Logging, form.selected)),
                    Span::styled(logging_mark.to_string(), value_style(QuickConnectField::Logging, form.selected)),
                ]),
                QuickConnectRow::Field(QuickConnectField::Connect | QuickConnectField::Cancel) => Line::default(),
                QuickConnectRow::ProfileOptions => Line::from(profile_list_spans.clone()),
                QuickConnectRow::Message => message_line.clone(),
                QuickConnectRow::Actions => Line::from(vec![
                    Span::styled("[ Enter ] Connect", connect_style),
                    Span::styled(" | ", Style::default().fg(theme::ansi_bright_black())),
                    Span::styled("[ Esc ] Cancel", cancel_style),
                ]),
            })
            .collect();

        frame.render_widget(Paragraph::new(lines), inner);
    }

    // Shared centered popup helper.
    pub(crate) fn centered_rect(width: u16, height: u16, area: Rect) -> Rect {
        let popup_width = width.min(area.width);
        let popup_height = height.min(area.height);
        let popup_x = area.x + area.width.saturating_sub(popup_width) / 2;
        let popup_y = area.y + area.height.saturating_sub(popup_height) / 2;
        Rect::new(popup_x, popup_y, popup_width, popup_height)
    }
}
