"""Permission/escalation chain notifier.

The notify tier broadcasts a ws event the renderer picks up. The text/call
tiers route through the cloud SMS bridge once enabled; until it's enabled
we fall back to an extra ws notify with a `fallback: true` marker so the
renderer can label it honestly ("Text-me fallback: cloud SMS not wired").
The *when* of escalation is owned by apps/workflows/escalation.py.
"""

import logging
from datetime import datetime

from backend.apps.workflows.models import PermissionTier, Workflow, WorkflowRun

logger = logging.getLogger(__name__)


def _base_payload(wf: Workflow, run: WorkflowRun) -> dict:
    return {
        "workflow_id": wf.id,
        "workflow_title": wf.title,
        "run_id": run.id,
        "status": run.status,
        "session_id": run.session_id,
        "started_at": run.started_at.isoformat() if isinstance(run.started_at, datetime) else run.started_at,
        "finished_at": run.finished_at.isoformat() if isinstance(run.finished_at, datetime) else run.finished_at,
    }


async def notify_run_complete(wf: Workflow, run: WorkflowRun) -> None:
    from backend.apps.agents.core.ws_manager import ws_manager
    from backend.apps.workflows import escalation

    payload = _base_payload(wf, run)
    await ws_manager.broadcast_global("workflow:notify", payload)

    # Kick off server-side escalation only if there are additional tiers beyond the default notify. The escalation runner will sleep + call send_tier per tier.
    escalation.schedule(wf, run)


async def send_tier(wf: Workflow, run: WorkflowRun, tier: PermissionTier) -> None:
    """Send a single escalation tier. Today the text/call paths fall back
    to an in-app notify with `fallback: true` and the tier kind set so the
    renderer can show "Text-me fallback (cloud SMS not wired)."
    """
    from backend.apps.agents.core.ws_manager import ws_manager

    payload = _base_payload(wf, run)
    payload["tier_kind"] = tier.kind
    payload["tier_phone"] = (tier.phone or "")[-4:] if tier.phone else None
    payload["fallback"] = True  # flip to False once the cloud SMS bridge is wired
    await ws_manager.broadcast_global("workflow:notify", payload)
    logger.info("workflow tier=%s fallback fired wf=%s run=%s", tier.kind, wf.id, run.id)
