from __future__ import annotations

from dataclasses import dataclass
from typing import Iterable

from .models import AlertEvent
from .ntfy_notifier import NtfyConfig, NtfyNotifier


@dataclass(frozen=True)
class RouteDecision:
    channel: str
    topic: str
    urgent: bool


class NotificationRouter:
    """Route HANZ events to dedicated ntfy channels."""

    ENTRY_ACTIONS = {"AWAL", "SIAGA", "EKSEKUSI"}
    GUARD_ACTIONS = {"TAHAN", "LEPAS", "JUAL"}

    def __init__(
        self,
        *,
        server_url: str,
        base_topic: str,
        token: str | None = None,
        dashboard_url: str | None = None,
    ) -> None:
        self.server_url = server_url.rstrip("/")
        self.base_topic = base_topic.strip()
        self.token = token
        self.dashboard_url = dashboard_url

        if not self.base_topic:
            raise ValueError("base_topic is required")

    def route(self, event: AlertEvent) -> RouteDecision:
        if event.new_action in self.ENTRY_ACTIONS:
            return RouteDecision(
                channel="ENTRY",
                topic=f"{self.base_topic}-ENTRY",
                urgent=event.new_action == "EKSEKUSI",
            )

        if event.new_action in self.GUARD_ACTIONS:
            return RouteDecision(
                channel="GUARD",
                topic=f"{self.base_topic}-GUARD",
                urgent=event.new_action in {"LEPAS", "JUAL"},
            )

        if event.event_type in {"SYSTEM", "SERVER", "FEED"}:
            return RouteDecision(
                channel="SYSTEM",
                topic=f"{self.base_topic}-SYSTEM",
                urgent=True,
            )

        return RouteDecision(
            channel="NEWS",
            topic=f"{self.base_topic}-NEWS",
            urgent=False,
        )

    def notifier_for(self, event: AlertEvent) -> NtfyNotifier:
        decision = self.route(event)
        return NtfyNotifier(
            NtfyConfig(
                server_url=self.server_url,
                topic=decision.topic,
                token=self.token,
                dashboard_url=self.dashboard_url,
            )
        )

    def send(self, event: AlertEvent) -> bool:
        return self.notifier_for(event).send(event)

    def topics(self) -> dict[str, str]:
        return {
            "ENTRY": f"{self.base_topic}-ENTRY",
            "GUARD": f"{self.base_topic}-GUARD",
            "SYSTEM": f"{self.base_topic}-SYSTEM",
            "NEWS": f"{self.base_topic}-NEWS",
        }
