//! Search state types.

/// Search mode: substring (default) or regex.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum SearchMode {
    #[default]
    Substring,
    Regex,
}

impl SearchMode {
    /// Human-readable label for display in status bar.
    pub const fn label(self) -> &'static str {
        match self {
            Self::Substring => "substring",
            Self::Regex => "regex",
        }
    }
}

/// Search state for diff mode.
#[derive(Debug, Clone)]
pub struct DiffSearchState {
    pub active: bool,
    pub query: String,
    pub results: Vec<DiffSearchResult>,
    pub selected: usize,
    /// Current search mode (substring or regex).
    pub mode: SearchMode,
    /// Error message from invalid regex pattern.
    pub search_error: Option<String>,
}

impl DiffSearchState {
    pub const fn new() -> Self {
        Self {
            active: false,
            query: String::new(),
            results: Vec::new(),
            selected: 0,
            mode: SearchMode::Substring,
            search_error: None,
        }
    }

    pub fn push_char(&mut self, c: char) {
        self.query.push(c);
    }

    pub fn pop_char(&mut self) {
        self.query.pop();
    }

    pub fn select_next(&mut self) {
        if !self.results.is_empty() && self.selected < self.results.len() - 1 {
            self.selected += 1;
        }
    }

    pub const fn select_prev(&mut self) {
        if self.selected > 0 {
            self.selected -= 1;
        }
    }

    pub fn clear(&mut self) {
        self.query.clear();
        self.results.clear();
        self.selected = 0;
        self.search_error = None;
    }
}

impl Default for DiffSearchState {
    fn default() -> Self {
        Self::new()
    }
}

/// Search result for diff mode.
#[derive(Debug, Clone)]
pub enum DiffSearchResult {
    Component {
        name: String,
        version: Option<String>,
        change_type: ChangeType,
    },
    Vulnerability {
        id: String,
        component_name: String,
        severity: Option<String>,
        change_type: VulnChangeType,
    },
    License {
        license: String,
        component_name: String,
        change_type: ChangeType,
    },
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ChangeType {
    Added,
    Removed,
    Modified,
}

impl ChangeType {
    pub const fn label(self) -> &'static str {
        match self {
            Self::Added => "added",
            Self::Removed => "removed",
            Self::Modified => "modified",
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum VulnChangeType {
    Introduced,
    Resolved,
}

impl VulnChangeType {
    pub const fn label(self) -> &'static str {
        match self {
            Self::Introduced => "introduced",
            Self::Resolved => "resolved",
        }
    }
}
