"""SP3b cross-app signal receivers for the marketplace.

Listens on the SP1 ``smehub_business_revoked`` signal (FRSME-OBR029) and
unpublishes every product listing tied to the revoked business so it
disappears from the public catalogue. Open demand responses originated by
the revoked business are also closed so buyers no longer see them.
"""
from __future__ import annotations

import logging

from django.dispatch import receiver
from django.utils import timezone

from apps.smehub.onboarding import signals as onb_signals

logger = logging.getLogger(__name__)


@receiver(onb_signals.smehub_business_revoked, dispatch_uid="smehub.marketplace.revoke_cascade")
def _on_business_revoked(sender, business=None, by_user=None, reason: str = "", **kwargs):
    if business is None:
        return

    from apps.core.notifications.models import Notification
    from apps.smehub._shared.notifications import notify_smehub
    from apps.smehub.marketplace.models import DemandResponse, ProductListing

    Verb = Notification.Verb

    products = ProductListing.objects.filter(
        business=business, status=ProductListing.Status.PUBLISHED,
    ).select_related("business__entrepreneur__user")
    now = timezone.now()
    for product in products:
        ProductListing.objects.filter(pk=product.pk).update(
            status=ProductListing.Status.UNPUBLISHED,
            unpublished_at=now,
        )
        try:
            entrepreneur_user = product.business.entrepreneur.user
            notify_smehub(
                entrepreneur_user,
                message=(
                    f"Product listing \"{product.name}\" was unpublished "
                    f"because the underlying business profile was revoked."
                ),
                verb=Verb.SMEHUB_BUSINESS_REVOKED,
                target=product,
            )
        except Exception:
            logger.exception("Cascade notification failed for product %s", product.pk)

    open_responses = DemandResponse.objects.filter(
        business=business,
        status__in=[
            DemandResponse.Status.SUBMITTED,
            DemandResponse.Status.SHORTLISTED,
        ],
    ).select_related("business__entrepreneur__user", "demand_listing")
    for response in open_responses:
        DemandResponse.objects.filter(pk=response.pk).update(
            status=DemandResponse.Status.WITHDRAWN,
            updated_at=now,
        )
        try:
            entrepreneur_user = response.business.entrepreneur.user
            listing_title = getattr(response.demand_listing, "title", "(unknown)")
            notify_smehub(
                entrepreneur_user,
                message=(
                    f"Your response to demand listing \"{listing_title}\" "
                    f"was withdrawn because the underlying business profile was revoked."
                ),
                verb=Verb.SMEHUB_BUSINESS_REVOKED,
                target=response,
            )
        except Exception:
            logger.exception("Cascade notification failed for demand response %s", response.pk)
