"""Show v0 — read-only run detail viewer from manifest.json."""

from __future__ import annotations

import json
import pathlib
from typing import Any

from milco.core.manifest import MANIFEST_FILENAME


def load_manifest(run_dir: pathlib.Path) -> dict[str, Any] | None:
    """Load manifest.json from a run directory. Returns None if missing."""
    manifest_path = run_dir / MANIFEST_FILENAME
    if not manifest_path.exists():
        return None
    return json.loads(manifest_path.read_text(encoding="utf-8"))


def list_run_ids(runs_dir: pathlib.Path) -> list[str]:
    """List available run_ids (directories under runs/ that contain manifest.json)."""
    if not runs_dir.exists():
        return []
    ids = []
    for p in sorted(runs_dir.iterdir()):
        if p.is_dir() and (p / MANIFEST_FILENAME).exists():
            ids.append(p.name)
    return ids


def format_run_detail(manifest: dict[str, Any]) -> str:
    """Format a manifest into a human-readable detail view."""
    lines: list[str] = []

    outcome = manifest.get("outcome", {})
    decision = outcome.get("decision", "?")
    exit_code = outcome.get("exit_code", "?")
    mode = manifest.get("mode", "?")
    command = manifest.get("command", "?")
    run_id = manifest.get("run_id", "?")
    ts = manifest.get("timestamps", {})
    repo = manifest.get("repo", {})

    lines.append(f"Run:       {run_id}")
    lines.append(f"Command:   {command}")
    lines.append(f"Mode:      {mode}")
    lines.append(f"Decision:  {decision}")
    lines.append(f"Exit code: {exit_code}")
    lines.append("")
    lines.append(f"Started:   {ts.get('started_at', '?')}")
    lines.append(f"Finished:  {ts.get('finished_at', '?')}")
    lines.append("")

    lines.append("Repo:")
    lines.append(f"  git:    {'yes' if repo.get('git_available') else 'no'}")
    if repo.get("branch"):
        lines.append(f"  branch: {repo['branch']}")
    if repo.get("commit"):
        lines.append(f"  commit: {repo['commit']}")
    dirty_b = repo.get("is_dirty_before")
    dirty_a = repo.get("is_dirty_after")
    if dirty_b is not None:
        lines.append(f"  dirty before: {'yes' if dirty_b else 'no'}")
    if dirty_a is not None:
        lines.append(f"  dirty after:  {'yes' if dirty_a else 'no'}")
    lines.append("")

    artifacts = manifest.get("artifacts", {})
    if artifacts:
        lines.append("Artifacts:")
        name_w = max(len(n) for n in artifacts) if artifacts else 10
        for name, entry in artifacts.items():
            size = entry.get("bytes", 0)
            sha = entry.get("sha256", "")[:12]
            lines.append(f"  {name:<{name_w}}  {size:>7} bytes  sha256:{sha}...")
    lines.append("")

    notes = manifest.get("notes", [])
    if notes:
        lines.append("Notes:")
        for n in notes:
            lines.append(f"  - {n}")

    return "\n".join(lines)
