"""
NotificationHub – Facade Pattern.

The single entry point users interact with.  Hides all internal complexity
(backends, repository, service, signal registry) behind a clean, minimal API.

Typical usage::

    from django_notify_hub import notify

    # One user
    notify.send(
        title={"en": "Welcome!", "ar": "أهلاً!"},
        body={"en": "Thanks for signing up."},
        recipient=user,
        related_object=user,
    )

    # Many users
    notify.send_many(
        title={"en": "System alert"},
        body={"en": "Scheduled maintenance tonight."},
        recipients=User.objects.filter(is_staff=True),
        related_object=None,
    )

    # Auto-send on model create
    notify.on_create(
        app_label="orders", model_name="Order",
        title=lambda o: {"en": f"Order #{o.pk} received"},
        body={"en": "We are processing your order."},
        recipients="customer",
    )

    # Auto-send on model update (with condition)
    notify.on_update(
        app_label="orders", model_name="Order",
        title={"en": "Order status changed"},
        body=lambda o: {"en": f"Your order is now {o.status}"},
        recipients="customer",
        condition=lambda old, new: old.status != new.status,
    )
"""
from __future__ import annotations

from typing import Any, Callable

from django_notify_hub.types import (
    BodyArg,
    DataArg,
    NotificationPayload,
    NotificationPriority,
    NotificationChannel,
    TitleArg,
)


class NotificationHub:
    """
    Facade over NotificationService and SignalRegistry.

    Instantiate once and reuse, or use the module-level ``notify`` singleton.
    """

    def __init__(self) -> None:
        from django_notify_hub.services.notification import NotificationService

        self._service = NotificationService()

    def send(
        self,
        title: TitleArg,
        body: BodyArg,
        recipient: Any,
        related_object: Any = None,
        data: DataArg = None,
        priority: NotificationPriority = NotificationPriority.NORMAL,
        channels: tuple[NotificationChannel, ...] = (NotificationChannel.FCM,),
    ) -> None:
        """Send a notification to a single user."""
        obj = related_object if related_object is not None else recipient
        payload = NotificationPayload.build(
            title=title, body=body, related_object=obj,
            data=data, priority=priority, channels=channels,
        )
        self._service.send(payload, recipient)

    def send_many(
        self,
        title: TitleArg,
        body: BodyArg,
        recipients: Any,
        related_object: Any = None,
        data: DataArg = None,
        priority: NotificationPriority = NotificationPriority.NORMAL,
        channels: tuple[NotificationChannel, ...] = (NotificationChannel.FCM,),
    ) -> None:
        """Send a notification to many users."""
        obj = related_object if related_object is not None else object()
        payload = NotificationPayload.build(
            title=title, body=body, related_object=obj,
            data=data, priority=priority, channels=channels,
        )
        self._service.send_many(payload, recipients)

    def on_create(
        self,
        app_label: str,
        model_name: str,
        title: TitleArg,
        body: BodyArg,
        recipients: Any,
        data: DataArg = None,
    ) -> None:
        """Register an auto-notification whenever a new model instance is created."""
        from django_notify_hub.services.registry import SignalRegistry

        SignalRegistry.on_create(
            app_label=app_label, model_name=model_name,
            title=title, body=body, recipients=recipients, data=data,
        )

    def on_update(
        self,
        app_label: str,
        model_name: str,
        title: TitleArg,
        body: BodyArg,
        recipients: Any,
        condition: Callable[[Any, Any], bool] | None = None,
        data: DataArg = None,
    ) -> None:
        """Register an auto-notification when a model instance is updated."""
        from django_notify_hub.services.registry import SignalRegistry

        SignalRegistry.on_update(
            app_label=app_label, model_name=model_name,
            title=title, body=body, recipients=recipients,
            condition=condition, data=data,
        )

