#!/usr/bin/env python3
"""
Stage S2: Story Bible

Claude reads the full story text and any user references, extracts
structured analysis into story_bible.json.
"""

import subprocess
import sys

from lib import claude_env
from pathlib import Path
from datetime import datetime, timezone

sys.path.insert(0, str(Path(__file__).parent.parent))

from lib import save_metadata, ensure_dir
from lib.path_utils_v3 import get_next_iteration
from lib.feedback_history_v5 import get_feedback_history_for_claude


def execute(story_path: Path, inputs: dict,
            feedback: str = None, refined_from: str = None) -> dict:
    """
    Execute Stage S2: Story Bible generation.

    Args:
        story_path: Path to story project directory
        inputs: {"S1-ingest": "001"}
        feedback: User feedback
        refined_from: Iteration being refined
    """
    stage_dir = story_path / "S2-bible"
    ensure_dir(stage_dir)
    iteration = get_next_iteration(stage_dir)
    iter_path = stage_dir / iteration
    ensure_dir(iter_path)

    print(f"\nStage S2: Story Bible (iteration {iteration})")

    # Verify source text exists
    source_file = story_path / "source.txt"
    if not source_file.exists():
        return {"status": "error", "error": "source.txt not found. Run S1-ingest first."}

    # Load session
    session_file = story_path / "session.txt"
    if not session_file.exists():
        return {"status": "error", "error": "session.txt not found"}
    session_id = session_file.read_text().strip()

    # Build user references section
    refs_section = _build_references_section(story_path)

    # Load prompt template
    prompt_path = Path(__file__).parent.parent.parent / "prompts" / "story" / "stage_s2_bible.txt"
    if not prompt_path.exists():
        return {"status": "error", "error": f"Prompt template not found: {prompt_path}"}

    prompt = prompt_path.read_text()
    prompt = prompt.replace("{user_references_section}", refs_section)

    # Add feedback
    if refined_from:
        feedback_history = get_feedback_history_for_claude(
            story_path, "S2-bible", refined_from
        )
        if feedback_history:
            prompt += f"\n\n## Previous Feedback\n\n{feedback_history}\n"
    if feedback:
        prompt += f"\n\n## User Feedback\n\n{feedback}\n"

    # Save feedback if provided
    if feedback:
        (iter_path / "feedback.txt").write_text(feedback)

    # Prepend output directory
    relative_iter_path = iter_path.relative_to(story_path)
    prompt = f"## Output Directory\n\nWrite ALL output files to: {relative_iter_path}/\n\n{prompt}"

    # Save prompt
    (iter_path / "prompt.txt").write_text(prompt)

    # Call Claude
    print(f"Session: {session_id}")
    print("Calling Claude to analyze story...")

    try:
        result = subprocess.run(
            ["claude", "--resume", session_id,
             "--allowedTools", "Read,Write,Glob,Grep",
             "-p", prompt],
            capture_output=True, text=True,
            cwd=str(story_path), timeout=600,
            env=claude_env()
        )

        if result.returncode != 0:
            error_detail = result.stderr or result.stdout
            error_msg = f"Claude returned code {result.returncode}: {error_detail}"
            return {"status": "error", "error": error_msg}

    except subprocess.TimeoutExpired:
        return {"status": "error", "error": "Claude timed out after 10 minutes"}

    # Validate output
    bible_file = iter_path / "story_bible.json"
    if not bible_file.exists():
        return {"status": "error", "error": "story_bible.json not created"}

    # User message
    user_msg_file = iter_path / "user_message.txt"
    user_message = (user_msg_file.read_text().strip() if user_msg_file.exists()
                    else "Story bible generated. Please review.")

    # Save metadata
    metadata = {
        "stage": "S2-bible",
        "iteration": iteration,
        "created_at": datetime.now(timezone.utc).isoformat(),
        "based_on": inputs,
        "refined_from": refined_from,
        "rating": None,
        "result": f"S2-bible/{iteration}/story_bible.json",
        "session_id": session_id,
    }
    save_metadata(iter_path / "metadata.json", metadata)

    print(f"\nGenerated: S2-bible/{iteration}/story_bible.json")
    return {
        "status": "success",
        "iteration": iteration,
        "result": f"S2-bible/{iteration}/story_bible.json",
        "user_message": user_message,
    }


def _build_references_section(story_path: Path) -> str:
    """Build prompt section describing user-provided references."""
    refs_path = story_path / "references"
    if not refs_path.exists():
        return ""

    sections = []

    # Check for style references
    style_path = refs_path / "style"
    if style_path.exists():
        style_photos = list(style_path.glob("*.jpg")) + list(style_path.glob("*.png")) + list(style_path.glob("*.webp"))
        if style_photos:
            sections.append("## User-Provided Visual References")
            sections.append(f"\nStyle/mood reference images ({len(style_photos)} photos):")
            for p in style_photos:
                sections.append(f"- `{p}`")

    # Check for people references
    people_path = refs_path / "people"
    if people_path.exists():
        for person_dir in sorted(people_path.iterdir()):
            if person_dir.is_dir():
                photos = list(person_dir.glob("*.jpg")) + list(person_dir.glob("*.png"))
                desc_file = person_dir / "description.md"
                if photos or desc_file.exists():
                    sections.append(f"\n### Person: {person_dir.name}")
                    if desc_file.exists():
                        sections.append(desc_file.read_text())
                    if photos:
                        sections.append(f"Reference photos: {len(photos)}")
                        for p in photos:
                            sections.append(f"- `{p}`")

    # Check for location references
    loc_path = refs_path / "locations"
    if loc_path.exists():
        loc_photos = list(loc_path.glob("*.jpg")) + list(loc_path.glob("*.png"))
        if loc_photos:
            sections.append("\n### Location References")
            for p in loc_photos:
                sections.append(f"- `{p}`")

    if sections:
        return "\n".join(sections)
    return "(No user references provided yet — references/ directory is empty)"
