"""
Iteration directory operations for V5 orchestrator.

Each iteration directory IS a log entry. metadata.json contains
based_on, refined_from, rating, etc.
"""

import json
from pathlib import Path
from typing import Optional
from datetime import datetime, timezone


def list_iterations(stage_dir: Path) -> list:
    """List all iteration numbers in a stage dir, sorted ascending."""
    if not stage_dir.exists():
        return []

    return sorted(
        d.name for d in stage_dir.iterdir()
        if d.is_dir() and d.name.isdigit() and len(d.name) == 3
    )


def read_metadata(iter_dir: Path) -> dict:
    """Read metadata.json from iteration directory."""
    metadata_file = iter_dir / "metadata.json"
    if not metadata_file.exists():
        return {}
    with open(metadata_file) as f:
        return json.load(f)


def save_iteration_metadata(iter_dir: Path, metadata: dict) -> None:
    """Save metadata.json to iteration directory."""
    metadata_file = iter_dir / "metadata.json"
    with open(metadata_file, "w") as f:
        json.dump(metadata, f, indent=2)
        f.write("\n")


def create_iteration_metadata(
    stage: str,
    iteration: str,
    based_on: dict,
    refined_from: Optional[str] = None,
    result: Optional[str] = None,
) -> dict:
    """Create a new metadata dict for an iteration."""
    return {
        "stage": stage,
        "iteration": iteration,
        "created_at": datetime.now(timezone.utc).isoformat(),
        "based_on": based_on,
        "refined_from": refined_from,
        "rating": None,
        "result": result,
    }


def get_best_iteration(
    take_path: Path,
    stage: str,
    parent_chain: Optional[dict] = None,
) -> Optional[str]:
    """
    Find best iteration for a stage: highest rating, then most recent.

    If parent_chain is provided, only consider iterations whose based_on
    matches the parent chain.
    """
    stage_dir = take_path / stage
    iterations = list_iterations(stage_dir)

    if not iterations:
        return None

    candidates = []
    for iter_num in iterations:
        meta = read_metadata(stage_dir / iter_num)
        if not meta:
            continue

        # Filter by parent chain if provided
        if parent_chain is not None:
            iter_based_on = meta.get("based_on", {})
            if iter_based_on != parent_chain:
                continue

        rating = meta.get("rating") or 0  # null/None treated as 0
        candidates.append((rating, iter_num))

    if not candidates:
        return None

    # Sort by rating desc, then iteration desc (most recent)
    candidates.sort(key=lambda x: (x[0], x[1]), reverse=True)
    return candidates[0][1]
