"""W20E2: shot-aware BG readiness report builder.

Pure operator-facing dry-run surface over W20E1 preflight plus explicit
target facts. It performs no network, DB, ImageAsset, or projects writes.
"""
from __future__ import annotations

from dataclasses import dataclass
from typing import Any, Dict, List, Optional

from app.modules.pipeline.shot_aware_bg_preflight import (
    SCOPE_FULL_FRESH_PROJECT_E2E,
    SCOPE_SHOT_AWARE_BG_E2E,
    ShotAwareBgPreflightFailure,
    ShotAwareBgPreflightRequest,
    evaluate_shot_aware_bg_preflight,
)


@dataclass(frozen=True)
class ShotAwareBgReadinessTarget:
    project_id: Optional[str] = None
    episode_id: Optional[str] = None
    planning_doc_present: Optional[bool] = None
    planning_doc_checkpoint_present: Optional[bool] = None


def _failure_to_dict(
    failure: ShotAwareBgPreflightFailure,
) -> Dict[str, Optional[str]]:
    return {
        "code": failure.code,
        "message": failure.message,
        "selector_path": failure.selector_path,
    }


def _target_to_dict(target: ShotAwareBgReadinessTarget) -> Dict[str, Any]:
    return {
        "project_id": target.project_id,
        "episode_id": target.episode_id,
        "planning_doc_present": target.planning_doc_present,
        "planning_doc_checkpoint_present": (
            target.planning_doc_checkpoint_present
        ),
    }


def _target_readiness_blockers(
    *, request: ShotAwareBgPreflightRequest, target: ShotAwareBgReadinessTarget
) -> List[Dict[str, str]]:
    if request.requested_scope not in {
        SCOPE_SHOT_AWARE_BG_E2E,
        SCOPE_FULL_FRESH_PROJECT_E2E,
    }:
        return []

    blockers: List[Dict[str, str]] = []
    if target.planning_doc_present is False:
        blockers.append(
            {
                "code": "planning_doc_missing_for_e2e_scope",
                "message": (
                    "The requested shot-aware image-generating scope needs "
                    "a planning document, but target.planning_doc_present "
                    "was supplied as False."
                ),
            }
        )
    if target.planning_doc_checkpoint_present is False:
        blockers.append(
            {
                "code": "planning_doc_checkpoint_missing_for_e2e_scope",
                "message": (
                    "The requested shot-aware image-generating scope needs "
                    "the planning document checkpoint, but "
                    "target.planning_doc_checkpoint_present was supplied "
                    "as False."
                ),
            }
        )
    return blockers


def build_shot_aware_bg_readiness_report(
    *,
    settings: Any,
    request: ShotAwareBgPreflightRequest,
    target: Optional[ShotAwareBgReadinessTarget] = None,
) -> Dict[str, Any]:
    resolved_target = target or ShotAwareBgReadinessTarget()
    preflight_result = evaluate_shot_aware_bg_preflight(
        settings=settings,
        request=request,
    )
    readiness_blockers = _target_readiness_blockers(
        request=request,
        target=resolved_target,
    )
    return {
        "ok": bool(preflight_result.ok and not readiness_blockers),
        "preflight": {
            "failures": [
                _failure_to_dict(failure)
                for failure in preflight_result.failures
            ],
            "budget_summary": preflight_result.budget_summary,
        },
        "target": _target_to_dict(resolved_target),
        "readiness_blockers": readiness_blockers,
        "real_api_call_counts": {"image": 0, "llm": 0, "vlm": 0},
        "write_counts": {
            "db": 0,
            "image_asset": 0,
            "projects_checkpoint": 0,
        },
    }
