"""CLI entry point for ISNAD Skill Scanner."""
import json
import sys
from typing import Optional

import click
from rich.console import Console
from rich.table import Table
from rich.panel import Panel
from rich.text import Text

from . import __version__
from .scanner import scan_skill, ScanResult
from .patterns import Severity


console = Console()


def format_severity(severity: Severity) -> Text:
    """Format severity with color."""
    colors = {
        Severity.DANGER: "red bold",
        Severity.WARN: "yellow",
        Severity.INFO: "blue",
    }
    return Text(severity.value.upper(), style=colors.get(severity, "white"))


def format_trust_level(level: str) -> Text:
    """Format trust level with color and emoji."""
    config = {
        "DANGER": ("🚨", "red bold"),
        "WARN": ("⚠️ ", "yellow bold"),
        "CAUTION": ("⚡", "yellow"),
        "SAFE": ("✅", "green bold"),
    }
    emoji, style = config.get(level, ("", "white"))
    return Text(f"{emoji} {level}", style=style)


def print_result(result: ScanResult, verbose: bool = False, show_hash: bool = False):
    """Print scan result in human-readable format."""
    console.print()
    
    # Header with trust level
    level_text = format_trust_level(result.trust_level)
    console.print(Panel(
        Text.assemble("Trust Level: ", level_text),
        title=f"[bold]ISNAD Scan: {result.path}[/bold]",
        border_style="blue"
    ))
    
    # Summary stats
    summary = result.summary()
    console.print(f"\n📁 Files scanned: {summary['files_scanned']}")
    console.print(f"⏭️  Files skipped: {summary['files_skipped']}")
    
    if show_hash and result.content_hash:
        console.print(f"🔑 Content hash: {result.content_hash}")
    
    # Findings summary
    findings = summary['findings']
    if findings['danger'] > 0:
        console.print(f"🚨 [red bold]DANGER findings: {findings['danger']}[/red bold]")
    if findings['warn'] > 0:
        console.print(f"⚠️  [yellow]WARN findings: {findings['warn']}[/yellow]")
    if findings['info'] > 0 and verbose:
        console.print(f"ℹ️  [blue]INFO findings: {findings['info']}[/blue]")
    
    # Symlinks
    if result.symlinks_found:
        console.print(f"🔗 [red]Unsafe symlinks: {len(result.symlinks_found)}[/red]")
    
    # Warnings
    if result.warnings and verbose:
        console.print(f"⚡ Warnings: {len(result.warnings)}")
    
    # Detailed findings grouped by severity
    if result.findings:
        console.print("\n[bold]Findings:[/bold]\n")
        
        # Group and sort by severity
        for severity in [Severity.DANGER, Severity.WARN, Severity.INFO]:
            severity_findings = [f for f in result.findings if f.severity == severity]
            
            if not severity_findings:
                continue
            
            if severity == Severity.INFO and not verbose:
                continue
            
            # Deduplicate similar findings
            seen_patterns = {}
            for finding in severity_findings:
                key = (finding.pattern_id, finding.file)
                if key not in seen_patterns:
                    seen_patterns[key] = []
                seen_patterns[key].append(finding)
            
            for (pattern_id, file), file_findings in seen_patterns.items():
                sev_text = format_severity(file_findings[0].severity)
                
                if len(file_findings) == 1:
                    f = file_findings[0]
                    console.print(Text.assemble(
                        "[", sev_text, "] ",
                        f"{f.file}:{f.line} — ",
                        (f.pattern_id, "cyan"),
                    ))
                    console.print(f"    {f.description}")
                    if f.context and verbose:
                        console.print(f"    [dim]{f.context}[/dim]")
                else:
                    # Multiple occurrences
                    lines = [str(f.line) for f in file_findings[:5]]
                    line_str = ",".join(lines) + ("..." if len(file_findings) > 5 else "")
                    console.print(Text.assemble(
                        "[", sev_text, "] ",
                        f"{file}:{{{line_str}}} — ",
                        (pattern_id, "cyan"),
                        f" ({len(file_findings)} occurrences)",
                    ))
                    console.print(f"    {file_findings[0].description}")
                
                console.print()
    
    # Errors
    if result.errors:
        console.print("[red bold]Errors:[/red bold]")
        for error in result.errors:
            console.print(f"  ❌ {error}")
    
    # Warnings (verbose only)
    if result.warnings and verbose:
        console.print("\n[yellow]Warnings:[/yellow]")
        for warning in result.warnings:
            console.print(f"  ⚡ {warning}")
    
    console.print()


def print_json(result: ScanResult):
    """Print scan result as JSON."""
    output = {
        "version": __version__,
        "path": result.path,
        "trust_level": result.trust_level,
        "content_hash": result.content_hash,
        "summary": result.summary(),
        "findings": [
            {
                "severity": f.severity.value,
                "pattern_id": f.pattern_id,
                "description": f.description,
                "file": f.file,
                "line": f.line,
                "match": f.match,
                "context": f.context,
            }
            for f in result.findings
        ],
        "symlinks": result.symlinks_found,
        "errors": result.errors,
        "warnings": result.warnings,
    }
    print(json.dumps(output, indent=2))


@click.command()
@click.argument('path')
@click.option('--json', 'output_json', is_flag=True, help='Output as JSON')
@click.option('--verbose', '-v', is_flag=True, help='Show INFO findings and extra details')
@click.option('--hash', 'show_hash', is_flag=True, help='Show content hash')
@click.option('--version', is_flag=True, help='Show version')
@click.option('--quiet', '-q', is_flag=True, help='Only output trust level')
@click.option('--cve', 'check_cves', is_flag=True, help='Check dependencies against CVE database (requires network)')
def main(path: str, output_json: bool, verbose: bool, show_hash: bool, version: bool, quiet: bool, check_cves: bool):
    """
    Scan an agent skill for security issues.
    
    PATH can be a local directory or file.
    
    \b
    Exit codes:
      0 = SAFE     - No issues found
      1 = CAUTION  - Minor issues, review recommended
      2 = DANGER   - Security issues detected
      3 = ERROR    - Scanner error
    
    \b
    Examples:
      isnad-scan ./skills/my-skill/
      isnad-scan ./skills/my-skill/ --json
      isnad-scan ./skills/my-skill/ -v --hash
    """
    if version:
        print(f"isnad-scan {__version__}")
        sys.exit(0)
    
    try:
        result = scan_skill(path, check_cves=check_cves)
    except Exception as e:
        if output_json:
            print(json.dumps({"error": str(e)}))
        else:
            console.print(f"[red]Error:[/red] {e}")
        sys.exit(3)
    
    if quiet:
        print(result.trust_level)
    elif output_json:
        print_json(result)
    else:
        print_result(result, verbose=verbose, show_hash=show_hash)
    
    sys.exit(result.exit_code)


if __name__ == "__main__":
    main()
