"""Command-line interface for Prismor security scanning tool."""

import sys
import json
import click
from typing import Optional
from .api import PrismorClient, PrismorAPIError


def print_success(message: str):
    """Print success message in green."""
    click.secho(f"✓ {message}", fg="green")


def print_error(message: str):
    """Print error message in red."""
    click.secho(f"✗ {message}", fg="red", err=True)


def print_info(message: str):
    """Print info message in blue."""
    click.secho(f"ℹ {message}", fg="blue")


def print_warning(message: str):
    """Print warning message in yellow."""
    click.secho(f"⚠ {message}", fg="yellow")


def format_scan_results(results: dict, scan_type: str):
    """Format and display scan results."""
    click.echo("\n" + "=" * 60)
    click.secho(f"  Scan Results - {scan_type}", fg="cyan", bold=True)
    click.echo("=" * 60 + "\n")
    
    # Display repository information
    if "repository" in results:
        click.secho("Repository:", fg="yellow", bold=True)
        click.echo(f"  {results['repository']}\n")
    
    if "branch" in results:
        click.secho("Branch:", fg="yellow", bold=True)
        click.echo(f"  {results['branch']}\n")
    
    if "commit_sha" in results:
        click.secho("Commit SHA:", fg="yellow", bold=True)
        click.echo(f"  {results['commit_sha']}\n")
    
    # Display scan results for each scan type
    if "scans" in results:
        scans = results["scans"]
        
        # Vulnerability scan results
        if "vulnerability" in scans:
            vuln_scan = scans["vulnerability"]
            click.secho("Vulnerability Scan:", fg="yellow", bold=True)
            status_color = "green" if vuln_scan.get("status") == "success" else "red"
            click.secho(f"  Status: {vuln_scan.get('status', 'unknown')}", fg=status_color)
            
            if "scan_results" in vuln_scan:
                scan_data = vuln_scan["scan_results"]
                if "vulnerabilities" in scan_data or "Results" in scan_data:
                    vuln_data = scan_data.get("vulnerabilities", scan_data.get("Results", []))
                    if isinstance(vuln_data, list):
                        click.echo(f"  Vulnerabilities Found: {len(vuln_data)}")
                    else:
                        click.echo(f"  Vulnerabilities: Data available")
            
            if "public_url" in vuln_scan:
                click.echo(f"  Results URL: {vuln_scan['public_url']}")
            click.echo()
        
        # SBOM results
        if "sbom" in scans:
            sbom_scan = scans["sbom"]
            click.secho("SBOM Generation:", fg="yellow", bold=True)
            status_color = "green" if sbom_scan.get("status") == "success" else "red"
            click.secho(f"  Status: {sbom_scan.get('status', 'unknown')}", fg=status_color)
            
            if "sbom" in sbom_scan:
                sbom_data = sbom_scan["sbom"]
                if isinstance(sbom_data, list):
                    click.echo(f"  Artifacts Found: {len(sbom_data)}")
                else:
                    click.echo(f"  SBOM: Data available")
            
            if "public_url" in sbom_scan:
                click.echo(f"  Results URL: {sbom_scan['public_url']}")
            click.echo()
        
        # Secret scan results
        if "secret" in scans:
            secret_scan = scans["secret"]
            click.secho("Secret Detection:", fg="yellow", bold=True)
            status_color = "green" if secret_scan.get("status") == "success" else "red"
            click.secho(f"  Status: {secret_scan.get('status', 'unknown')}", fg=status_color)
            
            if "summary" in secret_scan:
                summary = secret_scan["summary"]
                if isinstance(summary, dict):
                    for key, value in summary.items():
                        click.echo(f"  {key}: {value}")
                else:
                    click.echo(f"  Summary: {summary}")
            
            if "public_url" in secret_scan:
                click.echo(f"  Results URL: {secret_scan['public_url']}")
            click.echo()
    
    # Display scan timestamp
    if "scanned_at" in results:
        click.secho("Scanned At:", fg="yellow", bold=True)
        click.echo(f"  {results['scanned_at']}\n")
    
    click.echo("=" * 60 + "\n")


@click.group(invoke_without_command=True)
@click.option(
    "--scan",
    type=str,
    help="Repository to scan (username/repo or full GitHub URL)"
)
@click.option("--vex", is_flag=True, help="Perform vulnerability scanning")
@click.option("--sbom", is_flag=True, help="Generate Software Bill of Materials")
@click.option("--detect-secret", is_flag=True, help="Detect secrets in repository")
@click.option("--fullscan", is_flag=True, help="Perform all scan types")
@click.option("--branch", type=str, help="Specific branch to scan (defaults to main/master)")
@click.option("--json", "output_json", is_flag=True, help="Output results in JSON format")
@click.version_option(version="0.1.0", prog_name="prismor")
@click.pass_context
def cli(ctx, scan: Optional[str], vex: bool, sbom: bool, detect_secret: bool, 
        fullscan: bool, branch: Optional[str], output_json: bool):
    """Prismor CLI - Security scanning tool for GitHub repositories.
    
    Examples:
        prismor --scan username/repo --vex
        prismor --scan username/repo --fullscan
        prismor --scan https://github.com/username/repo --detect-secret
        prismor --scan username/repo --sbom --branch develop
        prismor status
        prismor repos
    """
    # If no command and no scan option, show help
    if ctx.invoked_subcommand is None and not scan:
        click.echo(ctx.get_help())
        return
    
    # If scan option is provided, perform the scan
    if scan:
        # Check if at least one scan type is selected
        if not any([vex, sbom, detect_secret, fullscan]):
            print_error("Please specify at least one scan type: --vex, --sbom, --detect-secret, or --fullscan")
            sys.exit(1)
        
        try:
            # Initialize API client
            print_info(f"Initializing Prismor scan for: {scan}")
            client = PrismorClient()
            
            # Determine scan type for display
            scan_types = []
            if fullscan:
                scan_types.append("Full Scan (VEX + SBOM + Secret Detection)")
            else:
                if vex:
                    scan_types.append("VEX")
                if sbom:
                    scan_types.append("SBOM")
                if detect_secret:
                    scan_types.append("Secret Detection")
            
            print_info(f"Scan type: {', '.join(scan_types)}")
            print_info("Starting scan... (this may take a few minutes)")
            
            # Perform scan
            results = client.scan(
                repo=scan,
                vex=vex,
                sbom=sbom,
                detect_secret=detect_secret,
                fullscan=fullscan,
                branch=branch
            )
            
            # Output results
            if output_json:
                click.echo(json.dumps(results, indent=2))
            else:
                print_success("Scan completed successfully!")
                format_scan_results(results, ', '.join(scan_types))
            
        except PrismorAPIError as e:
            print_error(str(e))
            sys.exit(1)
        except Exception as e:
            print_error(f"Unexpected error: {str(e)}")
            sys.exit(1)


@cli.command()
def version():
    """Display the version of Prismor CLI."""
    click.echo("Prismor CLI v0.1.0")


@cli.command()
def config():
    """Display current configuration."""
    import os
    
    click.echo("\n" + "=" * 60)
    click.secho("  Prismor CLI Configuration", fg="cyan", bold=True)
    click.echo("=" * 60 + "\n")
    
    # Check API key
    api_key = os.environ.get("PRISMOR_API_KEY")
    if api_key:
        # Show only first and last 4 characters
        masked_key = f"{api_key[:4]}...{api_key[-4:]}" if len(api_key) > 8 else "***"
        print_success(f"PRISMOR_API_KEY: {masked_key}")
    else:
        print_error("PRISMOR_API_KEY: Not set")
        click.echo("\nTo set your API key, run:")
        click.echo("  export PRISMOR_API_KEY=your_api_key")
    
    # click.echo("\nAPI Endpoint: http://localhost:3000")
    click.echo("=" * 60 + "\n")


@cli.command()
def repos():
    """List your connected repositories."""
    try:
        client = PrismorClient()
        repos_data = client.get_repositories()
        
        click.echo("\n" + "=" * 60)
        click.secho("  Your Repositories", fg="cyan", bold=True)
        click.echo("=" * 60 + "\n")
        
        user_info = repos_data.get("user", {})
        if user_info:
            click.secho(f"User: {user_info.get('name', 'Unknown')} ({user_info.get('email', 'No email')})", fg="yellow")
            click.echo()
        
        repositories = repos_data.get("repositories", [])
        if repositories:
            for repo in repositories:
                click.secho(f"• {repo.get('name', 'Unknown')}", fg="green")
                click.echo(f"  URL: {repo.get('htmlUrl', 'No URL')}")
                click.echo(f"  Owner: {repo.get('githubOwner', 'Unknown')}")
                click.echo()
        else:
            print_warning("No repositories found. Connect repositories through the web interface.")
        
        click.echo("=" * 60 + "\n")
        
    except PrismorAPIError as e:
        print_error(str(e))
        sys.exit(1)
    except Exception as e:
        print_error(f"Unexpected error: {str(e)}")
        sys.exit(1)


@cli.command()
def status():
    """Check your account status and GitHub integration."""
    try:
        client = PrismorClient()
        auth_data = client.authenticate()
        
        click.echo("\n" + "=" * 60)
        click.secho("  Account Status", fg="cyan", bold=True)
        click.echo("=" * 60 + "\n")
        
        user_info = auth_data.get("user", {})
        if user_info:
            click.secho(f"User: {user_info.get('name', 'Unknown')} ({user_info.get('email', 'No email')})", fg="yellow")
            click.echo()
            
            repositories = user_info.get("repositories", [])
            click.secho(f"Connected Repositories: {len(repositories)}", fg="green")
            
            if repositories:
                click.echo("\nRepository List:")
                for repo in repositories:
                    click.echo(f"  • {repo.get('name', 'Unknown')} ({repo.get('htmlUrl', 'No URL')})")
            else:
                print_warning("No repositories connected.")
                click.echo("\nTo connect repositories:")
                click.echo("  1. Visit https://prismor.dev/dashboard")
                click.echo("  2. Connect your GitHub account")
                click.echo("  3. Select repositories to scan")
        else:
            print_error("Failed to retrieve account information.")
        
        click.echo("\n" + "=" * 60 + "\n")
        
    except PrismorAPIError as e:
        print_error(str(e))
        sys.exit(1)
    except Exception as e:
        print_error(f"Unexpected error: {str(e)}")
        sys.exit(1)


def main():
    """Entry point for the CLI."""
    cli()


if __name__ == "__main__":
    main()

