#!/usr/bin/env python3
"""
Logging utilities for microdrama v4 workflow.

Handles JSONL logging to pipeline.log.
Adapted for v4: accepts story_path directly instead of story_name.
"""
import json
from datetime import datetime, timezone
from pathlib import Path
from typing import Optional, Dict, Any


def log_event(
    story_path: Path,
    event_type: str,
    data: Dict[str, Any],
    take: Optional[str] = None,
    stage: Optional[str] = None,
    iteration: Optional[str] = None
) -> None:
    """
    Log an event to pipeline.log in JSONL format.

    Args:
        story_path: Path to story directory (e.g., /mnt/video/microdrama-v3/20260203-slug/)
        event_type: Type of event (e.g., "init", "generate", "regenerate")
        data: Event data dictionary
        take: Take number
        stage: Stage name
        iteration: Iteration number
    """
    log_file = story_path / "pipeline.log"

    entry = {
        "timestamp": datetime.now(timezone.utc).isoformat(),
        "event": event_type,
        **data
    }

    if take:
        entry["take"] = take
    if stage:
        entry["stage"] = stage
    if iteration:
        entry["iteration"] = iteration

    # Append to log file (JSONL format)
    with open(log_file, "a") as f:
        f.write(json.dumps(entry) + "\n")


def log_init(story_path: Path, story_name: str, take: str, session_id: str, previous_take: Optional[str] = None) -> None:
    """
    Log take initialization.

    Args:
        story_path: Path to story directory
        story_name: Story name (slug only, for logging)
        take: Take number
        session_id: Claude session ID
        previous_take: Previous take number (if any)
    """
    data = {
        "action": "init_take",
        "story_name": story_name,
        "session_id": session_id,
        "previous_take": previous_take
    }
    log_event(story_path, "init", data, take=take)


def log_stage_start(
    story_name: str,
    take: str,
    stage: str,
    iteration: str,
    session_id: str
) -> None:
    """Log stage start."""
    data = {
        "action": "stage_start",
        "session_id": session_id,
        "status": "started"
    }
    log_event(story_name, "stage", data, take=take, stage=stage, iteration=iteration)


def log_stage_complete(
    story_name: str,
    take: str,
    stage: str,
    iteration: str,
    session_id: str,
    output_file: Optional[str] = None,
    cost_estimate: Optional[float] = None
) -> None:
    """Log stage completion."""
    data = {
        "action": "stage_complete",
        "session_id": session_id,
        "status": "completed"
    }

    if output_file:
        data["output_file"] = output_file
    if cost_estimate:
        data["cost_estimate_usd"] = cost_estimate

    log_event(story_name, "stage", data, take=take, stage=stage, iteration=iteration)


def log_stage_error(
    story_name: str,
    take: str,
    stage: str,
    iteration: str,
    session_id: str,
    error: str
) -> None:
    """Log stage error."""
    data = {
        "action": "stage_error",
        "session_id": session_id,
        "status": "failed",
        "error": error
    }
    log_event(story_name, "stage", data, take=take, stage=stage, iteration=iteration)


def log_feedback(
    story_name: str,
    take: str,
    stage: str,
    iteration: str,
    feedback: str
) -> None:
    """Log user feedback."""
    data = {
        "action": "feedback",
        "feedback_text": feedback
    }
    log_event(story_name, "feedback", data, take=take, stage=stage, iteration=iteration)


def get_log_entries(
    story_name: str,
    event_filter: Optional[str] = None,
    take_filter: Optional[str] = None,
    stage_filter: Optional[str] = None
) -> list:
    """
    Read and filter log entries.

    Args:
        story_name: Story name
        event_filter: Filter by event type
        take_filter: Filter by take number
        stage_filter: Filter by stage name

    Returns:
        List of log entries matching filters
    """
    story_path = get_story_path(story_name)
    log_file = story_path / "pipeline.log"

    if not log_file.exists():
        return []

    entries = []
    with open(log_file) as f:
        for line in f:
            if line.strip():
                entry = json.loads(line)

                # Apply filters
                if event_filter and entry.get("event") != event_filter:
                    continue
                if take_filter and entry.get("take") != take_filter:
                    continue
                if stage_filter and entry.get("stage") != stage_filter:
                    continue

                entries.append(entry)

    return entries


def get_take_cost(story_name: str, take: str) -> float:
    """
    Calculate total cost for a take.

    Args:
        story_name: Story name
        take: Take number

    Returns:
        Total cost in USD
    """
    entries = get_log_entries(story_name, take_filter=take)

    total = 0.0
    for entry in entries:
        if "cost_estimate_usd" in entry:
            total += entry["cost_estimate_usd"]

    return total


def get_stage_iterations(story_name: str, take: str, stage: str) -> list:
    """
    Get all iterations for a stage.

    Args:
        story_name: Story name
        take: Take number
        stage: Stage name

    Returns:
        List of iteration entries
    """
    entries = get_log_entries(story_name, take_filter=take, stage_filter=stage)

    # Group by iteration
    iterations = {}
    for entry in entries:
        iter_num = entry.get("iteration")
        if iter_num:
            if iter_num not in iterations:
                iterations[iter_num] = []
            iterations[iter_num].append(entry)

    return iterations


def log_assembly(
    story_name: str,
    take: str,
    iteration: str,
    scene_count: int,
    duration: float,
    size_mb: float
) -> None:
    """Log video assembly completion."""
    data = {
        "action": "assemble_video",
        "scene_count": scene_count,
        "duration_seconds": round(duration, 2),
        "size_mb": round(size_mb, 2),
        "status": "completed"
    }
    log_event(story_name, "assembly", data, take=take, stage="13-assembly", iteration=iteration)
