use std::fs;
use std::path::PathBuf;
use std::time::{SystemTime, UNIX_EPOCH};

/// Checks if cache cleanup is needed and performs it if last cleanup was > 30 days ago
pub fn check_and_cleanup_cache() {
    if let Err(e) = try_cleanup() {
        log::debug!("Cache cleanup check failed: {e}");
    }
}

fn try_cleanup() -> Result<(), Box<dyn std::error::Error>> {
    let home_dir = dirs::home_dir().ok_or("Could not determine home directory")?;
    let cache_base = home_dir.join(".scan_crate_cache");
    
    // If cache directory doesn't exist yet, nothing to clean
    if !cache_base.exists() {
        return Ok(());
    }
    
    let last_cleanup_file = cache_base.join(".last_cleanup");
    let now = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();
    
    // Check if we need to run cleanup (once per month)
    let should_cleanup = if last_cleanup_file.exists() {
        let last_cleanup_str = fs::read_to_string(&last_cleanup_file)?;
        let last_cleanup: u64 = last_cleanup_str.trim().parse()?;
        let days_since_cleanup = (now - last_cleanup) / (24 * 60 * 60);
        days_since_cleanup >= 30
    } else {
        true // First time, do cleanup
    };
    
    if !should_cleanup {
        log::debug!("Cache cleanup not needed yet");
        return Ok(());
    }
    
    log::info!("Running monthly cache cleanup");
    
    // Clean directories older than 30 days
    let thirty_days_ago = now - (30 * 24 * 60 * 60);
    
    // Clean crates cache
    cleanup_old_directories(&cache_base.join("crates"), thirty_days_ago)?;
    
    // Clean git cache  
    cleanup_old_directories(&cache_base.join("git"), thirty_days_ago)?;
    
    // Update last cleanup timestamp
    fs::write(&last_cleanup_file, now.to_string())?;
    
    log::info!("Cache cleanup completed");
    Ok(())
}

fn cleanup_old_directories(dir: &PathBuf, older_than_timestamp: u64) -> Result<(), Box<dyn std::error::Error>> {
    if !dir.exists() {
        return Ok(());
    }
    
    let mut removed_count = 0;
    let mut kept_count = 0;
    
    for entry in fs::read_dir(dir)? {
        let entry = entry?;
        let path = entry.path();
        
        if path.is_dir() {
            // Check modification time
            let metadata = fs::metadata(&path)?;
            let modified = metadata.modified()?;
            let modified_timestamp = modified.duration_since(UNIX_EPOCH)?.as_secs();
            
            if modified_timestamp < older_than_timestamp {
                // Remove old directory
                if let Err(e) = fs::remove_dir_all(&path) {
                    log::warn!("Failed to remove old cache directory {path:?}: {e}");
                } else {
                    log::debug!("Removed old cache directory: {path:?}");
                    removed_count += 1;
                }
            } else {
                kept_count += 1;
            }
        }
    }
    
    if removed_count > 0 {
        log::info!(
            "Cleaned up {removed_count} old cache directories, kept {kept_count} recent ones in {dir:?}"
        );
    }
    
    Ok(())
}