"""Framework-neutral async client for IHM Moderation API.

This module has no Telegram framework dependency. A host bot can use it from
aiogram, TeleBot, Pyrogram, a custom webhook service, or another Python stack.
"""

from __future__ import annotations

from dataclasses import dataclass
from typing import Any

import httpx


@dataclass(frozen=True)
class IHMClientSettings:
    api_key: str
    base_url: str = "https://ihm.thebeautifulmusic.ru"
    timeout_seconds: int = 55


class IHMClient:
    def __init__(
        self,
        api_key: str,
        base_url: str = "https://ihm.thebeautifulmusic.ru",
        timeout_seconds: int = 55,
    ):
        self.settings = IHMClientSettings(api_key, base_url.rstrip("/"), timeout_seconds)

    async def request(
        self, method: str, path: str, payload: dict[str, Any] | None = None
    ) -> dict[str, Any]:
        async with httpx.AsyncClient(timeout=self.settings.timeout_seconds) as client:
            response = await client.request(
                method,
                self.settings.base_url + path,
                headers={"Authorization": f"Bearer {self.settings.api_key}"},
                json=payload,
            )
            response.raise_for_status()
            return response.json()

    async def register_bot(self, bot_id: int, bot_username: str) -> dict[str, Any]:
        return await self.request(
            "POST", "/v1/register", {"bot_id": bot_id, "bot_username": bot_username}
        )

    async def check(self, event: dict[str, Any]) -> dict[str, Any]:
        """Submit a message, edited_message, reaction, or profile event."""
        return await self.request("POST", "/v1/check", event)

    async def get_bindings(self) -> dict[str, Any]:
        return await self.request("GET", "/v1/bindings")

    async def save_bindings(self, bindings: dict[str, Any]) -> dict[str, Any]:
        return await self.request("POST", "/v1/bindings", bindings)

    async def save_telegram_state(
        self, incident_id: str, state: dict[str, Any]
    ) -> dict[str, Any]:
        return await self.request(
            "PUT", f"/v1/incidents/{incident_id}/telegram-state", {"state": state}
        )

    async def decide(
        self, incident_id: str, decision: str, decided_by: int
    ) -> dict[str, Any]:
        return await self.request(
            "POST",
            f"/v1/incidents/{incident_id}/decision",
            {"decision": decision, "decided_by": decided_by},
        )

    async def technical_event(
        self, event: str, details: str = "", level: str = "error"
    ) -> dict[str, Any]:
        return await self.request(
            "POST",
            "/v1/technical-events",
            {"event": event, "details": details[:4000], "level": level},
        )
