import Foundation

protocol SybilAPIClienting: Sendable {
    func verifySession() async throws -> AuthSession
    func listWorkspaceItems() async throws -> [WorkspaceItem]
    func listChats() async throws -> [ChatSummary]
    func createChat(
        title: String?,
        provider: Provider?,
        model: String?,
        messages: [CompletionRequestMessage]?
    ) async throws -> ChatSummary
    func getChat(chatID: String) async throws -> ChatDetail
    func forkChat(chatID: String, messageID: String?) async throws -> ChatSummary
    func updateChatTitle(chatID: String, title: String) async throws -> ChatSummary
    func updateChatStar(chatID: String, starred: Bool) async throws -> ChatSummary
    func deleteChat(chatID: String) async throws
    func suggestChatTitle(chatID: String, content: String) async throws -> ChatSummary
    func listSearches() async throws -> [SearchSummary]
    func createSearch(title: String?, query: String?) async throws -> SearchSummary
    func getSearch(searchID: String) async throws -> SearchDetail
    func createChatFromSearch(searchID: String, title: String?) async throws -> ChatSummary
    func updateSearchStar(searchID: String, starred: Bool) async throws -> SearchSummary
    func deleteSearch(searchID: String) async throws
    func listModels() async throws -> ModelCatalogResponse
    func getActiveRuns() async throws -> ActiveRunsResponse
    func runCompletionStream(
        body: CompletionStreamRequest,
        onEvent: @escaping @Sendable (CompletionStreamEvent) async -> Void
    ) async throws
    func runQuickQuestionStream(
        body: QuickQuestionStreamRequest,
        onEvent: @escaping @Sendable (CompletionStreamEvent) async -> Void
    ) async throws
    func attachCompletionStream(
        chatID: String,
        onEvent: @escaping @Sendable (CompletionStreamEvent) async -> Void
    ) async throws
    func runSearchStream(
        searchID: String,
        body: SearchRunRequest,
        onEvent: @escaping @Sendable (SearchStreamEvent) async -> Void
    ) async throws
    func attachSearchStream(
        searchID: String,
        onEvent: @escaping @Sendable (SearchStreamEvent) async -> Void
    ) async throws
}

extension SybilAPIClienting {
    func createChat(title: String?) async throws -> ChatSummary {
        try await createChat(title: title, provider: nil, model: nil, messages: nil)
    }
}
