"""
CLI commands for Metis Agent.

This module provides the command-line interface for the agent.
"""
import os
import click
from pathlib import Path
from ..core import SingleAgent
from ..tools import get_available_tools
from ..tools.filesystem import FileSystemTool
from ..tools.project_context import ProjectContextTool
from ..auth.api_key_manager import APIKeyManager
from .file_commands import files, project
from .code_commands import code
from .phase3_commands import add_git_commands, add_project_commands, add_deps_commands
from .phase4_commands import add_generate_commands


@click.group()
def cli():
    """Metis Agent CLI for building and running AI agents."""
    pass


@cli.command()
@click.argument("query", required=False)
@click.option("-i", "--interactive", is_flag=True, help="Start interactive mode")
@click.option("--tool", help="Specify a tool to use")
@click.option("--session-id", help="Session ID for context")
@click.option("--memory", is_flag=True, help="Enable Titans memory")
@click.option("--llm", default="groq", help="LLM provider to use")
@click.option("--model", help="LLM model to use")
def run(query, interactive=False, tool=None, session_id=None, memory=False, llm="groq", model=None):
    """Run an agent with a specific query or start interactive mode."""
    agent = SingleAgent(use_titans_memory=memory, llm_provider=llm, llm_model=model)
    
    if interactive or query is None:
        # Interactive mode with directory context
        current_dir = Path.cwd()
        project_tool = ProjectContextTool()
        project_summary = project_tool.get_project_summary(".")
        
        click.echo("Metis Agent Interactive Mode")
        click.echo(f"Directory: {current_dir}")
        
        # Show project context if detected
        if project_summary.get("success"):
            summary = project_summary["summary"]
            if summary["primary_language"]:
                context_info = f"Project: {summary['project_name']} ({summary['primary_language']}"
                if summary['framework']:
                    context_info += f", {summary['framework']}"
                context_info += f", {summary['file_count']} files)"
                click.echo(context_info)
        
        click.echo("Type 'exit' to quit, 'help' for commands")
        click.echo("="*50)
        
        current_session = session_id or "main"
        
        while True:
            try:
                user_input = input(f"[{current_session}] > ").strip()
                
                if not user_input:
                    continue
                    
                if user_input.lower() in ['exit', 'quit']:
                    click.echo("Goodbye!")
                    break
                    
                elif user_input.lower() == 'help':
                    click.echo("Available commands:")
                    click.echo("  help          - Show this help")
                    click.echo("  exit/quit     - Exit interactive mode")
                    click.echo("  session <id>  - Switch to session <id>")
                    click.echo("  tools         - List available tools")
                    click.echo("  ")
                    click.echo("File commands:")
                    click.echo("  ls [pattern]  - List files in directory")
                    click.echo("  cat <file>    - Display file contents")
                    click.echo("  tree [depth]  - Show directory tree")
                    click.echo("  project       - Show project summary")
                    click.echo("  ")
                    click.echo("Code intelligence:")
                    click.echo("  analyze [file] - Analyze code structure")
                    click.echo("  overview       - Show project code overview")
                    click.echo("  generate <desc> - Generate code from description")
                    click.echo("  ")
                    click.echo("  <query>       - Ask the agent a question")
                    continue
                    
                elif user_input.startswith('session '):
                    new_session = user_input[8:].strip()
                    if new_session:
                        current_session = new_session
                        click.echo(f"Switched to session: {current_session}")
                    else:
                        click.echo("Please specify a session ID")
                    continue
                    
                elif user_input.lower() == 'tools':
                    from ..tools import get_available_tools
                    available_tools = get_available_tools()
                    click.echo("Available tools:")
                    for t in available_tools:
                        click.echo(f"  - {t}")
                    continue
                
                # File system commands
                elif user_input.startswith('ls'):
                    fs_tool = FileSystemTool()
                    parts = user_input.split()
                    pattern = parts[1] if len(parts) > 1 else "*"
                    result = fs_tool.list_files(pattern=pattern)
                    if result.get("success"):
                        click.echo(f"Directory: {result['directory']}")
                        if result["directories"]:
                            for d in result["directories"]:
                                click.echo(f"📁 {d['name']}/")
                        if result["files"]:
                            for f in result["files"]:
                                size_kb = f['size'] // 1024 if f['size'] > 1024 else f['size']
                                unit = "KB" if f['size'] > 1024 else "B"
                                click.echo(f"📄 {f['name']} ({size_kb}{unit})")
                    else:
                        click.echo(f"Error: {result.get('error')}")
                    continue
                
                elif user_input.startswith('cat '):
                    fs_tool = FileSystemTool()
                    filename = user_input[4:].strip()
                    result = fs_tool.read_file(filename)
                    if result.get("success"):
                        if result.get("is_binary"):
                            click.echo(f"Binary file: {filename} ({result['size']} bytes)")
                        else:
                            click.echo(f"File: {filename}")
                            click.echo("-" * 40)
                            content = result["content"]
                            lines = content.splitlines()
                            if len(lines) > 50:
                                for i, line in enumerate(lines[:25], 1):
                                    click.echo(f"{i:3d}: {line}")
                                click.echo(f"... ({len(lines) - 50} lines omitted) ...")
                                for i, line in enumerate(lines[-25:], len(lines) - 24):
                                    click.echo(f"{i:3d}: {line}")
                            else:
                                for i, line in enumerate(lines, 1):
                                    click.echo(f"{i:3d}: {line}")
                    else:
                        click.echo(f"Error: {result.get('error')}")
                    continue
                
                elif user_input.lower() == 'tree':
                    fs_tool = FileSystemTool()
                    result = fs_tool.get_tree(max_depth=3)
                    if result.get("success"):
                        def print_tree(node, prefix="", is_last=True):
                            connector = "└── " if is_last else "├── "
                            icon = "📁" if node["type"] == "directory" else "📄"
                            click.echo(f"{prefix}{connector}{icon} {node['name']}")
                            if node["type"] == "directory" and "children" in node:
                                extension = "    " if is_last else "│   "
                                new_prefix = prefix + extension
                                children = node["children"]
                                for i, child in enumerate(children):
                                    print_tree(child, new_prefix, i == len(children) - 1)
                        print_tree(result["tree"])
                    else:
                        click.echo(f"Error: {result.get('error')}")
                    continue
                
                elif user_input.lower() == 'project':
                    project_tool = ProjectContextTool()
                    result = project_tool.get_project_summary(".")
                    if result.get("success"):
                        summary = result["summary"]
                        click.echo(f"📊 Project: {summary['project_name']}")
                        if summary['primary_language']:
                            click.echo(f"Language: {summary['primary_language']}")
                        if summary['framework']:
                            click.echo(f"Framework: {summary['framework']}")
                        click.echo(f"Files: {summary['file_count']}")
                        if summary['key_features']:
                            click.echo(f"Features: {', '.join(summary['key_features'])}")
                    else:
                        click.echo(f"Error: {result.get('error')}")
                    continue
                
                # Code intelligence commands
                elif user_input == 'overview':
                    from ..tools.code_analysis import CodeAnalysisTool
                    code_tool = CodeAnalysisTool()
                    result = code_tool.get_code_overview(".")
                    if result.get("success"):
                        summary = result.get("summary", {})
                        click.echo("Code Overview")
                        click.echo("=" * 30)
                        click.echo(f"Primary Language: {summary.get('primary_language', 'Unknown')}")
                        click.echo(f"Total Files: {summary.get('total_files', 0)}")
                        click.echo(f"Total Lines: {summary.get('total_lines', 0)}")
                        complexity = summary.get('complexity_distribution', {})
                        if complexity:
                            click.echo(f"Complexity: {complexity.get('low', 0)} low, {complexity.get('medium', 0)} medium, {complexity.get('high', 0)} high")
                    else:
                        click.echo(f"Error: {result.get('error', 'Unknown error')}")
                    continue
                
                elif user_input.startswith('analyze '):
                    from ..tools.code_analysis import CodeAnalysisTool
                    code_tool = CodeAnalysisTool()
                    filename = user_input[8:].strip()
                    result = code_tool.analyze_file(filename)
                    if result.get("success"):
                        click.echo(f"Analysis: {result.get('file_path')}")
                        click.echo("=" * 30)
                        click.echo(f"Language: {result.get('language', 'Unknown')}")
                        click.echo(f"Lines: {result.get('lines_count', 0)}")
                        click.echo(f"Complexity: {result.get('complexity_estimate', 'Unknown')}")
                        functions = result.get('functions', [])
                        if functions:
                            click.echo(f"Functions: {len(functions)}")
                        classes = result.get('classes', [])
                        if classes:
                            click.echo(f"Classes: {len(classes)}")
                    else:
                        click.echo(f"Error: {result.get('error', 'Unknown error')}")
                    continue
                
                elif user_input.startswith('generate '):
                    from ..tools.context_aware_generator import ContextAwareCodeGenerator
                    generator_tool = ContextAwareCodeGenerator()
                    description = user_input[9:].strip()
                    result = generator_tool.execute(f"generate: {description}")
                    if result.get("success"):
                        click.echo(f"Generated {result.get('language', 'Unknown')} Code:")
                        click.echo("-" * 30)
                        click.echo(result.get('code', ''))
                    else:
                        click.echo(f"Error: {result.get('error', 'Code generation failed')}")
                    continue
                
                # Process query
                result = agent.process_query(user_input, session_id=current_session, tool_name=tool)
                click.echo(f"\n{result}\n")
                
            except KeyboardInterrupt:
                click.echo("\nGoodbye!")
                break
            except EOFError:
                click.echo("\nGoodbye!")
                break
    else:
        # Direct query mode
        result = agent.process_query(query, session_id=session_id, tool_name=tool)
        click.echo(result)


@cli.command()
@click.option("--port", default=5000, help="Port to run the server on")
@click.option("--memory", is_flag=True, help="Enable Titans memory")
def serve(port, memory=False):
    """Start the web server."""
    try:
        from ..web.server import app
        click.echo(f"Starting server on port {port} with Titans memory: {memory}")
        app.config['USE_TITANS_MEMORY'] = memory
        app.run(debug=True, port=port)
    except ImportError:
        click.echo("Web server not available. Please install Flask: pip install flask")


@cli.group()
def tools():
    """Manage agent tools."""
    pass


@tools.command("list")
def list_tools():
    """List available tools."""
    tools = get_available_tools()
    click.echo("Available tools:")
    for tool in tools:
        click.echo(f"- {tool}")


@cli.group()
def tasks():
    """Manage agent tasks."""
    pass


@tasks.command("list")
@click.option("--session-id", help="Session ID to filter tasks")
def list_tasks(session_id=None):
    """List current tasks."""
    from ..core.task_manager import TaskManager
    task_file = os.path.join(os.getcwd(), "tasks.md")
    task_manager = TaskManager(task_file)
    tasks = task_manager.get_all_tasks()
    
    click.echo("Pending tasks:")
    for task in tasks["pending"]:
        click.echo(f"- [ ] {task}")
    
    click.echo("\nCompleted tasks:")
    for task in tasks["completed"]:
        click.echo(f"- [x] {task}")


@cli.group()
def memory():
    """Manage agent memory."""
    pass


@memory.command("stats")
def memory_stats():
    """Show memory statistics."""
    from ..memory.titans.titans_adapter import TitansMemoryAdapter
    from ..core.agent import SingleAgent
    
    agent = SingleAgent(use_titans_memory=True)
    insights = agent.get_memory_insights()
    
    click.echo("Memory Statistics:")
    
    if insights["adaptive_memory"]["enabled"]:
        if "insights" in insights["adaptive_memory"]:
            memory_stats = insights["adaptive_memory"]["insights"]["memory_statistics"]
            click.echo(f"- Short-term memories: {memory_stats['short_term_count']}")
            click.echo(f"- Long-term memories: {memory_stats['long_term_count']}")
            click.echo(f"- Contexts: {memory_stats['context_count']}")
            click.echo(f"- Adaptations: {memory_stats['adaptation_count']}")
            click.echo(f"- Average surprise: {memory_stats['avg_surprise_recent']:.2f}")
            
            if "recommendations" in insights["adaptive_memory"]["insights"]:
                click.echo("\nRecommendations:")
                for rec in insights["adaptive_memory"]["insights"]["recommendations"]:
                    click.echo(f"- {rec}")
        else:
            click.echo("Titans memory enabled but no insights available.")
    else:
        click.echo("Titans memory not enabled.")


@cli.group()
def auth():
    """Manage authentication and API keys."""
    pass


@auth.command("set-key")
@click.argument("service")
@click.argument("key")
def set_key(service, key):
    """Set an API key for a service."""
    key_manager = APIKeyManager()
    key_manager.set_key(service, key)
    click.echo(f"API key for {service} set successfully.")


@auth.command("list-keys")
def list_keys():
    """List all configured API keys."""
    key_manager = APIKeyManager()
    services = key_manager.list_services()
    
    if not services:
        click.echo("No API keys configured.")
        return
        
    click.echo("Configured API keys:")
    for service in services:
        click.echo(f"- {service}")


@auth.command("remove-key")
@click.argument("service")
def remove_key(service):
    """Remove an API key for a service."""
    key_manager = APIKeyManager()
    key_manager.remove_key(service)
    click.echo(f"API key for {service} removed successfully.")


@cli.command("configure-llm")
@click.option("--provider", default="openai", help="LLM provider (openai, groq, anthropic, huggingface)")
@click.option("--model", help="Model name")
def configure_llm(provider, model):
    """Configure the LLM to use."""
    from ..core.llm_interface import configure_llm
    from ..auth.api_key_manager import APIKeyManager
    
    key_manager = APIKeyManager()
    api_key = key_manager.get_key(provider)
    
    if not api_key:
        api_key = click.prompt(f"Enter API key for {provider}", hide_input=True)
        key_manager.set_key(provider, api_key)
    
    configure_llm(provider, model, api_key)
    click.echo(f"LLM configured: {provider}" + (f" ({model})" if model else ""))


# Add command groups
cli.add_command(files)
cli.add_command(project)
cli.add_command(code)

# Add Phase 3 command groups
add_git_commands(cli)
add_project_commands(cli)
add_deps_commands(cli)

# Add Phase 4 command groups
add_generate_commands(cli)


if __name__ == "__main__":
    cli()