"""Executor for ExtractCutawayProposal.

Creates a new cutaway shot file derived from an existing beat.
"""
from __future__ import annotations

import logging
from typing import Optional

from fastapi import HTTPException

from recoil.api.adapters import beats as beats_adapter
from recoil.api.eventbus import BUS

logger = logging.getLogger(__name__)

_SCOPE = "api/executors/extract_cutaway"


def execute(
    from_beat_id: str,
    description: str,
    project_id: Optional[str] = None,
) -> dict:
    """Extract a cutaway shot from an existing beat.

    Args:
        from_beat_id: The source beat to extract from.
        description: Visual description for the cutaway (becomes prompt_override).
        project_id: Optional project slug.

    Returns:
        {"shot_id": str, "cutaway_source": str, "episode_id": str,
         "extract_cutaway_applied": True}

    Raises:
        HTTPException(404): If from_beat_id not found on disk.
    """
    try:
        result = beats_adapter.extract_cutaway(
            from_beat_id=from_beat_id,
            description=description,
            project_id=project_id,
        )
    except KeyError as exc:
        BUS.emit_sync(
            severity="failure",
            scope=_SCOPE,
            summary=f"extract_cutaway_target_not_found: {from_beat_id}",
            payload={"from_beat_id": from_beat_id, "error": str(exc)},
        )
        raise HTTPException(
            status_code=404,
            detail={
                "error": "beat_not_found",
                "from_beat_id": from_beat_id,
                "message": str(exc),
            },
        )
    BUS.emit_sync(
        severity="success",
        scope=_SCOPE,
        summary=f"extract_cutaway_applied: {result['shot_id']}",
        payload={
            **result,
            "from_beat_id": from_beat_id,
            "description_length": len(description),
        },
    )
    return result
