from __future__ import annotations

import json
from dataclasses import dataclass, field
from typing import Any


@dataclass(slots=True)
class CdpClient:
    websocket_url: str
    _socket: Any = field(default=None, init=False, repr=False)
    _next_id: int = field(default=1, init=False, repr=False)

    def connect(self) -> None:
        if self._socket is not None:
            return
        try:
            import websocket  # type: ignore
        except ImportError as exc:
            raise RuntimeError(
                "CDP websocket support requires the optional 'websocket-client' dependency. "
                "Install with: pip install chaser-sdk[cdp]"
            ) from exc

        self._socket = websocket.create_connection(self.websocket_url)

    def close(self) -> None:
        if self._socket is not None:
            self._socket.close()
            self._socket = None

    def send(self, method: str, params: dict[str, Any] | None = None, session_id: str | None = None) -> Any:
        if self._socket is None:
            raise RuntimeError("CDP websocket is not connected")

        message = {
            "id": self._next_id,
            "method": method,
            "params": params or {},
        }
        if session_id:
            message["sessionId"] = session_id
        request_id = self._next_id
        self._next_id += 1

        self._socket.send(json.dumps(message))
        while True:
            raw = self._socket.recv()
            payload = json.loads(raw)
            if payload.get("id") != request_id:
                continue
            if "error" in payload:
                raise RuntimeError(payload["error"].get("message", "CDP request failed"))
            return payload.get("result")
