use ratatui::layout::{Constraint, Direction, Layout, Rect};
use ratatui::text::{Line, Span};
use ratatui::widgets::{Block, Borders, Paragraph};
use ratatui::Frame;

use crate::theme::theme;

/// Create a centered rectangle by percentage of the parent area
pub fn centered_rect(percent_x: u16, percent_y: u16, r: Rect) -> Rect {
    let popup_layout = Layout::default()
        .direction(Direction::Vertical)
        .constraints([
            Constraint::Percentage((100 - percent_y) / 2),
            Constraint::Percentage(percent_y),
            Constraint::Percentage((100 - percent_y) / 2),
        ])
        .split(r);

    Layout::default()
        .direction(Direction::Horizontal)
        .constraints([
            Constraint::Percentage((100 - percent_x) / 2),
            Constraint::Percentage(percent_x),
            Constraint::Percentage((100 - percent_x) / 2),
        ])
        .split(popup_layout[1])[1]
}

/// Highlight matching substrings in text, returning borrowed spans.
/// Used for plugin names and log lines where the text outlives the frame.
pub fn highlight_match<'a>(
    text: &'a str,
    query: &str,
    base_style: ratatui::style::Style,
    highlight_style: ratatui::style::Style,
) -> Vec<Span<'a>> {
    let text_lower = text.to_lowercase();
    let terms: Vec<&str> = query.split_whitespace().collect();

    let mut best_match: Option<(usize, usize)> = None;
    for term in &terms {
        if let Some(start) = text_lower.find(term) {
            let end = start + term.len();
            best_match = Some(match best_match {
                Some((ps, pe)) => (ps.min(start), pe.max(end)),
                None => (start, end),
            });
        }
    }

    if let Some((start, end)) = best_match {
        if text.is_char_boundary(start) && text.is_char_boundary(end) {
            let mut spans = Vec::new();
            if start > 0 {
                spans.push(Span::styled(&text[..start], base_style));
            }
            spans.push(Span::styled(&text[start..end], highlight_style));
            if end < text.len() {
                spans.push(Span::styled(&text[end..], base_style));
            }
            spans
        } else {
            vec![Span::styled(text, base_style)]
        }
    } else {
        vec![Span::styled(text, base_style)]
    }
}

/// Highlight matching substrings in text, returning owned spans.
/// Used for paths where we need to format+own the string before highlighting.
pub fn highlight_match_owned(
    text: &str,
    query: &str,
    base_style: ratatui::style::Style,
    highlight_style: ratatui::style::Style,
) -> Vec<Span<'static>> {
    let text_lower = text.to_lowercase();
    let terms: Vec<&str> = query.split_whitespace().collect();

    let mut best_match: Option<(usize, usize)> = None;
    for term in &terms {
        if let Some(start) = text_lower.find(term) {
            let end = start + term.len();
            best_match = Some(match best_match {
                Some((ps, pe)) => (ps.min(start), pe.max(end)),
                None => (start, end),
            });
        }
    }

    if let Some((start, end)) = best_match {
        if text.is_char_boundary(start) && text.is_char_boundary(end) {
            let mut spans = Vec::new();
            if start > 0 {
                spans.push(Span::styled(text[..start].to_string(), base_style));
            }
            spans.push(Span::styled(text[start..end].to_string(), highlight_style));
            if end < text.len() {
                spans.push(Span::styled(text[end..].to_string(), base_style));
            }
            spans
        } else {
            vec![Span::styled(text.to_string(), base_style)]
        }
    } else {
        vec![Span::styled(text.to_string(), base_style)]
    }
}

/// Render a filter bar widget. Used by plugins, paths, and log tabs.
pub fn render_filter_bar(
    frame: &mut Frame,
    area: Rect,
    query: &str,
    is_active: bool,
    match_info: &str,
) {
    let t = theme();
    let cursor = if is_active { "█" } else { "" };
    let filter_line = Line::from(vec![
        Span::styled("  / ", t.status_bar_key),
        Span::styled(query, t.title),
        Span::styled(cursor, t.title),
        Span::styled(format!("  ({})", match_info), t.tab_inactive),
    ]);

    let border_style = if is_active {
        t.border_focused
    } else {
        t.border
    };

    let filter_bar = Paragraph::new(filter_line).block(
        Block::default()
            .borders(Borders::ALL)
            .border_style(border_style)
            .title(" Filter (Esc: clear, Enter: keep) ")
            .title_style(t.tab_inactive),
    );
    frame.render_widget(filter_bar, area);
}
