"""Pre-commit hook for SHIP Protocol scoring.

Usage in .pre-commit-config.yaml::

    repos:
      - repo: https://github.com/vibeatlas/ship-score-python
        rev: v1.0.0
        hooks:
          - id: ship-score
            args: ['--min-score=60']
"""

from __future__ import annotations

import subprocess
import sys
from pathlib import Path

import click

from .client import ShipClient


def _get_staged_message() -> str:
    """Get the commit message from COMMIT_EDITMSG or git."""
    # During commit, the message file is passed or available at .git/COMMIT_EDITMSG
    git_dir = Path(
        subprocess.check_output(
            ["git", "rev-parse", "--git-dir"], text=True
        ).strip()
    )
    msg_file = git_dir / "COMMIT_EDITMSG"
    if msg_file.exists():
        return msg_file.read_text().strip()
    return "unknown commit"


def _get_repo_name() -> str:
    """Derive owner/repo from git remote."""
    try:
        remote = subprocess.check_output(
            ["git", "remote", "get-url", "origin"], text=True
        ).strip()
        # Handle SSH and HTTPS URLs
        if remote.startswith("git@"):
            remote = remote.split(":", 1)[1]
        remote = remote.removeprefix("https://github.com/")
        remote = remote.removesuffix(".git")
        return remote
    except Exception:
        return "unknown/unknown"


def _get_primary_language(filenames: list[str]) -> str:
    """Detect primary language from staged file extensions."""
    ext_map = {
        ".py": "python",
        ".js": "javascript",
        ".ts": "typescript",
        ".go": "go",
        ".rs": "rust",
        ".java": "java",
        ".rb": "ruby",
        ".cpp": "cpp",
        ".c": "c",
    }
    counts: dict[str, int] = {}
    for f in filenames:
        ext = Path(f).suffix
        lang = ext_map.get(ext)
        if lang:
            counts[lang] = counts.get(lang, 0) + 1
    if not counts:
        return "unknown"
    return max(counts, key=lambda k: counts[k])


@click.command()
@click.option(
    "--min-score", default=60, type=int,
    help="Minimum passing score (0-100)",
)
@click.option(
    "--api-url", envvar="SHIP_API_URL",
    default=None, help="SHIP API base URL",
)
@click.argument("filenames", nargs=-1)
def main(
    min_score: int,
    api_url: str | None,
    filenames: tuple[str, ...],
) -> None:
    """SHIP Protocol pre-commit hook — blocks commits below score threshold."""
    if api_url:
        client = ShipClient(base_url=api_url)
    else:
        client = ShipClient()
    message = _get_staged_message()
    repo = _get_repo_name()
    language = _get_primary_language(list(filenames))

    try:
        result = client.score(repo=repo, message=message, language=language)
    except Exception as exc:
        click.echo(
            f"SHIP: Warning — API error ({exc}), "
            "allowing commit",
            err=True,
        )
        sys.exit(0)

    click.echo(
        f"SHIP Score: {result.score}/100 (Grade: {result.grade}) | "
        f"Confidence: {result.confidence:.2f}"
    )

    if result.score < min_score:
        click.echo(
            f"BLOCKED: Score {result.score} is below minimum threshold {min_score}",
            err=True,
        )
        if result.recommendations:
            click.echo("Recommendations:", err=True)
            for rec in result.recommendations:
                click.echo(f"  • {rec}", err=True)
        sys.exit(1)


if __name__ == "__main__":
    main()
