"""记忆服务（聊天记录等持久化），与 npm MemoryService / memory-service API 对齐。"""
from typing import Any, Optional

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


class MemoryService(BaseClient):
    service_path = "memory"

    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 "memory"

    def create_message(
        self,
        body: dict,
        options: Optional[RequestOptions] = None,
    ) -> Any:
        """写入一条消息（幂等）。POST /api/v1/messages"""
        opts = RequestOptions(method="POST", body=body)
        if options:
            opts.headers = options.headers or opts.headers
            opts.params = options.params or opts.params
            opts.user_context = options.user_context or opts.user_context
        return self.request("/api/v1/messages", opts)

    def list_room_messages(
        self,
        room_id: str,
        source: str,
        limit: Optional[int] = None,
        cursor: Optional[str] = None,
        direction: Optional[str] = None,
        msg_type: Optional[str] = None,
        options: Optional[RequestOptions] = None,
    ) -> dict:
        """分页拉取房间消息（游标分页）。GET /api/v1/rooms/:roomId/messages"""
        params = {"source": source}
        if limit is not None:
            params["limit"] = limit
        if cursor is not None:
            params["cursor"] = cursor
        if direction is not None:
            params["direction"] = direction
        if msg_type is not None:
            params["msg_type"] = msg_type
        opts = RequestOptions(method="GET", params=params)
        if options:
            opts.params = options.params or opts.params
        res = self.request_with_pagination(
            f"/api/v1/rooms/{room_id}/messages",
            opts,
        )
        return {
            "items": res.get("data") or [],
            "next_cursor": (res.get("pagination") or {}).get("cursor"),
            "has_more": (res.get("pagination") or {}).get("has_more", False),
        }

    def get_last_message(
        self,
        room_id: str,
        source: str,
        options: Optional[RequestOptions] = None,
    ) -> Any:
        """获取房间某 source 下最后一条消息。GET /api/v1/rooms/:roomId/last-message"""
        return self.request(
            f"/api/v1/rooms/{room_id}/last-message",
            RequestOptions(method="GET", params={"source": source})
            if options is None
            else options,
        )

    # ─── Room 管理 ─────────────────────────────────────────────────────────────

    def list_rooms(
        self,
        tenant_id: Optional[str] = None,
        source_provider: Optional[str] = None,
        page: Optional[int] = None,
        page_size: Optional[int] = None,
        options: Optional[RequestOptions] = None,
    ) -> dict:
        """列出所有房间（分页，按创建时间倒序）。GET /api/v1/rooms
        不传 tenant_id 则返回全部房间（需超管/管理员权限）。
        返回 {"items": [...], "total": int, "page": int, "page_size": int}
        """
        params: dict = {}
        if tenant_id is not None:
            params["tenant_id"] = tenant_id
        if source_provider is not None:
            params["source_provider"] = source_provider
        if page is not None:
            params["page"] = page
        if page_size is not None:
            params["page_size"] = page_size
        return self.request(
            "/api/v1/rooms",
            RequestOptions(method="GET", params=params),
        )

    def create_room(
        self,
        name: str,
        options: Optional[RequestOptions] = None,
    ) -> Any:
        """创建内部自建房间。POST /api/v1/rooms"""
        return self.request(
            "/api/v1/rooms",
            RequestOptions(method="POST", body={"name": name}),
        )

    def ensure_external_room(
        self,
        source_provider: str,
        source_room_id: str,
        name: str,
        options: Optional[RequestOptions] = None,
    ) -> Any:
        """惰性初始化外部房间映射（首次调用时自动创建并绑定来源）。
        POST /api/v1/rooms/ensure-external
        返回 {"room_id": str}
        """
        return self.request(
            "/api/v1/rooms/ensure-external",
            RequestOptions(
                method="POST",
                body={
                    "source_provider": source_provider,
                    "source_room_id": source_room_id,
                    "name": name,
                },
            ),
        )

    def get_room(
        self,
        room_id: str,
        options: Optional[RequestOptions] = None,
    ) -> Any:
        """获取房间信息（调用者须为成员）。GET /api/v1/rooms/:roomId"""
        return self.request(
            f"/api/v1/rooms/{room_id}",
            RequestOptions(method="GET"),
        )

    def list_room_members(
        self,
        room_id: str,
        options: Optional[RequestOptions] = None,
    ) -> Any:
        """获取房间成员列表。GET /api/v1/rooms/:roomId/members"""
        return self.request(
            f"/api/v1/rooms/{room_id}/members",
            RequestOptions(method="GET"),
        )

    def add_room_member(
        self,
        room_id: str,
        user_id: str,
        role: str = "MEMBER",
        options: Optional[RequestOptions] = None,
    ) -> Any:
        """添加单个房间成员。POST /api/v1/rooms/:roomId/members
        role: 'OWNER' | 'ADMIN' | 'MEMBER'
        """
        return self.request(
            f"/api/v1/rooms/{room_id}/members",
            RequestOptions(method="POST", body={"user_id": user_id, "role": role}),
        )

    def remove_room_member(
        self,
        room_id: str,
        user_id: str,
        options: Optional[RequestOptions] = None,
    ) -> Any:
        """移除房间成员。DELETE /api/v1/rooms/:roomId/members/:userId"""
        return self.request(
            f"/api/v1/rooms/{room_id}/members/{user_id}",
            RequestOptions(method="DELETE"),
        )

    def sync_room_members(
        self,
        room_id: str,
        members: list,
        options: Optional[RequestOptions] = None,
    ) -> Any:
        """全量同步房间成员（以传入列表为准，多余成员将被移除）。
        PUT /api/v1/rooms/:roomId/members/sync
        members: [{"user_id": str, "role": str}, ...]
        """
        return self.request(
            f"/api/v1/rooms/{room_id}/members/sync",
            RequestOptions(method="PUT", body={"members": members}),
        )
