#!/usr/bin/env python3
"""Verdict-keying helpers for Recoil — mode-aware shot_id derivation,
verdict filename construction, and `.verdicts/` directory resolution.

These helpers are imported by the verdict writer/reader (future learning-loop
deliverable). They live here separately so the learning-loop's verdict.py can
focus on schema + atomic write logic.

Behavior summary:

  Microdrama (`project.has_take_semantics == True`):
    derive_shot_identity("shot_033_take2.mp4", project) -> ("shot_033", 2)
    derive_shot_identity("shot_033.mp4",       project) -> ("shot_033", 1)
    verdict_filename("shot_033", 2)                      -> "shot_033_take2_verdict.json"

  Client_deliverable (`project.has_take_semantics == False`):
    derive_shot_identity("V1_STAY.mp4",       project)  -> ("V1_STAY", None)
    derive_shot_identity("V1_STAY_take1.mp4", project)  -> ("V1_STAY_take1", None)
    verdict_filename("V1_STAY", None)                   -> "V1_STAY_verdict.json"

  Verdicts directory (any mode):
    verdicts_dir(episode_dir) -> episode_dir / ".verdicts"  (created on first call)
"""

from __future__ import annotations

import re
from pathlib import Path

from recoil.core.project import Project

__all__ = ["derive_shot_identity", "verdict_filename", "verdicts_dir"]


_TAKE_SUFFIX = re.compile(r"_take(\d+)$")


def derive_shot_identity(
    filename: str, project: Project
) -> tuple[str, int | None]:
    """Return (shot_id, take_num) for a media filename in the project's mode.

    Microdrama: strips `_take(\\d+)$` from the stem; defaults take=1 if absent.
    Client_deliverable / non-take-semantic modes: stem is the shot_id verbatim;
    take_num is None.

    Multi-extension files (e.g. `foo.mp4.json`) are NOT supported here — pass
    the source media filename, not the sidecar.
    """
    stem = Path(filename).stem

    if project.has_take_semantics:
        m = _TAKE_SUFFIX.search(stem)
        if m:
            return stem[: m.start()], int(m.group(1))
        return stem, 1

    # Non-take-semantic modes: stem is identity, no take number
    return stem, None


def verdict_filename(shot_id: str, take_num: int | None) -> str:
    """Build the verdict filename for a shot+take.

    Microdrama: `{shot_id}_take{N}_verdict.json`
    Client / no-take modes: `{shot_id}_verdict.json`
    """
    if take_num is not None:
        return f"{shot_id}_take{take_num}_verdict.json"
    return f"{shot_id}_verdict.json"


def verdicts_dir(episode_dir: Path) -> Path:
    """Return the `.verdicts/` subdirectory for an episode, creating it if absent.

    Universal across modes — every project type that captures verdicts uses
    the `.verdicts/` subdirectory to keep verdict JSONs out of the source
    media directories.
    """
    d = episode_dir / ".verdicts"
    d.mkdir(parents=True, exist_ok=True)
    return d
