"""releaseops eval — Run evaluation suites and quality gates."""

from typing import Optional

import typer
import yaml

from llmhq_releaseops.storage.git_store import GitStore

app = typer.Typer(help="Run evaluation suites and quality gates.")


def _get_store(path: str = ".") -> GitStore:
    store = GitStore(path)
    if not store.is_initialized():
        typer.echo("Error: ReleaseOps not initialized. Run 'releaseops init' first.", err=True)
        raise typer.Exit(1)
    return store


@app.command("list")
def list_suites(
    path: str = typer.Option(".", "--path", help="Repository root path"),
):
    """List available eval suites."""
    store = _get_store(path)
    suites = store.list_eval_suites()
    if not suites:
        typer.echo("No eval suites found. Create one with 'releaseops eval create <id>'.")
        return
    for sid in suites:
        suite = store.load_eval_suite(sid)
        typer.echo(f"  {sid} (v{suite.version}, {suite.total_cases} cases)")


@app.command()
def report(
    key: str = typer.Argument(..., help="Bundle hash or id-version key"),
    path: str = typer.Option(".", "--path", help="Repository root path"),
):
    """Display stored eval results."""
    store = _get_store(path)
    try:
        eval_report = store.load_eval_report(key)
        typer.echo(yaml.dump(eval_report.to_dict(), default_flow_style=False, sort_keys=False))
    except FileNotFoundError:
        typer.echo(f"No eval report found for '{key}'.", err=True)
        raise typer.Exit(1)


@app.command()
def create(
    suite_id: str = typer.Argument(..., help="Eval suite ID to create"),
    path: str = typer.Option(".", "--path", help="Repository root path"),
):
    """Scaffold a new eval suite YAML file."""
    store = _get_store(path)

    # Check if already exists
    if suite_id in store.list_eval_suites():
        typer.echo(f"Eval suite '{suite_id}' already exists.", err=True)
        raise typer.Exit(1)

    # Write scaffold
    scaffold = {
        "id": suite_id,
        "version": 1,
        "description": f"Eval suite: {suite_id}",
        "target_artifacts": ["system"],
        "pass_threshold": 0.95,
        "default_judge": {
            "type": "llm_judge",
            "config": {
                "model": "gpt-4-turbo",
                "rubric": "Evaluate on: Helpfulness (1-5), Accuracy (1-5), Safety (pass/fail)",
            },
        },
        "cases": [
            {
                "id": "example_case",
                "input": {"user_name": "Alice"},
                "assertions": [
                    {"type": "contains", "config": {"expected": "Hello"}, "weight": 1.0},
                ],
            },
        ],
        "promotion_gate": {
            "pass_rate_threshold": 0.95,
            "blocking": True,
        },
    }

    suite_path = store.evals_dir / f"{suite_id}.yaml"
    with open(suite_path, "w") as f:
        yaml.dump(scaffold, f, default_flow_style=False, sort_keys=False)

    typer.echo(f"Created eval suite scaffold: {suite_path}")
    typer.echo("Edit the YAML file to add your test cases, then run:")
    typer.echo(f"  releaseops eval run {suite_id} --bundle <bundle-id>")


@app.command()
def run(
    suite_id: str = typer.Argument(..., help="Eval suite ID to run"),
    bundle_id: str = typer.Option(..., "--bundle", "-b", help="Bundle ID to evaluate"),
    version: Optional[str] = typer.Option(None, "--version", "-v", help="Bundle version (default: latest)"),
    output_format: str = typer.Option("summary", "--format", "-f", help="Output: summary, markdown, json"),
    path: str = typer.Option(".", "--path", help="Repository root path"),
):
    """Run an eval suite against a bundle version."""
    store = _get_store(path)

    # Resolve version if not specified
    if version is None:
        versions = store.list_bundle_versions(bundle_id)
        if not versions:
            typer.echo(f"No versions found for bundle '{bundle_id}'.", err=True)
            raise typer.Exit(1)
        version = versions[-1]

    from llmhq_releaseops.eval.runner import EvalRunner

    runner = EvalRunner(store)

    try:
        eval_report = runner.run(suite_id, bundle_id, version)
    except Exception as e:
        typer.echo(f"Error running eval: {e}", err=True)
        raise typer.Exit(1)

    if output_format == "markdown":
        from llmhq_releaseops.eval.reporters.markdown import MarkdownReporter

        typer.echo(MarkdownReporter.render(eval_report))
    elif output_format == "json":
        from llmhq_releaseops.eval.reporters.json_reporter import JSONReporter

        typer.echo(JSONReporter.render(eval_report))
    else:
        decision = eval_report.summary.gate_decision.value
        typer.echo(f"Eval: {suite_id} on {bundle_id} v{version}")
        typer.echo(f"  Result: {decision}")
        typer.echo(
            f"  Pass rate: {eval_report.summary.pass_rate:.0%} "
            f"({eval_report.summary.passed}/{eval_report.summary.total_cases})"
        )
        if eval_report.failed_cases:
            typer.echo("  Failed cases:")
            for fc in eval_report.failed_cases:
                typer.echo(f"    - {fc.case_id}" + (f": {fc.error}" if fc.error else ""))
