"""Клиент открытого API чата v1 (Python 3, только стандартная библиотека). Вызывайте с сервера, ключ — секрет."""
import json
import urllib.error
import urllib.request


class ChatApiError(Exception):
    def __init__(self, status: int, code: str, message: str):
        super().__init__(f"{status} {code}: {message}")
        self.status, self.code = status, code


class ChatApi:
    def __init__(self, host: str, key: str):
        self.base = f"https://{host}/v1.php"
        self.key = key

    def _call(self, route: str, params: dict | None = None, body: dict | None = None) -> dict:
        q = "&".join([f"r={route}"] + [f"{k}={v}" for k, v in (params or {}).items()])
        req = urllib.request.Request(f"{self.base}?{q}", method="POST" if body is not None else "GET",
                                     data=json.dumps(body, ensure_ascii=False).encode() if body is not None else None,
                                     headers={"Authorization": f"Bearer {self.key}", "Content-Type": "application/json"})
        try:
            with urllib.request.urlopen(req, timeout=15) as r:
                return json.load(r)
        except urllib.error.HTTPError as e:
            data = json.load(e)
            raise ChatApiError(e.code, data.get("code", ""), data.get("error", "")) from None

    def rooms(self) -> list:
        return self._call("rooms")["rooms"]

    def messages(self, room: str, after_id: int = 0, limit: int = 50) -> dict:
        return self._call("messages", {"room": room, "after_id": after_id, "limit": limit})

    def send(self, room: str, text: str, author_name: str = "", reply_to_id: int = 0) -> dict:
        return self._call("messages", body={"room": room, "body": text, "author_name": author_name,
                                            "reply_to_id": reply_to_id or None})["message"]


if __name__ == "__main__":
    api = ChatApi("chat.example.ru", "rgpc_ВАШ_КЛЮЧ")
    print(api.rooms())
    print(api.send("c_1", "Новый заказ №1234 оформлен", author_name="Магазин"))
