"""
统一客户端（与 npm Client 对齐）。
所有服务共享同一 TokenStorage；set_token / set_user_context 等会作用于全部服务。
"""
from .types import ClientConfig, UserContext, create_memory_token_storage
from .auth_service import AuthService
from .msg_service import MsgService
from .user_service import UserService
from .token_service import TokenService
from .file_service import FileService
from .ai_service import AiService
from .aigc_service import AigcService
from .provider_service import ProviderService
from .usage_service import UsageService
from .audit_service import AuditLogService
from .fronthost_service import FrontHostService
from .org_service import OrgService
from .delivery_stream_service import DeliveryStreamService
from .ez_ability_service import EzAbilityService
from .im_service import ImService
from .hub_service import HubService
from .task_service import TaskService
from .notes_service import NotesService
from .memory_service import MemoryService
from .chat_service import ChatService


class Client:
    """Qing 平台统一 SDK 入口，与 npm 版 qing-client 对齐。"""

    def __init__(self, config: ClientConfig) -> None:
        self.config = config
        storage = config.token_storage or create_memory_token_storage()

        self.auth = AuthService(config, storage)
        self.msg = MsgService(config, storage)
        self.user = UserService(config, storage)
        self.token = TokenService(config, storage)
        self.file = FileService(config, storage)
        self.ai = AiService(config, storage)
        self.aigc = AigcService(config, storage)
        self.provider = ProviderService(config, storage)
        self.usage = UsageService(config, storage)
        self.audit = AuditLogService(config, storage)
        self.fronthost = FrontHostService(config, storage)
        self.org = OrgService(config, storage)
        self.delivery_stream = DeliveryStreamService(config, storage)
        self.ez_ability = EzAbilityService(config, storage)
        self.im = ImService(config, storage)
        self.hub = HubService(config, storage)
        self.task = TaskService(config, storage)
        self.notes = NotesService(config, storage)
        self.memory = MemoryService(config, storage)
        self.chat = ChatService(config, storage)

        self._services = [
            self.auth, self.msg, self.user, self.token, self.file,
            self.ai, self.aigc, self.provider, self.usage, self.audit,
            self.fronthost, self.org, self.delivery_stream, self.ez_ability,
            self.im, self.hub, self.task, self.notes, self.memory, self.chat,
        ]

        self._services_dict = {
            "auth": self.auth,
            "msg": self.msg,
            "user": self.user,
            "token": self.token,
            "file": self.file,
            "ai": self.ai,
            "aigc": self.aigc,
            "provider": self.provider,
            "usage": self.usage,
            "audit": self.audit,
            "fronthost": self.fronthost,
            "org": self.org,
            "delivery_stream": self.delivery_stream,
            "ez_ability": self.ez_ability,
            "im": self.im,
            "hub": self.hub,
            "task": self.task,
            "notes": self.notes,
            "memory": self.memory,
            "chat": self.chat,
        }

    @property
    def services(self) -> dict:
        """按名称访问服务（与 npm client.services 对齐）。"""
        return self._services_dict

    def set_token(self, token: str) -> "Client":
        for s in self._services:
            s.set_token(token)
        return self

    def clear_token(self) -> "Client":
        for s in self._services:
            s.clear_token()
        return self

    def set_user_context(self, context: UserContext) -> "Client":
        for s in self._services:
            s.set_user_context(context)
        return self

    def set_project_id(self, project_id: str) -> "Client":
        for s in self._services:
            s.set_project_id(project_id)
        return self

    def set_app_id(self, app_id: str) -> "Client":
        for s in self._services:
            s.set_app_id(app_id)
        return self

    def set_org_id(self, org_id: str) -> "Client":
        for s in self._services:
            s.set_org_id(org_id)
        return self

    def set_project_and_app(self, project_id: str, app_id: str) -> "Client":
        for s in self._services:
            s.set_project_and_app(project_id, app_id)
        return self

    def set_project_org_app(
        self,
        project_id: str,
        org_id: str,
        app_id: str,
    ) -> "Client":
        for s in self._services:
            s.set_project_org_app(project_id, org_id, app_id)
        return self
