use super::{print_tree, visible, DisplayOpts};
use crate::config::Config;
use crate::ref_resolver::RefResolver;
use crate::store::Store;
use anyhow::Result;
use chrono::NaiveDate;
use colored::Colorize;

#[allow(clippy::too_many_arguments)]
pub fn run(
    config: &Config,
    date: NaiveDate,
    dates: Vec<NaiveDate>,
    type_filter: Option<String>,
    tag_filter: Option<String>,
    status_filter: Option<String>,
    name_filter: Option<String>,
    show_refs: bool,
    all: bool,
) -> Result<()> {
    let store = Store::new(&config.storage_dir);

    // Build the list of dates to display
    let range: Vec<NaiveDate> = if all {
        store.all_file_dates()?
    } else if dates.is_empty() {
        vec![date]
    } else {
        dates
    };

    let multi = range.len() > 1;
    let opts = DisplayOpts {
        type_filter,
        tag_filter,
        status_filter,
        name_filter,
    };
    let mut total_shown = 0usize;

    for d in &range {
        let elements = store.parse_date(*d)?;
        if elements.is_empty() {
            continue;
        }

        // Build resolver once per day (only when --refs requested)
        let resolver = if show_refs {
            Some(RefResolver::new(&elements))
        } else {
            None
        };

        // Skip day entirely if no elements pass the filter
        let day_visible = elements
            .values()
            .any(|e| !e.is_mps_group() && visible(e, &opts));
        if !day_visible {
            continue;
        }

        if multi {
            println!(
                "{}",
                format!("── {} ─────────────", d.format("%Y-%m-%d")).white()
            );
        }

        total_shown += print_tree(&elements, &opts, resolver.as_ref(), show_refs);
    }

    if total_shown == 0 {
        println!("{}", "(no elements found)".yellow());
    }

    Ok(())
}
