"""Chat 基础服务（流式对话），与 npm ChatService 对齐。"""
from typing import Any, Callable, Iterator, Optional

from .base_client import BaseClient
from .types import ClientConfig, RequestOptions, TokenStorage


class ChatService(BaseClient):
    service_path = "chat"

    def __init__(
        self,
        config: ClientConfig,
        token_storage: Optional[TokenStorage] = None,
    ) -> None:
        super().__init__(config, token_storage=token_storage)

    @property
    def service_name(self) -> str:
        return "chat"

    def stream_completion(
        self,
        room_id: str,
        message: str,
        system_prompt: Optional[str] = None,
        model: Optional[str] = None,
        options: Optional[RequestOptions] = None,
    ) -> Iterator[dict]:
        """流式对话，yield ChatStreamEvent dict。

        每个 event 格式：
        - ``{"type": "delta", "delta": "..."}``   — 增量文字
        - ``{"type": "done", "usage": {...}}``     — 流结束
        - ``{"type": "error", "error": "..."}``   — 错误

        Example::

            for event in client.chat.stream_completion("room-1", "你好"):
                if event["type"] == "delta":
                    print(event["delta"], end="", flush=True)
                elif event["type"] == "done":
                    print()

        POST /api/chat/completions → 服务内部 /api/v1/chat/completions
        """
        body: dict = {"roomId": room_id, "message": message}
        if system_prompt is not None:
            body["systemPrompt"] = system_prompt
        if model is not None:
            body["model"] = model

        opts = RequestOptions(method="POST", body=body)
        if options:
            opts.headers = options.headers or opts.headers
            opts.user_context = options.user_context or opts.user_context
            opts.project_id = options.project_id or opts.project_id
            opts.app_id = options.app_id or opts.app_id
            opts.org_id = options.org_id or opts.org_id

        yield from self.stream_request("/completions", opts)

    def stream_completion_with_callbacks(
        self,
        room_id: str,
        message: str,
        on_delta: Optional[Callable[[str], None]] = None,
        on_done: Optional[Callable[[str, Any], None]] = None,
        on_error: Optional[Callable[[str], None]] = None,
        system_prompt: Optional[str] = None,
        model: Optional[str] = None,
        options: Optional[RequestOptions] = None,
    ) -> str:
        """回调风格的流式对话，返回完整回复文本。

        Example::

            full = client.chat.stream_completion_with_callbacks(
                "room-1", "你好",
                on_delta=lambda d: print(d, end="", flush=True),
                on_done=lambda full, usage: print("\\n完成"),
            )
        """
        full_reply = ""
        try:
            for event in self.stream_completion(
                room_id, message, system_prompt=system_prompt, model=model, options=options
            ):
                if event.get("type") == "delta":
                    delta = event.get("delta", "")
                    full_reply += delta
                    if on_delta:
                        on_delta(delta)
                elif event.get("type") == "done":
                    if on_done:
                        on_done(full_reply, event.get("usage"))
                elif event.get("type") == "error":
                    if on_error:
                        on_error(event.get("error", "未知错误"))
        except Exception as e:
            if on_error:
                on_error(str(e))
            raise

        return full_reply
