"""ntfy push notification client."""

from __future__ import annotations

import logging
from typing import Any, Final

import aiohttp

from ..http_base import HttpProviderClient

_LOGGER = logging.getLogger(__name__)

_PRIORITY_MIN: Final = 1
_PRIORITY_MAX: Final = 5
_DEFAULT_PRIORITY: Final = 3
_MAX_TAGS: Final = 10
_MAX_TAG_LEN: Final = 64


def _strip_crlf(value: str) -> str:
    """Remove CR/LF — ntfy's JSON path is safe today, but the same fields
    are used by the header API; defensive sanitization here means a future
    refactor can't accidentally re-introduce header injection."""
    return value.replace("\r", " ").replace("\n", " ")


class NtfyClient(HttpProviderClient):
    """Sends push notifications via ntfy server."""

    def __init__(self, session: aiohttp.ClientSession) -> None:
        super().__init__(session, provider_name="ntfy")

    async def send(
        self,
        server_url: str,
        topic: str,
        message: str,
        title: str | None = None,
        priority: int = _DEFAULT_PRIORITY,
        tags: list[str] | None = None,
        click_url: str | None = None,
        auth_token: str | None = None,
        markdown: bool = True,
    ) -> dict[str, Any]:
        """Send a push notification to an ntfy topic."""
        if not server_url or not topic:
            return {"success": False, "error": "Missing server_url or topic"}

        topic = _strip_crlf(topic).strip()
        if not topic:
            return {"success": False, "error": "Topic is empty after sanitization"}

        try:
            priority_int = int(priority) if priority is not None else _DEFAULT_PRIORITY
        except (TypeError, ValueError):
            priority_int = _DEFAULT_PRIORITY
        priority_int = max(_PRIORITY_MIN, min(priority_int, _PRIORITY_MAX))

        payload: dict[str, Any] = {
            "topic": topic,
            "message": message,
            "markdown": bool(markdown),
        }
        if title:
            payload["title"] = _strip_crlf(title)
        if priority_int != _DEFAULT_PRIORITY:
            payload["priority"] = priority_int
        if tags:
            cleaned = [
                _strip_crlf(str(t))[:_MAX_TAG_LEN]
                for t in tags[:_MAX_TAGS]
                if t
            ]
            if cleaned:
                payload["tags"] = cleaned
        if click_url:
            payload["click"] = _strip_crlf(click_url)

        headers: dict[str, str] = {}
        if auth_token:
            headers["Authorization"] = f"Bearer {auth_token}"

        return await self.request("POST", server_url.rstrip("/"), json=payload, headers=headers)
