"""Analysis material body + related-tasks builders.

bash `build_review_material`, `resolve_related_tasks_json`,
`build_related_tasks_bullets`, `build_related_tasks_inline` 의 python 구현.
brief 본문과 directive 를 합쳐 lead 가 읽을 `analysis-material.md` 본문을
만들고, 이미 manifest 에 기록된 related-tasks 와 새 입력을 merge 한다.
"""
from __future__ import annotations

import json
from pathlib import Path
from typing import Optional

from .json_boundary import load_owned_object


def build_analysis_material(brief_path: Path, directive: str = "") -> str:
    """`analysis-material.md` 본문 문자열을 돌려준다."""
    parts = ["# OKSTRA Analysis Material", "", "## Task Brief", ""]
    parts.append(Path(brief_path).read_text(encoding="utf-8").rstrip())
    if directive:
        parts.append("")
        parts.append("## Directive")
        parts.append("")
        parts.append(
            "> Free-form directive supplied via `--directive`. Treat as a hard hint that may override default heuristics in lead, workers, and downstream skills (e.g. okstra-schedule-gen's Gantt skip gate)."
        )
        parts.append("")
        parts.append(directive)
    return "\n".join(parts).rstrip() + "\n"


def resolve_related_tasks(
    *, task_manifest_path: Optional[Path], raw_related: str
) -> list[str]:
    """기존 manifest 의 relatedTasks + 새 CSV 입력을 dedupe-merge."""
    existing: list[str] = []
    if task_manifest_path and Path(task_manifest_path).exists():
        try:
            manifest = load_owned_object(
                Path(task_manifest_path), artifact="task manifest"
            )
            existing = manifest.get("relatedTasks") or []
            if not isinstance(existing, list):
                existing = []
        except Exception:
            existing = []
    provided = [v.strip() for v in (raw_related or "").split(",") if v.strip()]
    seen: set[str] = set()
    out: list[str] = []
    for v in [*existing, *provided]:
        if not v or v in seen:
            continue
        seen.add(v)
        out.append(v)
    return out


def related_tasks_bullets(items: list[str]) -> str:
    if not items:
        return "- None recorded"
    return "\n".join(f"- `{v}`" for v in items)


def related_tasks_inline(items: list[str]) -> str:
    return ", ".join(items) if items else "None"
