"""
CLI commands for code intelligence features.

This module provides CLI commands for code analysis, generation, and context-aware
development assistance.
"""
import click
from pathlib import Path
from ..tools.code_analysis import CodeAnalysisTool
from ..tools.context_aware_generator import ContextAwareCodeGenerator


@click.group()
def code():
    """Code intelligence and generation commands."""
    pass


@code.command()
@click.argument('file_path', required=False)
@click.option('--project', '-p', is_flag=True, help='Analyze entire project')
@click.option('--overview', '-o', is_flag=True, help='Show code overview')
@click.option('--dependencies', '-d', is_flag=True, help='Show dependencies')
def analyze(file_path, project, overview, dependencies):
    """Analyze code structure and patterns."""
    tool = CodeAnalysisTool()
    
    try:
        if dependencies:
            result = tool.analyze_dependencies(".")
            if result.get("success"):
                click.echo("Dependency Analysis")
                click.echo("=" * 50)
                
                internal = result.get("internal_imports", [])
                external = result.get("external_imports", [])
                
                if external:
                    click.echo(f"\nExternal Dependencies ({len(external)}):")
                    for dep in external[:10]:  # Show top 10
                        click.echo(f"  - {dep}")
                    if len(external) > 10:
                        click.echo(f"  ... and {len(external) - 10} more")
                
                if internal:
                    click.echo(f"\nInternal Imports ({len(internal)}):")
                    for dep in internal[:10]:  # Show top 10
                        click.echo(f"  - {dep}")
                    if len(internal) > 10:
                        click.echo(f"  ... and {len(internal) - 10} more")
                        
            else:
                click.echo(f"Error: {result.get('error', 'Unknown error')}")
        
        elif overview:
            result = tool.get_code_overview(".")
            if result.get("success"):
                summary = result.get("summary", {})
                click.echo("Code Overview")
                click.echo("=" * 50)
                
                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)}")
                
                languages = summary.get('languages_used', [])
                if languages:
                    click.echo(f"Languages: {', '.join(languages)}")
                
                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")
                
                patterns = summary.get('patterns', [])
                if patterns:
                    click.echo("\nProject Patterns:")
                    for pattern in patterns[:5]:
                        click.echo(f"  - {pattern}")
                        
            else:
                click.echo(f"Error: {result.get('error', 'Unknown error')}")
        
        elif project:
            result = tool.analyze_project(".")
            if result.get("success"):
                click.echo(" Project Analysis")
                click.echo("=" * 50)
                
                click.echo(f" Directory: {result.get('directory', '.')}")
                click.echo(f" Total Files: {result.get('total_files', 0)}")
                click.echo(f" Total Lines: {result.get('total_lines', 0)}")
                
                languages = result.get('languages', {})
                if languages:
                    click.echo(f"\n Languages:")
                    for lang, count in languages.items():
                        click.echo(f"   {lang}: {count} files")
                
                complexity = result.get('complexity_summary', {})
                if complexity:
                    click.echo(f"\n Complexity Distribution:")
                    for level, count in complexity.items():
                        if count > 0:
                            click.echo(f"   {level}: {count} files")
                
                common_imports = result.get('common_imports', {})
                if common_imports:
                    click.echo(f"\n Most Common Imports:")
                    for imp, count in sorted(common_imports.items(), key=lambda x: x[1], reverse=True)[:5]:
                        click.echo(f"   {imp}: {count} files")
                        
            else:
                click.echo(f"Error: {result.get('error', 'Unknown error')}")
        
        elif file_path:
            result = tool.analyze_file(file_path)
            if result.get("success"):
                click.echo(f" Analysis: {result.get('file_path')}")
                click.echo("=" * 50)
                
                click.echo(f" Language: {result.get('language', 'Unknown')}")
                click.echo(f" Lines: {result.get('lines_count', 0)}")
                click.echo(f" Size: {result.get('size_bytes', 0)} bytes")
                click.echo(f" Complexity: {result.get('complexity_estimate', 'Unknown')}")
                
                functions = result.get('functions', [])
                if functions:
                    click.echo(f"\n Functions ({len(functions)}):")
                    for func in functions:
                        name = func.get('name', 'Unknown')
                        line = func.get('line_number', '?')
                        args = func.get('args_count', 0)
                        click.echo(f"   {name}() - Line {line} ({args} args)")
                
                classes = result.get('classes', [])
                if classes:
                    click.echo(f"\n Classes ({len(classes)}):")
                    for cls in classes:
                        name = cls.get('name', 'Unknown')
                        line = cls.get('line_number', '?')
                        methods = len(cls.get('methods', []))
                        click.echo(f"   {name} - Line {line} ({methods} methods)")
                
                imports = result.get('imports', [])
                if imports:
                    click.echo(f"\n Imports ({len(imports)}):")
                    for imp in imports[:10]:  # Show first 10
                        if imp.get('type') == 'import':
                            click.echo(f"   import {imp.get('module', '')}")
                        else:
                            click.echo(f"   from {imp.get('module', '')} import {imp.get('name', '')}")
                    if len(imports) > 10:
                        click.echo(f"  ... and {len(imports) - 10} more")
                        
            else:
                click.echo(f"Error: {result.get('error', 'Unknown error')}")
        
        else:
            # Default to project overview
            result = tool.get_code_overview(".")
            if result.get("success"):
                summary = result.get("summary", {})
                click.echo(" Quick Code Overview")
                click.echo("=" * 30)
                click.echo(f" Language: {summary.get('primary_language', 'Unknown')}")
                click.echo(f" Files: {summary.get('total_files', 0)}")
                click.echo(f" Lines: {summary.get('total_lines', 0)}")
                
                click.echo(f"\n Use 'metis code analyze --project' for detailed analysis")
            else:
                click.echo(f"Error: {result.get('error', 'Unknown error')}")
                
    except Exception as e:
        click.echo(f" Error analyzing code: {str(e)}")


@code.command()
@click.argument('description')
@click.option('--type', '-t', type=click.Choice(['function', 'class', 'test', 'docs']), 
              help='Type of code to generate')
@click.option('--language', '-l', type=str, help='Target language (auto-detected if not specified)')
@click.option('--file', '-f', type=str, help='Output file path')
@click.option('--show-context', is_flag=True, help='Show project context used for generation')
def generate(description, type, language, file, show_context):
    """Generate code based on description and project context."""
    tool = ContextAwareCodeGenerator()
    
    try:
        # Prepare the task with type prefix if specified
        if type:
            task = f"generate {type}: {description}"
        else:
            task = f"generate: {description}"
        
        result = tool.execute(task)
        
        if result.get("success"):
            click.echo(f" Generated {result.get('language', 'Unknown')} Code")
            click.echo("=" * 50)
            
            # Show context if requested
            if show_context:
                context_used = result.get("context_used", {})
                if context_used:
                    click.echo(" Context Used:")
                    
                    imports = context_used.get("common_imports", [])
                    if imports:
                        click.echo(f"   Common imports: {', '.join(imports)}")
                    
                    style = context_used.get("coding_style", {})
                    if style:
                        click.echo(f"   Code style: {style.get('indentation', '4 spaces')}")
                    
                    patterns = context_used.get("project_patterns", [])
                    if patterns:
                        click.echo(f"   Project patterns: {', '.join(patterns)}")
                    
                    click.echo()
            
            # Show imports if any
            imports = result.get("imports", [])
            if imports:
                click.echo(" Required Imports:")
                for imp in imports:
                    click.echo(f"  {imp}")
                click.echo()
            
            # Show the generated code
            click.echo(" Generated Code:")
            click.echo("-" * 30)
            code = result.get("code", "")
            click.echo(code)
            
            # Save to file if requested
            if file:
                try:
                    Path(file).parent.mkdir(parents=True, exist_ok=True)
                    with open(file, 'w', encoding='utf-8') as f:
                        if imports:
                            f.write('\n'.join(imports) + '\n\n')
                        f.write(code)
                    click.echo(f"\n Code saved to: {file}")
                except Exception as e:
                    click.echo(f" Error saving file: {str(e)}")
            
            # Show additional info
            if result.get("function_name"):
                click.echo(f"\n Function: {result.get('function_name')}")
            if result.get("class_name"):
                click.echo(f" Class: {result.get('class_name')}")
            if result.get("methods_generated"):
                click.echo(f" Methods: {result.get('methods_generated')}")
                
        else:
            click.echo(f" Error: {result.get('error', 'Code generation failed')}")
            
    except Exception as e:
        click.echo(f" Error generating code: {str(e)}")


@code.command()
@click.argument('target', required=False)
@click.option('--project', '-p', is_flag=True, help='Generate documentation for entire project')
@click.option('--format', '-f', type=click.Choice(['markdown', 'rst', 'txt']), 
              default='markdown', help='Documentation format')
@click.option('--output', '-o', type=str, help='Output file path')
def docs(target, project, format, output):
    """Generate documentation for code or project."""
    tool = ContextAwareCodeGenerator()
    
    try:
        if project:
            task = "generate project documentation"
        elif target:
            task = f"generate documentation for {target}"
        else:
            task = "generate project documentation"
        
        result = tool.execute(task)
        
        if result.get("success"):
            click.echo(" Generated Documentation")
            click.echo("=" * 50)
            
            doc_content = result.get("documentation", "")
            if doc_content:
                click.echo(doc_content)
                
                # Save to file if requested or suggested
                output_file = output or result.get("filename", "documentation.md")
                if output_file:
                    try:
                        Path(output_file).parent.mkdir(parents=True, exist_ok=True)
                        with open(output_file, 'w', encoding='utf-8') as f:
                            f.write(doc_content)
                        click.echo(f"\n Documentation saved to: {output_file}")
                    except Exception as e:
                        click.echo(f" Error saving documentation: {str(e)}")
            else:
                click.echo(" No documentation content generated")
                
        else:
            click.echo(f" Error: {result.get('error', 'Documentation generation failed')}")
            
    except Exception as e:
        click.echo(f" Error generating documentation: {str(e)}")


@code.command()
@click.argument('file_or_code', required=False)
@click.option('--suggestions', '-s', is_flag=True, help='Show refactoring suggestions')
def refactor(file_or_code, suggestions):
    """Get refactoring suggestions for code."""
    tool = ContextAwareCodeGenerator()
    
    try:
        if file_or_code:
            task = f"suggest refactoring for {file_or_code}"
        else:
            task = "suggest refactoring for current project"
        
        result = tool.execute(task)
        
        if result.get("success"):
            click.echo(" Refactoring Suggestions")
            click.echo("=" * 50)
            
            suggestions_list = result.get("suggestions", [])
            if suggestions_list:
                for i, suggestion in enumerate(suggestions_list, 1):
                    click.echo(f"{i}. {suggestion}")
            
            priority = result.get("priority", "medium")
            effort = result.get("estimated_effort", "unknown")
            
            click.echo(f"\n Priority: {priority.title()}")
            click.echo(f" Estimated Effort: {effort}")
            
        else:
            click.echo(f" Error: {result.get('error', 'Refactoring analysis failed')}")
            
    except Exception as e:
        click.echo(f" Error analyzing refactoring: {str(e)}")


@code.command()
@click.option('--interactive', '-i', is_flag=True, help='Start interactive code exploration')
def explore(interactive):
    """Explore codebase with context-aware assistance."""
    if interactive:
        click.echo(" Interactive Code Explorer")
        click.echo("=" * 50)
        click.echo("Type commands or questions about your code:")
        click.echo("   'analyze <file>' - Analyze specific file")
        click.echo("   'generate <description>' - Generate code")
        click.echo("   'help' - Show help")
        click.echo("   'exit' - Exit explorer")
        click.echo()
        
        # Simple interactive loop
        analysis_tool = CodeAnalysisTool()
        generator_tool = ContextAwareCodeGenerator()
        
        while True:
            try:
                user_input = click.prompt("code> ", type=str, show_default=False)
                
                if user_input.lower() in ['exit', 'quit']:
                    break
                elif user_input.lower() == 'help':
                    click.echo("Available commands:")
                    click.echo("  analyze <file> - Analyze file")
                    click.echo("  generate <desc> - Generate code")
                    click.echo("  overview - Project overview")
                    click.echo("  exit - Exit explorer")
                elif user_input.lower().startswith('analyze '):
                    file_path = user_input[8:].strip()
                    result = analysis_tool.analyze_file(file_path)
                    if result.get("success"):
                        click.echo(f" {file_path}: {result.get('lines_count', 0)} lines, {len(result.get('functions', []))} functions")
                    else:
                        click.echo(f" {result.get('error', 'Analysis failed')}")
                elif user_input.lower().startswith('generate '):
                    description = user_input[9:].strip()
                    result = generator_tool.execute(f"generate: {description}")
                    if result.get("success"):
                        click.echo(f" Generated {result.get('language', 'code')}:")
                        click.echo(result.get('code', ''))
                    else:
                        click.echo(f" {result.get('error', 'Generation failed')}")
                elif user_input.lower() == 'overview':
                    result = analysis_tool.get_code_overview(".")
                    if result.get("success"):
                        summary = result.get("summary", {})
                        click.echo(f" {summary.get('total_files', 0)} files, {summary.get('total_lines', 0)} lines")
                        click.echo(f" Primary: {summary.get('primary_language', 'Unknown')}")
                    else:
                        click.echo(f" {result.get('error', 'Overview failed')}")
                else:
                    click.echo(" Unknown command. Type 'help' for available commands.")
                    
            except KeyboardInterrupt:
                break
            except EOFError:
                break
        
        click.echo("\n Goodbye!")
    else:
        # Non-interactive exploration - show project overview
        tool = CodeAnalysisTool()
        result = tool.get_code_overview(".")
        
        if result.get("success"):
            summary = result.get("summary", {})
            click.echo(" Code Exploration")
            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)}")
            
            click.echo(f"\n Use 'metis code explore --interactive' for interactive exploration")
        else:
            click.echo(f" Error: {result.get('error', 'Unknown error')}")


# Export the command group
__all__ = ['code']
