use super::{element_extra, tags_str, type_badge};
use crate::config::Config;
use crate::elements::Element;
use crate::store::Store;
use anyhow::Result;
use chrono::NaiveDate;
use colored::Colorize;

pub fn run(
    config: &Config,
    query: &str,
    type_filter: Option<String>,
    tag_filter: Option<String>,
    name_filter: Option<String>,
    since_date: Option<NaiveDate>,
) -> Result<()> {
    let store = Store::new(&config.storage_dir);
    let mut results = store.search(
        query,
        type_filter.as_deref(),
        tag_filter.as_deref(),
        since_date,
    )?;

    // Post-filter by --name: only character entries whose name matches are kept.
    if let Some(ref nf) = name_filter {
        let nf_lower = nf.to_lowercase();
        results.retain(|r| match &r.element {
            Element::Character { data, .. } => data
                .name
                .as_deref()
                .map(|n| n.to_lowercase() == nf_lower)
                .unwrap_or(false),
            _ => false,
        });
    }

    if results.is_empty() {
        println!("{}", format!("No results for '{}'", query).yellow());
        return Ok(());
    }

    for r in &results {
        let el = &r.element;
        let body_line = el.body_str().trim().lines().next().unwrap_or("").trim();
        let tags = tags_str(el.tags());
        let extra = element_extra(el);
        println!(
            "{} {} {}{}{}",
            r.date_str.white(),
            type_badge(&el.kind()),
            extra,
            body_line,
            tags
        );
    }

    let n = results.len();
    println!(
        "{}",
        format!("({} result{})", n, if n == 1 { "" } else { "s" }).white()
    );
    Ok(())
}
