//! Simple CLI to test aurora-semantic functionality
//!
//! Usage:
//!   test_cli --index-dir <path> index <workspace_path>
//!   test_cli --index-dir <path> search <workspace_path> <query>
//!   test_cli --index-dir <path> list
//!   test_cli --index-dir <path> stats <workspace_path>
//!   test_cli --index-dir <path> delete <workspace_path>
//!   test_cli --index-dir <path> files <workspace_path>  -- List indexed files

use aurora_semantic::{Engine, EngineConfig, WorkspaceConfig, SearchQuery};
use std::path::PathBuf;
use std::env;

fn get_default_index_dir() -> PathBuf {
    // Default: Use a test directory in temp
    let temp_dir = env::temp_dir().join("aurora_semantic_test");
    std::fs::create_dir_all(&temp_dir).expect("Failed to create test directory");
    temp_dir
}

fn parse_index_dir(args: &[String]) -> (PathBuf, usize) {
    // Check for --index-dir or -d flag
    for (i, arg) in args.iter().enumerate() {
        if (arg == "--index-dir" || arg == "-d") && i + 1 < args.len() {
            let dir = PathBuf::from(&args[i + 1]);
            return (dir, i + 2); // Skip the flag and its value
        }
    }
    (get_default_index_dir(), 1) // Start from index 1 (skip program name)
}

#[tokio::main]
async fn main() {
    let args: Vec<String> = env::args().collect();
    
    if args.len() < 2 {
        print_usage();
        return;
    }

    let (index_dir, cmd_start) = parse_index_dir(&args);
    
    if cmd_start >= args.len() {
        print_usage();
        return;
    }
    
    let command = &args[cmd_start];
    let remaining_args: Vec<&String> = args[cmd_start..].iter().collect();
    
    println!("=== Aurora Semantic Test CLI ===");
    println!("Index directory: {}", index_dir.display());
    println!();

    match command.as_str() {
        "index" => {
            if remaining_args.len() < 2 {
                println!("Error: Missing workspace path");
                println!("Usage: test_cli [--index-dir <path>] index <workspace_path>");
                return;
            }
            let workspace_path = PathBuf::from(remaining_args[1]);
            index_workspace(&index_dir, &workspace_path).await;
        }
        "search" => {
            if remaining_args.len() < 3 {
                println!("Error: Missing workspace path or query");
                println!("Usage: test_cli [--index-dir <path>] search <workspace_path> <query>");
                return;
            }
            let workspace_path = PathBuf::from(remaining_args[1]);
            let query = remaining_args[2];
            search_workspace(&index_dir, &workspace_path, query).await;
        }
        "list" => {
            list_workspaces(&index_dir);
        }
        "stats" => {
            if remaining_args.len() < 2 {
                println!("Error: Missing workspace path");
                println!("Usage: test_cli [--index-dir <path>] stats <workspace_path>");
                return;
            }
            let workspace_path = PathBuf::from(remaining_args[1]);
            show_stats(&index_dir, &workspace_path);
        }
        "files" => {
            if remaining_args.len() < 2 {
                println!("Error: Missing workspace path");
                println!("Usage: test_cli [--index-dir <path>] files <workspace_path>");
                return;
            }
            let workspace_path = PathBuf::from(remaining_args[1]);
            list_indexed_files(&index_dir, &workspace_path);
        }
        "delete" => {
            if remaining_args.len() < 2 {
                println!("Error: Missing workspace path");
                println!("Usage: test_cli [--index-dir <path>] delete <workspace_path>");
                return;
            }
            let workspace_path = PathBuf::from(remaining_args[1]);
            delete_workspace(&index_dir, &workspace_path);
        }
        "clean" => {
            clean_all(&index_dir);
        }
        _ => {
            println!("Unknown command: {}", command);
            print_usage();
        }
    }
}

fn print_usage() {
    println!("Aurora Semantic Test CLI");
    println!();
    println!("Options:");
    println!("  --index-dir, -d <path>         Set index directory (default: temp)");
    println!("  --model, -m <path>             Set embedding model path");
    println!();
    println!("Commands:");
    println!("  index <workspace_path>         Index a workspace");
    println!("  search <workspace_path> <q>    Search in a workspace");
    println!("  list                           List all indexed workspaces");
    println!("  stats <workspace_path>         Show workspace statistics");
    println!("  files <workspace_path>         List indexed files by extension");
    println!("  delete <workspace_path>        Delete workspace index");
    println!("  clean                          Delete all indexes");
    println!();
    println!("Example:");
    println!("  test_cli -d C:\\Users\\Alvan\\AppData\\Roaming\\aurora_agent\\semantic -m E:\\aurora-semantic-model list");
}

async fn index_workspace(index_dir: &PathBuf, workspace_path: &PathBuf) {
    println!("Indexing workspace: {}", workspace_path.display());
    
    if !workspace_path.exists() {
        println!("Error: Workspace path does not exist");
        return;
    }

    let config = EngineConfig::new(index_dir.clone());
    let engine = match Engine::new(config) {
        Ok(e) => e,
        Err(e) => {
            println!("Error creating engine: {}", e);
            return;
        }
    };

    let ws_config = WorkspaceConfig::new(workspace_path.clone());
    
    // Progress callback
    let progress_callback = Box::new(|progress: aurora_semantic::IndexProgress| {
        let phase = match progress.phase {
            aurora_semantic::IndexPhase::Scanning => "Scanning",
            aurora_semantic::IndexPhase::Parsing => "Parsing",
            aurora_semantic::IndexPhase::Embedding => "Embedding",
            aurora_semantic::IndexPhase::Indexing => "Indexing",
            aurora_semantic::IndexPhase::Persisting => "Persisting",
            aurora_semantic::IndexPhase::Complete => "Complete",
        };
        
        if let Some(file) = &progress.current_file {
            println!("  [{:10}] {}/{} - {}", phase, progress.processed, progress.total, file.display());
        } else {
            println!("  [{:10}] {}/{}", phase, progress.processed, progress.total);
        }
    });

    println!();
    match engine.index_or_reindex_workspace(ws_config, Some(progress_callback)).await {
        Ok(workspace_id) => {
            println!();
            println!("SUCCESS! Workspace indexed with ID: {}", workspace_id);
            
            // Show stats
            if let Ok(stats) = engine.get_workspace_stats(&workspace_id) {
                println!();
                println!("Statistics:");
                println!("  Documents: {}", stats.document_count);
                println!("  Chunks: {}", stats.chunk_count);
                println!("  Total bytes: {}", stats.total_bytes);
            }
        }
        Err(e) => {
            println!();
            println!("ERROR: Indexing failed: {}", e);
        }
    }
}

async fn search_workspace(index_dir: &PathBuf, workspace_path: &PathBuf, query: &str) {
    println!("Searching in workspace: {}", workspace_path.display());
    println!("Query: {}", query);
    println!();

    let config = EngineConfig::new(index_dir.clone());
    let engine = match Engine::new(config) {
        Ok(e) => e,
        Err(e) => {
            println!("Error creating engine: {}", e);
            return;
        }
    };

    // Find workspace by path
    let workspace_id = match engine.find_workspace_by_path(workspace_path) {
        Ok(Some(id)) => id,
        Ok(None) => {
            println!("Error: Workspace not found. Please index it first.");
            return;
        }
        Err(e) => {
            println!("Error finding workspace: {}", e);
            return;
        }
    };

    println!("Found workspace ID: {}", workspace_id);

    // Load workspace
    if let Err(e) = engine.load_workspace(&workspace_id) {
        println!("Error loading workspace: {}", e);
        return;
    }

    // Search
    let search_query = SearchQuery::new(query).limit(10);
    
    match engine.search(&workspace_id, search_query) {
        Ok(results) => {
            println!();
            println!("Found {} results:", results.len());
            println!();
            
            for (i, result) in results.iter().enumerate() {
                println!("{}. {} (score: {:.3})", i + 1, result.document.relative_path.display(), result.score);
                println!("   Lines {}-{}", result.chunk.start_line, result.chunk.end_line);
                if let Some(ref symbol) = result.chunk.symbol_name {
                    println!("   Symbol: {}", symbol);
                }
                println!("   Type: {:?}", result.chunk.chunk_type);
                
                // Show first 200 chars of content
                let content_preview: String = result.chunk.content.chars().take(200).collect();
                let content_preview = content_preview.replace('\n', " ").replace('\r', "");
                println!("   Preview: {}...", content_preview);
                println!();
            }
        }
        Err(e) => {
            println!("Error searching: {}", e);
        }
    }
}

fn list_workspaces(index_dir: &PathBuf) {
    println!("Listing all indexed workspaces...");
    println!();

    let config = EngineConfig::new(index_dir.clone());
    let engine = match Engine::new(config) {
        Ok(e) => e,
        Err(e) => {
            println!("Error creating engine: {}", e);
            return;
        }
    };

    match engine.list_workspaces() {
        Ok(workspaces) => {
            if workspaces.is_empty() {
                println!("No workspaces indexed.");
            } else {
                println!("Found {} workspace(s):", workspaces.len());
                println!();
                
                for ws_id in workspaces {
                    println!("  ID: {}", ws_id);
                    if let Ok(stats) = engine.get_workspace_stats(&ws_id) {
                        println!("    Path: {}", stats.root_path.display());
                        println!("    Documents: {}", stats.document_count);
                        println!("    Chunks: {}", stats.chunk_count);
                    }
                    println!();
                }
            }
        }
        Err(e) => {
            println!("Error listing workspaces: {}", e);
        }
    }
}

fn show_stats(index_dir: &PathBuf, workspace_path: &PathBuf) {
    println!("Getting stats for workspace: {}", workspace_path.display());
    println!();

    let config = EngineConfig::new(index_dir.clone());
    let engine = match Engine::new(config) {
        Ok(e) => e,
        Err(e) => {
            println!("Error creating engine: {}", e);
            return;
        }
    };

    // Find workspace by path
    let workspace_id = match engine.find_workspace_by_path(workspace_path) {
        Ok(Some(id)) => id,
        Ok(None) => {
            println!("Error: Workspace not found. Please index it first.");
            return;
        }
        Err(e) => {
            println!("Error finding workspace: {}", e);
            return;
        }
    };

    match engine.get_workspace_stats(&workspace_id) {
        Ok(stats) => {
            println!("Workspace Statistics:");
            println!("  ID: {}", stats.workspace_id);
            println!("  Root path: {}", stats.root_path.display());
            println!("  Documents: {}", stats.document_count);
            println!("  Chunks: {}", stats.chunk_count);
            println!("  Total bytes: {}", stats.total_bytes);
            println!("  Index size: {} bytes", stats.index_size_bytes);
            println!("  Created: {}", stats.created_at);
            println!("  Updated: {}", stats.updated_at);
            
            if !stats.language_stats.is_empty() {
                println!();
                println!("  Languages:");
                for lang_stat in &stats.language_stats {
                    println!("    {:?}: {} files, {} chunks", 
                        lang_stat.language, 
                        lang_stat.file_count,
                        lang_stat.chunk_count
                    );
                }
            }
        }
        Err(e) => {
            println!("Error getting stats: {}", e);
        }
    }
}

fn delete_workspace(index_dir: &PathBuf, workspace_path: &PathBuf) {
    println!("Deleting workspace: {}", workspace_path.display());

    let config = EngineConfig::new(index_dir.clone());
    let engine = match Engine::new(config) {
        Ok(e) => e,
        Err(e) => {
            println!("Error creating engine: {}", e);
            return;
        }
    };

    // Find workspace by path
    let workspace_id = match engine.find_workspace_by_path(workspace_path) {
        Ok(Some(id)) => id,
        Ok(None) => {
            println!("Error: Workspace not found.");
            return;
        }
        Err(e) => {
            println!("Error finding workspace: {}", e);
            return;
        }
    };

    match engine.delete_workspace(&workspace_id) {
        Ok(_) => {
            println!("SUCCESS! Workspace deleted.");
        }
        Err(e) => {
            println!("Error deleting workspace: {}", e);
        }
    }
}

fn clean_all(index_dir: &PathBuf) {
    println!("Cleaning all indexes in: {}", index_dir.display());
    
    if index_dir.exists() {
        match std::fs::remove_dir_all(index_dir) {
            Ok(_) => {
                println!("SUCCESS! All indexes deleted.");
            }
            Err(e) => {
                println!("Error: {}", e);
            }
        }
    } else {
        println!("Index directory does not exist.");
    }
}

fn list_indexed_files(index_dir: &PathBuf, workspace_path: &PathBuf) {
    println!("Listing indexed files for: {}", workspace_path.display());
    println!();
    
    // Just show stats with language breakdown - get_all_documents not available
    show_stats(index_dir, workspace_path);
}

