use super::super::theme;
use super::super::*;

pub(super) fn render_loading_overlay(
    frame: &mut Frame<'_>,
    app: &App,
    content_area: Rect,
    theme: &theme::Theme,
    kind: LoadingKind,
    title: &str,
    message: &str,
) {
    let area = centered_rect_fixed(OVERLAY_FIXED_MD.0, OVERLAY_FIXED_MD.1, content_area);
    frame.render_widget(Clear, area);

    let spinner = match app.tick % 4 {
        1 => "/",
        2 => "-",
        3 => "\\",
        _ => "|",
    };
    let full_title = format!("{spinner} {title}");

    let outer = Block::default()
        .borders(Borders::ALL)
        .border_type(BorderType::Plain)
        .border_style(overlay_border_style(theme, false))
        .title(full_title);
    frame.render_widget(outer.clone(), area);
    let inner = outer.inner(area);

    let chunks = Layout::default()
        .direction(Direction::Vertical)
        .constraints([Constraint::Length(1), Constraint::Min(0)])
        .split(inner);

    let esc_label = match kind {
        LoadingKind::UpdateCheck => texts::tui_key_cancel(),
        _ => texts::tui_key_close(),
    };
    render_key_bar_center(frame, chunks[0], theme, &[("Esc", esc_label)]);
    let body_area = inset_top(chunks[1], 1);
    frame.render_widget(
        Paragraph::new(centered_message_lines(
            message,
            body_area.width,
            body_area.height,
        ))
        .alignment(Alignment::Center)
        .wrap(Wrap { trim: false }),
        body_area,
    );
}

pub(super) fn render_speedtest_running_overlay(
    frame: &mut Frame<'_>,
    content_area: Rect,
    theme: &theme::Theme,
    url: &str,
) {
    let title = texts::tui_speedtest_title();
    let message = texts::tui_speedtest_running(url);
    render_compact_message_overlay(frame, content_area, theme, title, &message);
}

pub(super) fn render_speedtest_result_overlay(
    frame: &mut Frame<'_>,
    content_area: Rect,
    theme: &theme::Theme,
    url: &str,
    lines: &[String],
    scroll: usize,
) {
    render_result_overlay(
        frame,
        content_area,
        theme,
        texts::tui_speedtest_title(),
        texts::tui_speedtest_title_with_url(url),
        lines,
        scroll,
    );
}

pub(super) fn render_stream_check_running_overlay(
    frame: &mut Frame<'_>,
    content_area: Rect,
    theme: &theme::Theme,
    provider_name: &str,
) {
    let title = texts::tui_stream_check_title();
    let message = texts::tui_stream_check_running(provider_name);
    render_compact_message_overlay(frame, content_area, theme, title, &message);
}

pub(super) fn render_stream_check_result_overlay(
    frame: &mut Frame<'_>,
    content_area: Rect,
    theme: &theme::Theme,
    provider_name: &str,
    lines: &[String],
    scroll: usize,
) {
    render_result_overlay(
        frame,
        content_area,
        theme,
        texts::tui_stream_check_title(),
        texts::tui_stream_check_title_with_provider(provider_name),
        lines,
        scroll,
    );
}

pub(super) fn render_update_available_overlay(
    frame: &mut Frame<'_>,
    content_area: Rect,
    theme: &theme::Theme,
    current: &str,
    latest: &str,
    selected: usize,
) {
    let area = centered_rect_fixed(OVERLAY_FIXED_MD.0, OVERLAY_FIXED_MD.1, content_area);
    frame.render_widget(Clear, area);

    let outer = Block::default()
        .borders(Borders::ALL)
        .border_type(BorderType::Plain)
        .border_style(overlay_border_style(theme, true))
        .title(texts::tui_update_available_title());
    frame.render_widget(outer.clone(), area);
    let inner = outer.inner(area);

    let chunks = Layout::default()
        .direction(Direction::Vertical)
        .constraints([
            Constraint::Length(1),
            Constraint::Length(2),
            Constraint::Length(1),
            Constraint::Min(0),
        ])
        .split(inner);

    render_key_bar_center(
        frame,
        chunks[0],
        theme,
        &[
            ("←→", texts::tui_key_select()),
            ("Enter", texts::tui_key_apply()),
            ("Esc", texts::tui_key_cancel()),
        ],
    );

    let version_line = texts::tui_update_version_info(current, latest);
    frame.render_widget(
        Paragraph::new(Line::raw(version_line)).alignment(Alignment::Center),
        chunks[1],
    );

    let update_label = format!("[ {} ]", texts::tui_update_btn_update());
    let cancel_label = format!("[ {} ]", texts::tui_update_btn_cancel());
    let update_style = if selected == 0 {
        Style::default()
            .fg(theme.accent)
            .add_modifier(Modifier::BOLD | Modifier::REVERSED)
    } else {
        Style::default().fg(theme.dim)
    };
    let cancel_style = if selected == 1 {
        Style::default()
            .fg(theme.warn)
            .add_modifier(Modifier::BOLD | Modifier::REVERSED)
    } else {
        Style::default().fg(theme.dim)
    };

    let buttons = Line::from(vec![
        Span::styled(update_label, update_style),
        Span::raw("  "),
        Span::styled(cancel_label, cancel_style),
    ]);
    frame.render_widget(
        Paragraph::new(buttons).alignment(Alignment::Center),
        chunks[2],
    );
}

pub(super) fn render_update_downloading_overlay(
    frame: &mut Frame<'_>,
    content_area: Rect,
    theme: &theme::Theme,
    downloaded: u64,
    total: Option<u64>,
) {
    let area = centered_rect_fixed(OVERLAY_FIXED_SM.0, OVERLAY_FIXED_SM.1, content_area);
    frame.render_widget(Clear, area);

    let outer = Block::default()
        .borders(Borders::ALL)
        .border_type(BorderType::Plain)
        .border_style(overlay_border_style(theme, true))
        .title(texts::tui_update_downloading_title());
    frame.render_widget(outer.clone(), area);
    let inner = outer.inner(area);

    let chunks = Layout::default()
        .direction(Direction::Vertical)
        .constraints([Constraint::Length(1), Constraint::Min(0)])
        .split(inner);

    render_key_bar_center(frame, chunks[0], theme, &[("Esc", texts::tui_key_hide())]);
    let body_area = inset_top(chunks[1], 1);

    let progress_text = if let Some(t) = total {
        if t > 0 {
            let pct = ((downloaded.saturating_mul(100) / t).min(100)) as u64;
            texts::tui_update_downloading_progress(pct, downloaded / 1024, t / 1024)
        } else {
            texts::tui_update_downloading_kb(downloaded / 1024)
        }
    } else {
        texts::tui_update_downloading_kb(downloaded / 1024)
    };

    let gauge_ratio = if let Some(t) = total {
        if t > 0 {
            (downloaded as f64 / t as f64).min(1.0)
        } else {
            0.0
        }
    } else {
        0.0
    };

    frame.render_widget(
        Gauge::default()
            .block(Block::default())
            .gauge_style(Style::default().fg(theme.accent))
            .ratio(gauge_ratio)
            .label(progress_text),
        body_area,
    );
}

pub(super) fn render_update_result_overlay(
    frame: &mut Frame<'_>,
    content_area: Rect,
    theme: &theme::Theme,
    success: bool,
    message: &str,
) {
    let area = centered_rect_fixed(OVERLAY_FIXED_SM.0, OVERLAY_FIXED_SM.1, content_area);
    frame.render_widget(Clear, area);

    let border_color = if success {
        transient_feedback_color(theme, &ToastKind::Success)
    } else {
        transient_feedback_color(theme, &ToastKind::Error)
    };
    let outer = Block::default()
        .borders(Borders::ALL)
        .border_type(BorderType::Plain)
        .border_style(Style::default().fg(border_color))
        .title(texts::tui_update_result_title());
    frame.render_widget(outer.clone(), area);
    let inner = outer.inner(area);

    let chunks = Layout::default()
        .direction(Direction::Vertical)
        .constraints([Constraint::Length(1), Constraint::Min(0)])
        .split(inner);

    let keys = if success {
        [
            ("Enter", texts::tui_key_exit()),
            ("Esc", texts::tui_key_hide()),
        ]
    } else {
        [
            ("Enter", texts::tui_key_close()),
            ("Esc", texts::tui_key_close()),
        ]
    };
    render_key_bar_center(frame, chunks[0], theme, &keys);
    let body_area = inset_top(chunks[1], 1);

    frame.render_widget(
        Paragraph::new(centered_message_lines(
            message,
            body_area.width,
            body_area.height,
        ))
        .alignment(Alignment::Center),
        body_area,
    );
}

fn render_compact_message_overlay(
    frame: &mut Frame<'_>,
    content_area: Rect,
    theme: &theme::Theme,
    title: &str,
    message: &str,
) {
    let area = compact_message_overlay_rect(content_area, title, message);
    frame.render_widget(Clear, area);
    let outer = Block::default()
        .borders(Borders::ALL)
        .border_type(BorderType::Plain)
        .border_style(overlay_border_style(theme, false))
        .title(title);
    frame.render_widget(outer.clone(), area);
    let inner = outer.inner(area);

    let chunks = Layout::default()
        .direction(Direction::Vertical)
        .constraints([Constraint::Length(1), Constraint::Min(0)])
        .split(inner);

    render_key_bar_center(frame, chunks[0], theme, &[("Esc", texts::tui_key_close())]);
    let body_area = inset_top(chunks[1], 1);
    frame.render_widget(
        Paragraph::new(centered_message_lines(
            message,
            body_area.width,
            body_area.height,
        ))
        .alignment(Alignment::Center)
        .wrap(Wrap { trim: false }),
        body_area,
    );
}

fn render_result_overlay(
    frame: &mut Frame<'_>,
    content_area: Rect,
    theme: &theme::Theme,
    compact_title: &str,
    full_title: String,
    lines: &[String],
    scroll: usize,
) {
    if should_use_compact_lines_overlay(content_area, compact_title, lines) {
        let area = compact_lines_overlay_rect(content_area, compact_title, lines);
        frame.render_widget(Clear, area);

        let outer = Block::default()
            .borders(Borders::ALL)
            .border_type(BorderType::Plain)
            .border_style(overlay_border_style(theme, false))
            .title(compact_title);
        frame.render_widget(outer.clone(), area);
        let inner = outer.inner(area);

        let chunks = Layout::default()
            .direction(Direction::Vertical)
            .constraints([Constraint::Length(1), Constraint::Min(0)])
            .split(inner);

        render_key_bar_center(frame, chunks[0], theme, &[("Esc", texts::tui_key_close())]);
        let body_area = inset_top(chunks[1], 1);
        frame.render_widget(
            Paragraph::new(centered_text_lines(
                lines,
                body_area.width,
                body_area.height,
            ))
            .alignment(Alignment::Center)
            .wrap(Wrap { trim: false }),
            body_area,
        );
        return;
    }

    let area = centered_rect(OVERLAY_LG.0, OVERLAY_LG.1, content_area);
    frame.render_widget(Clear, area);

    let outer = Block::default()
        .borders(Borders::ALL)
        .border_type(BorderType::Plain)
        .border_style(overlay_border_style(theme, false))
        .title(full_title);
    frame.render_widget(outer.clone(), area);
    let inner = outer.inner(area);

    let chunks = Layout::default()
        .direction(Direction::Vertical)
        .constraints([Constraint::Length(1), Constraint::Min(0)])
        .split(inner);

    render_key_bar_center(
        frame,
        chunks[0],
        theme,
        &[
            ("↑↓", texts::tui_key_scroll()),
            ("Esc", texts::tui_key_close()),
        ],
    );

    let body_area = inset_top(chunks[1], 1);
    let height = body_area.height as usize;
    let start = scroll.min(lines.len());
    let end = (start + height).min(lines.len());
    let shown = lines[start..end]
        .iter()
        .map(|s| Line::raw(s.clone()))
        .collect::<Vec<_>>();

    frame.render_widget(Paragraph::new(shown).wrap(Wrap { trim: false }), body_area);
}
