"""Catalog Engine — signal handlers.

Subscribes to catalog domain events and performs side-effects:
- Activity feed recording
- Notification dispatch
- AI description generation (async)
"""

from __future__ import annotations

from simorgh.apps.events.bus import subscribe


# ── Activity Feed ───────────────────────────────────────────────────────────

def _record_activity(verb: str, payload: dict) -> None:
    try:
        from django.contrib.contenttypes.models import ContentType

        from simorgh.apps.catalog.models import CatalogItem
        from simorgh.apps.platform_core.models import Activity

        item_id = payload.get("item_id")
        tenant_id = payload.get("tenant_id")
        actor_id = payload.get("actor_id")

        if not item_id or not tenant_id:
            return

        item = CatalogItem.objects.filter(public_id=item_id, tenant_id=tenant_id).first()
        if not item:
            return

        Activity.objects.create(
            tenant_id=tenant_id,
            organization_node_id=item.organization_node_id,
            actor_id=actor_id,
            verb=f"catalog.{verb}",
            content_type=ContentType.objects.get_for_model(CatalogItem),
            object_id=item.pk,
            occurred_at=item.updated_at,
            extra={
                "name": item.name,
                "catalog_type": item.catalog_type,
                "public_id": str(item.public_id),
            },
        )
    except Exception:
        import structlog
        _log = structlog.get_logger("simorgh.catalog.signals")
        _log.warning("catalog.activity_record_failed", payload=payload, exc_info=True)


# ── Notification Dispatch ───────────────────────────────────────────────────

def _send_notification(event_name: str, payload: dict) -> None:
    """Send in-app notification for catalog events via Notification Engine."""
    try:
        from simorgh.apps.notifications.services import send_notification

        item_id = payload.get("item_id")
        tenant_id = payload.get("tenant_id")
        actor_id = payload.get("actor_id")
        item_name = payload.get("name", "")

        if not item_id or not tenant_id:
            return

        notification_key = f"catalog.{event_name}"
        send_notification(
            tenant_id=tenant_id,
            actor_id=actor_id,
            key=notification_key,
            context={
                "item_id": item_id,
                "item_name": item_name,
            },
        )
    except Exception:
        import structlog
        _log = structlog.get_logger("simorgh.catalog.signals")
        _log.debug("catalog.notification_skipped", event=event_name, exc_info=True)


# ── AI Description Generation (async) ───────────────────────────────────────

def _trigger_ai_description(item_id: str, tenant_id: int, name: str) -> None:
    """Trigger async AI description generation for a new catalog item."""
    try:
        from simorgh.apps.catalog.tasks import ai_generate_description
        ai_generate_description.delay(item_id=item_id, tenant_id=tenant_id)
    except Exception:
        import structlog
        _log = structlog.get_logger("simorgh.catalog.signals")
        _log.debug("catalog.ai_task_enqueue_failed", item_id=item_id, exc_info=True)


# ── Subscriptions ───────────────────────────────────────────────────────────

@subscribe("catalog.item_created")
def _on_item_created(payload: dict) -> None:
    _record_activity("created", payload)
    _send_notification("item_created", payload)
    _trigger_ai_description(
        payload.get("item_id", ""),
        payload.get("tenant_id", 0),
        payload.get("name", ""),
    )


@subscribe("catalog.item_published")
def _on_item_published(payload: dict) -> None:
    _record_activity("published", payload)
    _send_notification("item_published", payload)


@subscribe("catalog.item_retired")
def _on_item_retired(payload: dict) -> None:
    _record_activity("retired", payload)


@subscribe("catalog.item_submitted_for_review")
def _on_item_submitted_for_review(payload: dict) -> None:
    _record_activity("submitted_for_review", payload)
    _send_notification("item_submitted_for_review", payload)


@subscribe("catalog.category_created")
def _on_category_created(payload: dict) -> None:
    _send_notification("category_created", payload)


@subscribe("catalog.category_updated")
def _on_category_updated(payload: dict) -> None:
    _send_notification("category_updated", payload)
