"""run_seq 예측."""
from __future__ import annotations

import re as _re
from pathlib import Path
from typing import Optional

from .ids import slugify_task_segment
from .paths import task_runs_dir
from .run_index_row import read_run_index


def predict_next_run_seq(project_root: Path, task_group: str, task_id: str,
                         task_type: str, *,
                         home: Optional[Path] = None,
                         project_id: Optional[str] = None) -> int:
    """타깃 프로젝트와 (선택적) 중앙 인덱스를 합쳐 다음 run_seq 를 계산.

    스캔 소스:
      1. reports/ 의 final-report-<task_type>-<seq:03d>.md (완료된 run)
      2. manifests/ 의 run-manifest-<task_type>-<seq:03d>.json (시작했지만 종료 전)
      3. home/active.jsonl 의 같은 (project_id, group, task_id, task_type) row
         (다른 okstra-ctl 프로세스가 이미 예약한 in-flight run) — home/project_id 가 주어진 경우만

    이 셋의 max + 1 이 안전한 다음 seq.
    """
    task_type_segment = slugify_task_segment(task_type)
    base = task_runs_dir(project_root, task_group, task_id) / task_type_segment
    max_seq = 0
    rep_pat = _re.compile(rf"^final-report-{_re.escape(task_type_segment)}-(\d+)\.md$")
    man_pat = _re.compile(rf"^run-manifest-{_re.escape(task_type_segment)}-(\d+)\.json$")
    for sub, pat in (("reports", rep_pat), ("manifests", man_pat)):
        d = base / sub
        if not d.is_dir():
            continue
        for child in d.iterdir():
            m = pat.match(child.name)
            if m:
                n = int(m.group(1))
                if n > max_seq:
                    max_seq = n
    if home is not None and project_id is not None:
        for src in ("active.jsonl", "recent.jsonl"):
            for r in read_run_index(home / src):
                if (r.get("projectId") == project_id
                        and r.get("taskGroup") == task_group
                        and r.get("taskId") == task_id
                        and r.get("taskType") == task_type):
                    s = int(r.get("runSeq", 0))
                    if s > max_seq:
                        max_seq = s
    return max_seq + 1
