use std::time::Duration;

use ratatui::{
    buffer::Buffer,
    layout::Rect,
    style::{Modifier, Style},
    text::{Line, Span},
    widgets::{Paragraph, Widget},
};

use crate::engine::{EngineFlags, EngineKind};
use crate::input::vim::VimMode;
use crate::ui::theme;

pub fn format_duration(d: Duration) -> String {
    let micros = d.as_micros();
    if micros < 1000 {
        format!("{micros}\u{03bc}s")
    } else {
        format!("{:.1}ms", micros as f64 / 1000.0)
    }
}

pub struct StatusBar {
    pub engine: EngineKind,
    pub match_count: usize,
    pub flags: EngineFlags,
    pub show_whitespace: bool,
    pub compile_time: Option<Duration>,
    pub match_time: Option<Duration>,
    pub vim_mode: Option<VimMode>,
    /// Non-None when the active engine has a known security advisory.
    pub engine_warning: Option<&'static str>,
}

impl Widget for StatusBar {
    fn render(self, area: Rect, buf: &mut Buffer) {
        let mut spans = Vec::new();

        if let Some(mode) = self.vim_mode {
            let (mode_text, mode_bg) = match mode {
                VimMode::Insert => (" INSERT ", theme::GREEN),
                VimMode::Normal => (" NORMAL ", theme::BLUE),
            };
            spans.push(Span::styled(
                mode_text,
                Style::default()
                    .fg(theme::BASE)
                    .bg(mode_bg)
                    .add_modifier(Modifier::BOLD),
            ));
            spans.push(Span::styled(" ", Style::default().bg(theme::SURFACE0)));
        }

        spans.push(Span::styled(
            format!(" {} ", self.engine),
            Style::default()
                .fg(theme::BASE)
                .bg(theme::BLUE)
                .add_modifier(Modifier::BOLD),
        ));
        if let Some(warning) = self.engine_warning {
            spans.push(Span::styled(" ", Style::default().bg(theme::SURFACE0)));
            spans.push(Span::styled(
                format!(" \u{26a0} {warning} "),
                Style::default()
                    .fg(theme::BASE)
                    .bg(theme::RED)
                    .add_modifier(Modifier::BOLD),
            ));
        }
        spans.push(Span::styled(" ", Style::default().bg(theme::SURFACE0)));
        spans.push(Span::styled(
            format!(
                " {} match{} ",
                self.match_count,
                if self.match_count == 1 { "" } else { "es" }
            ),
            Style::default().fg(theme::TEXT).bg(theme::SURFACE0),
        ));
        spans.push(Span::styled(" ", Style::default().bg(theme::SURFACE0)));

        // Timing info
        if self.compile_time.is_some() || self.match_time.is_some() {
            let mut parts = Vec::new();
            if let Some(ct) = self.compile_time {
                parts.push(format!("compile: {}", format_duration(ct)));
            }
            if let Some(mt) = self.match_time {
                parts.push(format!("match: {}", format_duration(mt)));
            }
            spans.push(Span::styled(
                format!("{} ", parts.join(" | ")),
                Style::default().fg(theme::SUBTEXT).bg(theme::SURFACE0),
            ));
        }

        // Flag indicators
        let flags = [
            ("i", self.flags.case_insensitive),
            ("m", self.flags.multi_line),
            ("s", self.flags.dot_matches_newline),
            ("u", self.flags.unicode),
            ("x", self.flags.extended),
        ];

        for (name, active) in &flags {
            let style = if *active {
                Style::default()
                    .fg(theme::BASE)
                    .bg(theme::GREEN)
                    .add_modifier(Modifier::BOLD)
            } else {
                Style::default().fg(theme::OVERLAY).bg(theme::SURFACE0)
            };
            spans.push(Span::styled(format!(" {name} "), style));
        }

        if self.show_whitespace {
            spans.push(Span::styled(
                " \u{00b7} ",
                Style::default()
                    .fg(theme::BASE)
                    .bg(theme::TEAL)
                    .add_modifier(Modifier::BOLD),
            ));
        }

        spans.push(Span::styled(
            " | Tab: switch | Ctrl+E: engine | Ctrl+W: ws | F1: help ",
            Style::default().fg(theme::SUBTEXT).bg(theme::SURFACE0),
        ));

        let line = Line::from(spans);
        let paragraph = Paragraph::new(line).style(Style::default().bg(theme::SURFACE0));
        paragraph.render(area, buf);
    }
}
