"""CLI for SHIP Protocol scoring."""

from __future__ import annotations

import sys
from pathlib import Path

import click
from rich.console import Console
from rich.table import Table

from .client import ShipClient

console = Console()
err_console = Console(stderr=True)


def _grade_color(grade: str) -> str:
    return {
        "A": "green",
        "B": "blue",
        "C": "yellow",
        "D": "red",
        "F": "bright_red",
    }.get(grade.upper()[0] if grade else "", "white")


@click.group()
@click.option(
    "--api-url",
    envvar="SHIP_API_URL",
    default=None,
    help="SHIP API base URL",
)
@click.pass_context
def cli(ctx: click.Context, api_url: str | None) -> None:
    """SHIP Protocol — AI code reliability scoring."""
    ctx.ensure_object(dict)
    if api_url:
        ctx.obj["client"] = ShipClient(base_url=api_url)
    else:
        ctx.obj["client"] = ShipClient()


@cli.command()
@click.option("--repo", required=True, help="Repository (owner/repo)")
@click.option("--message", required=True, help="Commit message")
@click.option("--language", default="python", help="Primary language")
@click.option("--tool", default="claude", help="AI tool used")
@click.option("--json", "as_json", is_flag=True, help="Raw JSON")
@click.pass_context
def score(
    ctx: click.Context,
    repo: str,
    message: str,
    language: str,
    tool: str,
    as_json: bool,
) -> None:
    """Score an AI-generated commit for reliability."""
    client: ShipClient = ctx.obj["client"]
    try:
        result = client.score(
            repo=repo,
            message=message,
            language=language,
            tool=tool,
        )
    except Exception as exc:
        err_console.print(f"[red]Error:[/red] {exc}")
        sys.exit(1)

    if as_json:
        click.echo(result.model_dump_json(indent=2))
        return

    color = _grade_color(result.grade)
    console.print(
        f"SHIP Score: [{color} bold]{result.score}/100[/] "
        f"(Grade: [{color}]{result.grade}[/]) | "
        f"Confidence: {result.confidence:.2f}"
    )
    if result.recommendations:
        console.print("\n[bold]Recommendations:[/bold]")
        for rec in result.recommendations:
            console.print(f"  • {rec}")


@cli.command()
@click.option(
    "--file",
    "file_path",
    required=True,
    type=click.Path(exists=True),
    help="File to analyze",
)
@click.option(
    "--language",
    default=None,
    help="Language (auto-detected from extension)",
)
@click.option("--json", "as_json", is_flag=True, help="Raw JSON")
@click.pass_context
def detect(
    ctx: click.Context,
    file_path: str,
    language: str | None,
    as_json: bool,
) -> None:
    """Detect if a file contains AI-generated code."""
    client: ShipClient = ctx.obj["client"]
    path = Path(file_path)
    code = path.read_text()

    if language is None:
        ext_map = {
            ".py": "python",
            ".js": "javascript",
            ".ts": "typescript",
            ".go": "go",
            ".rs": "rust",
        }
        language = ext_map.get(path.suffix, "unknown")

    try:
        result = client.detect(code=code, language=language)
    except Exception as exc:
        err_console.print(f"[red]Error:[/red] {exc}")
        sys.exit(1)

    if as_json:
        click.echo(result.model_dump_json(indent=2))
        return

    ai_str = "[green]Yes[/green]" if result.is_ai else "[yellow]No[/yellow]"
    console.print(
        f"AI-Generated: {ai_str} "
        f"({result.confidence:.0%} confidence) | "
        f"{result.features_used} features analyzed"
    )


@cli.command()
@click.argument("repo")
@click.pass_context
def report(ctx: click.Context, repo: str) -> None:
    """Generate a full markdown report for a repository."""
    client: ShipClient = ctx.obj["client"]
    try:
        result = client.score(
            repo=repo,
            message="repository analysis",
            language="mixed",
        )
    except Exception as exc:
        err_console.print(f"[red]Error:[/red] {exc}")
        sys.exit(1)

    click.echo(f"# SHIP Report: {repo}\n")
    click.echo(f"**Score:** {result.score}/100 ({result.grade})")
    click.echo(f"**Confidence:** {result.confidence:.2f}\n")
    if result.factors:
        click.echo("## Factors\n")
        for k, v in result.factors.items():
            click.echo(f"- **{k}**: {v}")
    if result.recommendations:
        click.echo("\n## Recommendations\n")
        for rec in result.recommendations:
            click.echo(f"- {rec}")


@cli.command()
@click.pass_context
def health(ctx: click.Context) -> None:
    """Check SHIP API health and data stats."""
    client: ShipClient = ctx.obj["client"]
    status = client.health()

    if status.api_reachable:
        console.print(
            f"[green]✓[/green] API reachable: {status.api_url}"
        )
        console.print(f"  Commits: {status.total_commits:,}")
        console.print(f"  Repos:   {status.total_repos:,}")
    else:
        console.print(
            f"[red]✗[/red] API unreachable: {status.api_url}"
        )
        console.print(f"  Error: {status.error}")
        sys.exit(1)


@cli.command()
@click.pass_context
def tools(ctx: click.Context) -> None:
    """List AI tool reliability rankings."""
    client: ShipClient = ctx.obj["client"]
    try:
        tool_list = client.tools()
    except Exception as exc:
        err_console.print(f"[red]Error:[/red] {exc}")
        sys.exit(1)

    table = Table(title="AI Tool Reliability Rankings")
    table.add_column("Tool", style="bold")
    table.add_column("Score", justify="right")
    table.add_column("Grade", justify="center")

    for t in sorted(
        tool_list,
        key=lambda x: x.reliability_score or 0,
        reverse=True,
    ):
        grade = t.grade or "—"
        color = _grade_color(grade)
        rs = t.reliability_score
        score_str = str(int(rs)) if rs is not None else "—"
        table.add_row(
            t.display_name or t.name,
            score_str,
            f"[{color}]{grade}[/]",
        )

    console.print(table)


if __name__ == "__main__":
    cli()
