mod aliases;
mod db;
mod display;
mod export;
mod filter;
mod import;
mod shell;
mod util;

use db::{init_db, is_database_empty, load_date, load_project, load_search, load_today,
         load_week_offset, load_yesterday, prune_events, recap_dir, flush_events};
use display::{print_first_run_message, print_help, print_recap, print_search, print_stats,
              print_streak, print_timeline};
use export::{export_csv, export_json};
use import::import_history;
use shell::{install_shell_integration_auto, uninstall_shell_integration};

const VERSION: &str = env!("CARGO_PKG_VERSION");

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let dir = recap_dir();
    let conn = init_db(&dir)?;
    let imported = flush_events(&conn, &dir)?;
    if imported > 0 {
        eprintln!("✓ {} new commands recorded", imported);
    }

    let args: Vec<String> = std::env::args().collect();

    match args.get(1).map(|s| s.as_str()) {
        Some("--version") | Some("-V") => {
            println!("recap {}", VERSION);
        }
        Some("--stats") => {
            let events = load_week_offset(&conn, 0)?;
            print_stats(&events, 0);
        }
        Some("--streak") => {
            print_streak(&conn)?;
        }
        Some("--import") => {
            let n = import_history(&conn)?;
            println!("✓ {} commands imported", n);
        }
        Some("--export") => {
            let format = args.get(2).map(|s| s.as_str()).unwrap_or("json");
            match format {
                "csv" => export_csv(&conn)?,
                _ => export_json(&conn)?,
            }
        }
        Some("--timeline") => {
            let events = match args.get(2).map(|s| s.as_str()) {
                Some("--today") => load_today(&conn)?,
                Some("--date") => match args.get(3) {
                    Some(s) => match chrono::NaiveDate::parse_from_str(s, "%Y-%m-%d") {
                        Ok(date) => load_date(&conn, date)?,
                        Err(_) => {
                            println!("Invalid date format. Expected YYYY-MM-DD.");
                            return Ok(());
                        }
                    },
                    None => {
                        println!("Usage: recap --timeline --date <YYYY-MM-DD>");
                        return Ok(());
                    }
                },
                _ => load_yesterday(&conn)?,
            };
            print_timeline(&events);
        }
        Some("--today") => {
            let events = load_today(&conn)?;
            print_recap(&events);
        }
        Some("--yesterday") => {
            let events = load_yesterday(&conn)?;
            print_recap(&events);
        }
        Some("--date") => match args.get(2) {
            Some(s) => match chrono::NaiveDate::parse_from_str(s, "%Y-%m-%d") {
                Ok(date) => {
                    let events = load_date(&conn, date)?;
                    print_recap(&events);
                }
                Err(_) => println!("Invalid date format. Expected YYYY-MM-DD."),
            },
            None => println!("Usage: recap --date <YYYY-MM-DD>"),
        },
        Some("--week") => {
            let weeks: i64 = args.get(2).and_then(|s| s.parse().ok()).unwrap_or(1);
            let events = load_week_offset(&conn, weeks)?;
            print_stats(&events, weeks);
        }
        Some("--search") => {
            if let Some(query) = args.get(2) {
                let events = load_search(&conn, query)?;
                print_search(&events, query);
            } else {
                println!("Usage: recap --search <query>");
            }
        }
        Some("--project") => {
            if let Some(project) = args.get(2) {
                let events = load_project(&conn, project)?;
                print_recap(&events);
            } else {
                println!("Usage: recap --project <name>");
            }
        }
        Some("--prune") => {
            let days: i64 = args.get(2).and_then(|s| s.parse().ok()).unwrap_or(90);
            let deleted = prune_events(&conn, days)?;
            println!("✓ Deleted {} events older than {} days", deleted, days);
        }
        Some("--install") => {
            install_shell_integration_auto()?;
        }
        Some("--uninstall") => {
            uninstall_shell_integration()?;
        }
        Some("--help") | Some("-h") => {
            print_help();
        }
        _ => {
            if is_database_empty(&conn)? {
                print_first_run_message();
            } else {
                let events = load_yesterday(&conn)?;
                print_recap(&events);
            }
        }
    }

    Ok(())
}
