"""Path helpers for generated final-report view artifacts."""
from __future__ import annotations

from pathlib import Path

from .json_boundary import JsonBoundaryError, load_owned_object


def html_view_path(report_path: Path) -> Path:
    """Return the HTML sibling for a final-report Markdown or data path."""
    if report_path.name.endswith(".data.json"):
        stem = report_path.name.removesuffix(".data.json")
        return report_path.with_name(stem + ".html")
    return report_path.with_suffix(".html")


def user_responses_dir_for_report(report_path: Path) -> Path:
    """Return the sidecar directory used by the report's exported responses."""
    return report_path.parent.parent / "user-responses"


def team_state_path_for_report(report_path: Path, task_type: str, seq: str) -> Path:
    """The team-state of the run that produced this report.

    The report's sequence is not the run's: categories are numbered on their
    own (`paths.compute_run_paths`), so two prepared-and-abandoned runs leave
    the report slot free while consuming state slots, and the run that finally
    writes `final-report-…-002` keeps its usage in `team-state-…-004`. Naming
    the state after the report's seq read the earlier run's usage — a header
    elapsed of 389h taken from a run that shared nothing but the number
    (observed 2026-09-02, dev-10626 error-analysis). The run manifest names
    both files (`expectedReportRecordPath`, `teamStatePath`), so the latest
    manifest naming this report decides; the seq-derived sibling is the
    fallback for a run directory without such a manifest.
    """
    run_dir = report_path.parent.parent
    recorded = _team_state_from_manifests(run_dir, report_path.name)
    if recorded is not None:
        return recorded
    return run_dir / "state" / f"team-state-{task_type}-{seq}.json"


def _team_state_from_manifests(run_dir: Path, report_name: str) -> Path | None:
    # 최신 manifest 부터 본다 — 같은 보고서 자리를 이름한 run 이 여럿이면(앞선
    # run 이 준비만 하고 끝난 경우) 마지막 run 이 그 보고서를 쓴 run 이다.
    # `Path.glob` 는 디렉터리가 없어도 빈 결과를 낸다.
    for manifest_path in sorted(
        (run_dir / "manifests").glob("run-manifest-*.json"), reverse=True
    ):
        try:
            manifest = load_owned_object(manifest_path, artifact="run manifest")
        except (OSError, JsonBoundaryError):
            # 깨진 manifest 는 이 보고서를 이름할 수 없다 — 다음 후보를 본다.
            continue
        expected = manifest.get("expectedReportRecordPath")
        team_state = manifest.get("teamStatePath")
        if not isinstance(expected, str) or not isinstance(team_state, str):
            continue
        if Path(expected).name != report_name or not team_state:
            continue
        return run_dir / "state" / Path(team_state).name
    return None
