import { BaseHttpClient, type RequestConfig } from './BaseHttpClient';
import {
  ApiRespProviderRequesters,
  ApiRespProviderRequester,
  ApiRespProviderLLMModels,
  ApiRespProviderLLMModel,
  LLMModel,
  ApiRespPipelines,
  Pipeline,
  ApiRespPlatformAdapters,
  ApiRespPlatformAdapter,
  ApiRespPlatformBots,
  ApiRespPlatformBot,
  Bot,
  ApiRespPlugins,
  ApiRespPlugin,
  ApiRespPluginConfig,
  ApiRespExtensions,
  AsyncTaskCreatedResp,
  ApiRespSystemInfo,
  ApiRespAsyncTasks,
  ApiRespUserToken,
  GetPipelineResponseData,
  GetPipelineMetadataResponseData,
  AsyncTask,
  ApiRespWebChatMessages,
  ApiRespKnowledgeBases,
  ApiRespKnowledgeBase,
  KnowledgeBase,
  ApiRespKnowledgeBaseFiles,
  ApiRespKnowledgeBaseRetrieve,
  ApiRespProviderEmbeddingModels,
  ApiRespProviderEmbeddingModel,
  EmbeddingModel,
  ApiRespProviderRerankModels,
  ApiRespProviderRerankModel,
  RerankModel,
  ApiRespPluginSystemStatus,
  ApiRespBoxStatus,
  BoxSessionInfo,
  ApiRespMCPServers,
  ApiRespMCPServer,
  ApiRespMCPResources,
  ApiRespMCPResourceContents,
  MCPServer,
  ApiRespModelProviders,
  ApiRespModelProvider,
  ApiRespScannedProviderModels,
  ModelProvider,
  ApiRespKnowledgeEngines,
  ApiRespParsers,
  RagMigrationStatusResp,
  ApiRespTools,
  ApiRespToolDetail,
  Skill,
  ApiRespSkills,
  ApiRespSkill,
} from '@/app/infra/entities/api';
import { Plugin } from '@/app/infra/entities/plugin';
import type { PluginLogEntry } from '@/app/infra/entities/plugin';
import type { I18nObject } from '@/app/infra/entities/common';
import { GetBotLogsRequest } from '@/app/infra/http/requestParam/bots/GetBotLogsRequest';
import { GetBotLogsResponse } from '@/app/infra/http/requestParam/bots/GetBotLogsResponse';
import type {
  CurrentWorkspace,
  Workspace,
  WorkspaceInvitation,
  WorkspaceInvitationDelivery,
  WorkspaceMembership,
  WorkspaceBootstrapResponse,
  WorkspaceRole,
  WorkspaceSpaceBilling,
} from '@/app/infra/entities/workspace';

/**
 * 后端服务客户端
 * 负责与后端 API 的所有交互
 */
export class BackendClient extends BaseHttpClient {
  constructor(baseURL: string) {
    super(baseURL, false);
  }

  // ============ Provider API ============
  public getProviderRequesters(
    model_type?: string,
  ): Promise<ApiRespProviderRequesters> {
    return this.get('/api/v1/provider/requesters', { type: model_type });
  }

  public getProviderRequester(name: string): Promise<ApiRespProviderRequester> {
    return this.get(`/api/v1/provider/requesters/${name}`);
  }

  public getProviderRequesterIconURL(name: string): string {
    if (this.instance.defaults.baseURL === '/') {
      const url = window.location.href;
      const baseURL = url.split('/').slice(0, 3).join('/');
      return `${baseURL}/api/v1/provider/requesters/${name}/icon`;
    }
    return (
      this.instance.defaults.baseURL +
      `/api/v1/provider/requesters/${name}/icon`
    );
  }

  // ============ Model Providers ============
  public getModelProviders(): Promise<ApiRespModelProviders> {
    return this.get('/api/v1/provider/providers');
  }

  public getModelProvider(uuid: string): Promise<ApiRespModelProvider> {
    return this.get(`/api/v1/provider/providers/${uuid}`);
  }

  public createModelProvider(
    provider: Omit<ModelProvider, 'uuid'>,
  ): Promise<{ uuid: string }> {
    return this.post('/api/v1/provider/providers', provider);
  }

  public updateModelProvider(
    uuid: string,
    provider: Partial<ModelProvider>,
  ): Promise<object> {
    return this.put(`/api/v1/provider/providers/${uuid}`, provider);
  }

  public deleteModelProvider(uuid: string): Promise<object> {
    return this.delete(`/api/v1/provider/providers/${uuid}`);
  }

  public scanProviderModels(
    uuid: string,
    modelType?: 'llm' | 'embedding' | 'rerank',
  ): Promise<ApiRespScannedProviderModels> {
    const params = modelType ? { type: modelType } : {};
    return this.get(`/api/v1/provider/providers/${uuid}/scan-models`, params);
  }

  // ============ Provider Model LLM ============
  public getProviderLLMModels(
    providerUuid?: string,
  ): Promise<ApiRespProviderLLMModels> {
    const params = providerUuid ? { provider_uuid: providerUuid } : {};
    return this.get('/api/v1/provider/models/llm', params);
  }

  public getProviderLLMModel(uuid: string): Promise<ApiRespProviderLLMModel> {
    return this.get(`/api/v1/provider/models/llm/${uuid}`);
  }

  public createProviderLLMModel(
    model: Omit<LLMModel, 'uuid'>,
  ): Promise<{ uuid: string }> {
    return this.post('/api/v1/provider/models/llm', model);
  }

  public deleteProviderLLMModel(uuid: string): Promise<object> {
    return this.delete(`/api/v1/provider/models/llm/${uuid}`);
  }

  public updateProviderLLMModel(
    uuid: string,
    model: LLMModel,
  ): Promise<object> {
    return this.put(`/api/v1/provider/models/llm/${uuid}`, model);
  }

  public testLLMModel(uuid: string, model: LLMModel): Promise<object> {
    return this.post(`/api/v1/provider/models/llm/${uuid}/test`, model);
  }

  // ============ Provider Model Embedding ============
  public getProviderEmbeddingModels(
    providerUuid?: string,
  ): Promise<ApiRespProviderEmbeddingModels> {
    const params = providerUuid ? { provider_uuid: providerUuid } : {};
    return this.get('/api/v1/provider/models/embedding', params);
  }

  public getProviderEmbeddingModel(
    uuid: string,
  ): Promise<ApiRespProviderEmbeddingModel> {
    return this.get(`/api/v1/provider/models/embedding/${uuid}`);
  }

  public createProviderEmbeddingModel(model: EmbeddingModel): Promise<object> {
    return this.post('/api/v1/provider/models/embedding', model);
  }

  public deleteProviderEmbeddingModel(uuid: string): Promise<object> {
    return this.delete(`/api/v1/provider/models/embedding/${uuid}`);
  }

  public updateProviderEmbeddingModel(
    uuid: string,
    model: EmbeddingModel,
  ): Promise<object> {
    return this.put(`/api/v1/provider/models/embedding/${uuid}`, model);
  }

  public testEmbeddingModel(
    uuid: string,
    model: EmbeddingModel,
  ): Promise<object> {
    return this.post(`/api/v1/provider/models/embedding/${uuid}/test`, model);
  }

  // ============ Provider Model Rerank ============
  public getProviderRerankModels(
    providerUuid?: string,
  ): Promise<ApiRespProviderRerankModels> {
    const params = providerUuid ? { provider_uuid: providerUuid } : {};
    return this.get('/api/v1/provider/models/rerank', params);
  }

  public getProviderRerankModel(
    uuid: string,
  ): Promise<ApiRespProviderRerankModel> {
    return this.get(`/api/v1/provider/models/rerank/${uuid}`);
  }

  public createProviderRerankModel(model: RerankModel): Promise<object> {
    return this.post('/api/v1/provider/models/rerank', model);
  }

  public deleteProviderRerankModel(uuid: string): Promise<object> {
    return this.delete(`/api/v1/provider/models/rerank/${uuid}`);
  }

  public updateProviderRerankModel(
    uuid: string,
    model: RerankModel,
  ): Promise<object> {
    return this.put(`/api/v1/provider/models/rerank/${uuid}`, model);
  }

  public testRerankModel(uuid: string, model: RerankModel): Promise<object> {
    return this.post(`/api/v1/provider/models/rerank/${uuid}/test`, model);
  }

  // ============ Pipeline API ============
  public getGeneralPipelineMetadata(): Promise<GetPipelineMetadataResponseData> {
    // as designed, this method will be deprecated, and only for developer to check the prefered config schema
    return this.get('/api/v1/pipelines/_/metadata');
  }

  public getPipelines(
    sortBy?: string,
    sortOrder?: string,
  ): Promise<ApiRespPipelines> {
    const params = new URLSearchParams();
    if (sortBy) params.append('sort_by', sortBy);
    if (sortOrder) params.append('sort_order', sortOrder);
    const queryString = params.toString();
    return this.get(`/api/v1/pipelines${queryString ? `?${queryString}` : ''}`);
  }

  public getPipeline(uuid: string): Promise<GetPipelineResponseData> {
    return this.get(`/api/v1/pipelines/${uuid}`);
  }

  public createPipeline(pipeline: Pipeline): Promise<{
    uuid: string;
  }> {
    return this.post('/api/v1/pipelines', pipeline);
  }

  public updatePipeline(uuid: string, pipeline: Pipeline): Promise<object> {
    return this.put(`/api/v1/pipelines/${uuid}`, pipeline);
  }

  public deletePipeline(uuid: string): Promise<object> {
    return this.delete(`/api/v1/pipelines/${uuid}`);
  }

  public copyPipeline(uuid: string): Promise<{ uuid: string }> {
    return this.post(`/api/v1/pipelines/${uuid}/copy`);
  }

  public getPipelineExtensions(uuid: string): Promise<{
    enable_all_plugins: boolean;
    enable_all_mcp_servers: boolean;
    enable_all_skills: boolean;
    mcp_resource_agent_read_enabled: boolean;
    bound_plugins: Array<{ author: string; name: string }>;
    available_plugins: Plugin[];
    bound_mcp_servers: string[];
    available_mcp_servers: MCPServer[];
    bound_mcp_resources: Array<{
      server_uuid?: string;
      server_name?: string;
      uri: string;
      mode?: string;
      enabled?: boolean;
      max_bytes?: number;
      max_tokens?: number;
    }>;
    bound_skills: string[];
    available_skills: Skill[];
  }> {
    return this.get(`/api/v1/pipelines/${uuid}/extensions`);
  }

  public updatePipelineExtensions(
    uuid: string,
    bound_plugins: Array<{ author: string; name: string }>,
    bound_mcp_servers: string[],
    enable_all_plugins: boolean = true,
    enable_all_mcp_servers: boolean = true,
    bound_skills: string[] = [],
    enable_all_skills: boolean = true,
    bound_mcp_resources?: Array<{
      server_uuid?: string;
      server_name?: string;
      uri: string;
      mode?: string;
      enabled?: boolean;
      max_bytes?: number;
      max_tokens?: number;
    }>,
    mcp_resource_agent_read_enabled?: boolean,
  ): Promise<object> {
    const payload: Record<string, unknown> = {
      bound_plugins,
      bound_mcp_servers,
      enable_all_plugins,
      enable_all_mcp_servers,
      bound_skills,
      enable_all_skills,
    };
    if (bound_mcp_resources !== undefined) {
      payload.bound_mcp_resources = bound_mcp_resources;
    }
    if (mcp_resource_agent_read_enabled !== undefined) {
      payload.mcp_resource_agent_read_enabled = mcp_resource_agent_read_enabled;
    }
    return this.put(`/api/v1/pipelines/${uuid}/extensions`, payload);
  }

  // ============ WebSocket Chat API ============
  public getWebSocketHistoryMessages(
    pipelineId: string,
    sessionType: string,
  ): Promise<ApiRespWebChatMessages> {
    return this.get(
      `/api/v1/pipelines/${pipelineId}/ws/messages/${sessionType}`,
    );
  }

  public async uploadWebSocketImage(
    pipelineId: string,
    imageFile: File,
  ): Promise<{ file_key: string }> {
    const formData = new FormData();
    formData.append('file', imageFile);

    return this.postFile(`/api/v1/files/images`, formData);
  }

  public resetWebSocketSession(
    pipelineId: string,
    sessionType: string,
  ): Promise<{ message: string }> {
    return this.post(`/api/v1/pipelines/${pipelineId}/ws/reset/${sessionType}`);
  }

  public getWebSocketConnections(pipelineId: string): Promise<{
    stats: {
      total_connections: number;
      pipelines: number;
      connections_by_pipeline: Record<string, number>;
      connections_by_session_type: Record<string, number>;
    };
    connections: Array<{
      connection_id: string;
      session_type: string;
      created_at: string;
      last_active: string;
      is_active: boolean;
    }>;
  }> {
    return this.get(`/api/v1/pipelines/${pipelineId}/ws/connections`);
  }

  public broadcastWebSocketMessage(
    pipelineId: string,
    message: string,
  ): Promise<{ message: string }> {
    return this.post(`/api/v1/pipelines/${pipelineId}/ws/broadcast`, {
      message,
    });
  }

  // ============ Platform API ============
  public getAdapters(): Promise<ApiRespPlatformAdapters> {
    return this.get('/api/v1/platform/adapters');
  }

  public getAdapter(name: string): Promise<ApiRespPlatformAdapter> {
    return this.get(`/api/v1/platform/adapters/${name}`);
  }

  public getAdapterIconURL(name: string): string {
    if (this.instance.defaults.baseURL === '/') {
      // 获取用户访问的URL
      const url = window.location.href;
      const baseURL = url.split('/').slice(0, 3).join('/');
      return `${baseURL}/api/v1/platform/adapters/${name}/icon`;
    }
    return (
      this.instance.defaults.baseURL + `/api/v1/platform/adapters/${name}/icon`
    );
  }

  // ============ Platform Bots ============
  public getBots(): Promise<ApiRespPlatformBots> {
    return this.get('/api/v1/platform/bots');
  }

  public getBot(uuid: string): Promise<ApiRespPlatformBot> {
    return this.get(`/api/v1/platform/bots/${uuid}`);
  }

  public createBot(bot: Bot): Promise<{ uuid: string }> {
    return this.post('/api/v1/platform/bots', bot);
  }

  public updateBot(uuid: string, bot: Bot): Promise<object> {
    return this.put(`/api/v1/platform/bots/${uuid}`, bot);
  }

  public deleteBot(uuid: string): Promise<object> {
    return this.delete(`/api/v1/platform/bots/${uuid}`);
  }

  public getBotAdmins(botId: string): Promise<{
    admins: Array<{ id: number; launcher_type: string; launcher_id: string }>;
  }> {
    return this.get(`/api/v1/platform/bots/${botId}/admins`);
  }

  public addBotAdmin(
    botId: string,
    launcher_type: string,
    launcher_id: string,
  ): Promise<{ id: number }> {
    return this.post(`/api/v1/platform/bots/${botId}/admins`, {
      launcher_type,
      launcher_id,
    });
  }

  public deleteBotAdmin(botId: string, adminId: number): Promise<object> {
    return this.delete(`/api/v1/platform/bots/${botId}/admins/${adminId}`);
  }

  public getBotLogs(
    botId: string,
    request: GetBotLogsRequest,
  ): Promise<GetBotLogsResponse> {
    return this.post(`/api/v1/platform/bots/${botId}/logs`, request);
  }

  public testHttpBotInbound(
    botId: string,
    message: string,
  ): Promise<{ session_id: string; accepted_message_id: string }> {
    return this.post(`/api/v1/platform/bots/${botId}/test-inbound`, {
      message,
    });
  }

  public getBotSessions(
    botId: string,
    options: {
      limit: number;
      offset: number;
      startTime?: string;
      endTime?: string;
      userQuery?: string;
    },
  ): Promise<{
    sessions: Array<{
      session_id: string;
      bot_id: string;
      bot_name: string;
      pipeline_id: string;
      pipeline_name: string;
      message_count: number;
      start_time: string;
      last_activity: string;
      is_active: boolean;
      platform: string | null;
      user_id: string | null;
      user_name: string | null;
    }>;
    total: number;
  }> {
    const queryParams = new URLSearchParams();
    queryParams.append('botId', botId);
    queryParams.append('limit', options.limit.toString());
    queryParams.append('offset', options.offset.toString());
    if (options.startTime) {
      queryParams.append('startTime', options.startTime);
    }
    if (options.endTime) {
      queryParams.append('endTime', options.endTime);
    }
    if (options.userQuery) {
      queryParams.append('userQuery', options.userQuery);
    }
    return this.get(`/api/v1/monitoring/sessions?${queryParams.toString()}`);
  }

  public getSessionMessages(
    sessionId: string,
    limit: number = 200,
    offset: number = 0,
  ): Promise<{
    messages: Array<{
      id: string;
      timestamp: string;
      bot_id: string;
      bot_name: string;
      pipeline_id: string;
      pipeline_name: string;
      message_content: string;
      session_id: string;
      status: string;
      level: string;
      platform: string | null;
      user_id: string | null;
      user_name: string | null;
      runner_name: string | null;
      variables: string | null;
      role: string | null;
    }>;
    total: number;
  }> {
    const queryParams = new URLSearchParams();
    queryParams.append('sessionId', sessionId);
    queryParams.append('limit', limit.toString());
    queryParams.append('offset', offset.toString());
    return this.get(`/api/v1/monitoring/messages?${queryParams.toString()}`);
  }

  // ============ File management API ============
  public uploadDocumentFile(file: File): Promise<{ file_id: string }> {
    const formData = new FormData();
    formData.append('file', file);

    return this.request<{ file_id: string }>({
      method: 'post',
      url: '/api/v1/files/documents',
      data: formData,
      headers: {
        'Content-Type': 'multipart/form-data',
      },
    });
  }

  // ============ Knowledge Base API ============
  public getKnowledgeBases(): Promise<ApiRespKnowledgeBases> {
    return this.get('/api/v1/knowledge/bases');
  }

  public getKnowledgeBase(uuid: string): Promise<ApiRespKnowledgeBase> {
    return this.get(`/api/v1/knowledge/bases/${uuid}`);
  }

  public createKnowledgeBase(base: KnowledgeBase): Promise<{ uuid: string }> {
    return this.post('/api/v1/knowledge/bases', base);
  }

  public updateKnowledgeBase(
    uuid: string,
    base: KnowledgeBase,
  ): Promise<{ uuid: string }> {
    return this.put(`/api/v1/knowledge/bases/${uuid}`, base);
  }

  public uploadKnowledgeBaseFile(
    uuid: string,
    file_id: string,
    parserPluginId?: string,
  ): Promise<object> {
    return this.post(`/api/v1/knowledge/bases/${uuid}/files`, {
      file_id,
      parser_plugin_id: parserPluginId,
    });
  }

  public getKnowledgeBaseFiles(
    uuid: string,
  ): Promise<ApiRespKnowledgeBaseFiles> {
    return this.get(`/api/v1/knowledge/bases/${uuid}/files`);
  }

  public deleteKnowledgeBaseFile(
    uuid: string,
    file_id: string,
  ): Promise<object> {
    return this.delete(`/api/v1/knowledge/bases/${uuid}/files/${file_id}`);
  }

  public deleteKnowledgeBase(uuid: string): Promise<object> {
    return this.delete(`/api/v1/knowledge/bases/${uuid}`);
  }

  public retrieveKnowledgeBase(
    uuid: string,
    query: string,
    retrievalSettings?: Record<string, unknown>,
  ): Promise<ApiRespKnowledgeBaseRetrieve> {
    return this.post(`/api/v1/knowledge/bases/${uuid}/retrieve`, {
      query,
      retrieval_settings: retrievalSettings ?? {},
    });
  }

  // ============ Knowledge Engines API ============
  public getKnowledgeEngines(): Promise<ApiRespKnowledgeEngines> {
    return this.get('/api/v1/knowledge/engines');
  }

  // ============ Parsers API ============
  public listParsers(mimeType?: string): Promise<ApiRespParsers> {
    const params = mimeType ? `?mime_type=${encodeURIComponent(mimeType)}` : '';
    return this.get(`/api/v1/knowledge/parsers${params}`);
  }

  // ============ Extensions API ============
  public getExtensions(): Promise<ApiRespExtensions> {
    return this.get('/api/v1/extensions');
  }

  // ============ Plugins API ============
  public getPlugins(): Promise<ApiRespPlugins> {
    return this.get('/api/v1/plugins');
  }

  public getPlugin(author: string, name: string): Promise<ApiRespPlugin> {
    return this.get(`/api/v1/plugins/${author}/${name}`);
  }

  public getPluginConfig(
    author: string,
    name: string,
  ): Promise<ApiRespPluginConfig> {
    return this.get(`/api/v1/plugins/${author}/${name}/config`);
  }

  public updatePluginConfig(
    author: string,
    name: string,
    config: object,
  ): Promise<object> {
    return this.put(`/api/v1/plugins/${author}/${name}/config`, config);
  }

  public uploadPluginConfigFile(file: File): Promise<{ file_key: string }> {
    const formData = new FormData();
    formData.append('file', file);

    return this.request<{ file_key: string }>({
      method: 'post',
      url: '/api/v1/plugins/config-files',
      data: formData,
      headers: {
        'Content-Type': 'multipart/form-data',
      },
    });
  }

  public deletePluginConfigFile(
    fileKey: string,
  ): Promise<{ deleted: boolean }> {
    return this.delete(`/api/v1/plugins/config-files/${fileKey}`);
  }

  public getPluginReadme(
    author: string,
    name: string,
    language: string = 'en',
  ): Promise<{ readme: string }> {
    return this.get(
      `/api/v1/plugins/${author}/${name}/readme?language=${language}`,
    );
  }

  public getPluginLogs(
    author: string,
    name: string,
    limit: number = 200,
    level?: string,
  ): Promise<{ logs: PluginLogEntry[] }> {
    const params = new URLSearchParams();
    params.set('limit', String(limit));
    if (level) {
      params.set('level', level);
    }
    return this.get(
      `/api/v1/plugins/${author}/${name}/logs?${params.toString()}`,
    );
  }

  public getMcpServerLogs(
    serverName: string,
    limit: number = 200,
    level?: string,
  ): Promise<{ logs: PluginLogEntry[] }> {
    const params = new URLSearchParams();
    params.set('limit', String(limit));
    if (level) {
      params.set('level', level);
    }
    return this.get(
      `/api/v1/mcp/servers/${encodeURIComponent(serverName)}/logs?${params.toString()}`,
    );
  }

  public getPluginAssetURL(
    author: string,
    name: string,
    filepath: string,
  ): string {
    if (this.instance.defaults.baseURL === '/') {
      return `${window.location.origin}/api/v1/plugins/${author}/${name}/assets/${filepath}`;
    }
    return (
      this.instance.defaults.baseURL +
      `/api/v1/plugins/${author}/${name}/assets/${filepath}`
    );
  }

  private async getAuthenticatedObjectURL(
    path: string,
    rewritePluginPageSdk = false,
  ): Promise<string> {
    const response = await this.instance.get<Blob>(path, {
      responseType: 'blob',
    });
    let blob = response.data;
    if (rewritePluginPageSdk && blob.type.startsWith('text/html')) {
      const apiBase =
        this.instance.defaults.baseURL === '/'
          ? window.location.origin
          : this.instance.defaults.baseURL?.replace(/\/$/, '');
      const pageSdkUrl = `${apiBase}/api/v1/plugins/_sdk/page-sdk.js`;
      const html = await blob.text();
      blob = new Blob(
        [
          html.replace(
            /(<script\b[^>]*\bsrc\s*=\s*)(["'])\/api\/v1\/plugins\/_sdk\/page-sdk\.js\2/gi,
            `$1$2${pageSdkUrl}$2`,
          ),
        ],
        { type: blob.type },
      );
    }
    return URL.createObjectURL(blob);
  }

  public getAuthenticatedPluginAssetURL(
    author: string,
    name: string,
    filepath: string,
  ): Promise<string> {
    return this.getAuthenticatedObjectURL(
      `/api/v1/plugins/${author}/${name}/authenticated-assets/${filepath}`,
      true,
    );
  }

  public getAuthenticatedPluginIconURL(
    author: string,
    name: string,
  ): Promise<string> {
    return this.getAuthenticatedObjectURL(
      `/api/v1/plugins/${author}/${name}/authenticated-icon`,
    );
  }

  public async pluginPageApi(
    author: string,
    name: string,
    pageId: string,
    endpoint: string,
    method: string = 'POST',
    body?: unknown,
  ): Promise<unknown> {
    const resp = await this.instance.request({
      url: `/api/v1/plugins/${author}/${name}/page-api`,
      method: 'POST',
      data: {
        page_id: pageId,
        endpoint,
        method,
        body,
      },
    });
    return resp.data?.data;
  }

  public getPluginIconURL(author: string, name: string): string {
    if (this.instance.defaults.baseURL === '/') {
      const url = window.location.href;
      const baseURL = url.split('/').slice(0, 3).join('/');
      return `${baseURL}/api/v1/plugins/${author}/${name}/icon`;
    }
    return (
      this.instance.defaults.baseURL + `/api/v1/plugins/${author}/${name}/icon`
    );
  }

  public installPluginFromGithub(
    assetId: number,
    releaseId: number,
    owner: string,
    repo: string,
    releaseTag: string,
  ): Promise<AsyncTaskCreatedResp> {
    return this.post('/api/v1/plugins/install/github', {
      asset_id: assetId,
      release_id: releaseId,
      owner,
      repo,
      release_tag: releaseTag,
    });
  }

  public getGithubReleases(repoUrl: string): Promise<{
    releases: Array<{
      id: number;
      tag_name: string;
      name: string;
      published_at: string;
      prerelease: boolean;
      draft: boolean;
      source_type?: 'release' | 'tag' | 'branch';
      archive_url?: string;
    }>;
    owner: string;
    repo: string;
    source_subdir?: string;
  }> {
    return this.post('/api/v1/plugins/github/releases', { repo_url: repoUrl });
  }

  public getGithubReleaseAssets(
    owner: string,
    repo: string,
    releaseId: number,
    releaseTag?: string,
    sourceType?: 'release' | 'tag' | 'branch',
    archiveUrl?: string,
  ): Promise<{
    assets: Array<{
      id: number;
      name: string;
      size: number;
      download_url: string;
      content_type: string;
    }>;
  }> {
    return this.post('/api/v1/plugins/github/release-assets', {
      owner,
      repo,
      release_id: releaseId,
      release_tag: releaseTag,
      source_type: sourceType,
      archive_url: archiveUrl,
    });
  }

  public installPluginFromLocal(file: File): Promise<AsyncTaskCreatedResp> {
    const formData = new FormData();
    formData.append('file', file);
    return this.postFile('/api/v1/plugins/install/local', formData);
  }

  public previewPluginInstallFromLocal(file: File): Promise<{
    filename: string;
    size: number;
    manifest: Record<string, unknown>;
    metadata: {
      author?: string;
      name?: string;
      version?: string;
      label?: I18nObject;
      description?: I18nObject;
      repository?: string;
    };
    component_types: string[];
    component_counts: Record<string, number>;
    requirements: string[];
    file_count: number;
  }> {
    const formData = new FormData();
    formData.append('file', file);
    return this.postFile('/api/v1/plugins/install/local/preview', formData);
  }

  // ============ Skill Install API ============
  public installSkillFromGithub(
    assetUrl: string,
    owner: string,
    repo: string,
    releaseTag: string,
    sourcePaths?: string[],
    sourceSubdir?: string,
  ): Promise<ApiRespSkills> {
    return this.post('/api/v1/skills/install/github', {
      asset_url: assetUrl,
      owner,
      repo,
      release_tag: releaseTag,
      source_paths: sourcePaths,
      source_subdir: sourceSubdir,
    });
  }

  public previewSkillInstallFromGithub(
    assetUrl: string,
    owner: string,
    repo: string,
    releaseTag: string,
    sourceSubdir?: string,
  ): Promise<{ skills: Skill[] }> {
    return this.post('/api/v1/skills/install/github/preview', {
      asset_url: assetUrl,
      owner,
      repo,
      release_tag: releaseTag,
      source_subdir: sourceSubdir,
    });
  }

  public previewSkillInstallFromUpload(
    file: File,
  ): Promise<{ skills: Skill[] }> {
    const formData = new FormData();
    formData.append('file', file);
    return this.postFile('/api/v1/skills/install/upload/preview', formData);
  }

  public installSkillFromUpload(
    file: File,
    sourcePaths?: string[],
  ): Promise<ApiRespSkills> {
    const formData = new FormData();
    formData.append('file', file);
    for (const sourcePath of sourcePaths || []) {
      formData.append('source_paths', sourcePath);
    }
    return this.postFile('/api/v1/skills/install/upload', formData);
  }

  public installPluginFromMarketplace(
    author: string,
    name: string,
    version: string,
  ): Promise<AsyncTaskCreatedResp> {
    return this.post('/api/v1/plugins/install/marketplace', {
      plugin_author: author,
      plugin_name: name,
      plugin_version: version,
    });
  }

  public removePlugin(
    author: string,
    name: string,
    deleteData: boolean = false,
  ): Promise<AsyncTaskCreatedResp> {
    return this.delete(
      `/api/v1/plugins/${author}/${name}?delete_data=${deleteData}`,
    );
  }

  public upgradePlugin(
    author: string,
    name: string,
  ): Promise<AsyncTaskCreatedResp> {
    return this.post(`/api/v1/plugins/${author}/${name}/upgrade`);
  }

  // ============ MCP API ============
  public getMCPServers(): Promise<ApiRespMCPServers> {
    return this.get('/api/v1/mcp/servers');
  }

  // ========== Tools ==========

  public getTools(pipelineId?: string): Promise<ApiRespTools> {
    return this.get(
      '/api/v1/tools',
      pipelineId ? { pipeline_uuid: pipelineId } : undefined,
    );
  }

  public getToolDetail(toolName: string): Promise<ApiRespToolDetail> {
    return this.get(`/api/v1/tools/${toolName}`);
  }

  public getMCPServer(serverName: string): Promise<ApiRespMCPServer> {
    return this.get(`/api/v1/mcp/servers/${encodeURIComponent(serverName)}`);
  }

  public createMCPServer(server: MCPServer): Promise<AsyncTaskCreatedResp> {
    return this.post('/api/v1/mcp/servers', server);
  }

  public updateMCPServer(
    serverName: string,
    server: Partial<MCPServer>,
  ): Promise<AsyncTaskCreatedResp> {
    return this.put(
      `/api/v1/mcp/servers/${encodeURIComponent(serverName)}`,
      server,
    );
  }

  public deleteMCPServer(serverName: string): Promise<AsyncTaskCreatedResp> {
    return this.delete(`/api/v1/mcp/servers/${encodeURIComponent(serverName)}`);
  }

  public toggleMCPServer(
    serverName: string,
    target_enabled: boolean,
  ): Promise<AsyncTaskCreatedResp> {
    return this.put(`/api/v1/mcp/servers/${encodeURIComponent(serverName)}`, {
      enable: target_enabled,
    });
  }

  public testMCPServer(
    serverName: string,
    serverData: object,
  ): Promise<AsyncTaskCreatedResp> {
    return this.post(
      `/api/v1/mcp/servers/${encodeURIComponent(serverName)}/test`,
      serverData,
    );
  }

  public installMCPServerFromGithub(
    source: string,
  ): Promise<AsyncTaskCreatedResp> {
    return this.post('/api/v1/mcp/install/github', { source });
  }

  public installMCPServerFromSSE(
    source: object,
  ): Promise<AsyncTaskCreatedResp> {
    return this.post('/api/v1/mcp/servers', { source });
  }

  public getMCPServerResources(
    serverName: string,
  ): Promise<ApiRespMCPResources> {
    return this.get(
      `/api/v1/mcp/servers/${encodeURIComponent(serverName)}/resources`,
    );
  }

  public readMCPServerResource(
    serverName: string,
    uri: string,
    maxBytes?: number,
  ): Promise<ApiRespMCPResourceContents> {
    return this.post(
      `/api/v1/mcp/servers/${encodeURIComponent(serverName)}/resources/read`,
      {
        uri,
        max_bytes: maxBytes,
      },
    );
  }

  // ============ System API ============
  public getSystemInfo(): Promise<ApiRespSystemInfo> {
    return this.get('/api/v1/system/info');
  }

  public updateWizardStatus(status: 'skipped' | 'completed'): Promise<void> {
    return this.post('/api/v1/system/wizard/completed', { status });
  }

  public saveWizardProgress(progress: {
    step: number;
    selected_adapter: string | null;
    created_bot_uuid: string | null;
    created_pipeline_uuid?: string | null;
    bot_saved: boolean;
    message_received?: boolean;
    selected_runner: string | null;
  }): Promise<void> {
    return this.put('/api/v1/system/wizard/progress', progress);
  }

  public getWizardRecommendedModel(): Promise<{
    uuid: string;
    name: string;
  }> {
    return this.get('/api/v1/system/wizard/recommended-model');
  }

  public getAsyncTasks(params?: {
    type?: string;
    kind?: string;
  }): Promise<ApiRespAsyncTasks> {
    const query = new URLSearchParams();
    if (params?.type) query.set('type', params.type);
    if (params?.kind) query.set('kind', params.kind);
    const qs = query.toString();
    return this.get(`/api/v1/system/tasks${qs ? `?${qs}` : ''}`);
  }

  public getAsyncTask(id: number): Promise<AsyncTask> {
    return this.get(`/api/v1/system/tasks/${id}`);
  }

  public getPluginSystemStatus(): Promise<ApiRespPluginSystemStatus> {
    return this.get('/api/v1/system/status/plugin-system');
  }

  // ============ RAG Migration API ============
  public getRagMigrationStatus(): Promise<RagMigrationStatusResp> {
    return this.get('/api/v1/knowledge/migration/status');
  }

  public executeRagMigration(
    installPlugin: boolean = true,
  ): Promise<AsyncTaskCreatedResp> {
    return this.post('/api/v1/knowledge/migration/execute', {
      install_plugin: installPlugin,
    });
  }

  public dismissRagMigration(): Promise<object> {
    return this.post('/api/v1/knowledge/migration/dismiss');
  }

  public getPluginDebugInfo(): Promise<{
    debug_url: string;
    plugin_debug_key: string;
    expires_at: string;
  }> {
    return this.get('/api/v1/plugins/debug-info');
  }

  public getBoxRuntimeStatus(): Promise<ApiRespBoxStatus> {
    return this.get('/api/v1/box/runtime-status');
  }

  public getBoxStatus(): Promise<ApiRespBoxStatus> {
    return this.get('/api/v1/box/status');
  }

  public getBoxSessions(): Promise<BoxSessionInfo[]> {
    return this.get('/api/v1/box/sessions');
  }

  // ============ User API ============
  public checkIfInited(): Promise<{ initialized: boolean }> {
    return this.get('/api/v1/user/init', undefined, { skipWorkspace: true });
  }

  public initUser(user: string, password: string): Promise<object> {
    return this.post(
      '/api/v1/user/init',
      { user, password },
      { skipWorkspace: true },
    );
  }

  public authUser(user: string, password: string): Promise<ApiRespUserToken> {
    return this.post(
      '/api/v1/user/auth',
      { user, password },
      { skipWorkspace: true },
    );
  }

  public checkUserToken(): Promise<ApiRespUserToken> {
    return this.get('/api/v1/user/check-token', undefined, {
      skipWorkspace: true,
    });
  }

  public resetPassword(
    user: string,
    recoveryKey: string,
    newPassword: string,
  ): Promise<{ user: string }> {
    return this.post(
      '/api/v1/user/reset-password',
      {
        user,
        recovery_key: recoveryKey,
        new_password: newPassword,
      },
      { skipWorkspace: true },
    );
  }

  public changePassword(
    currentPassword: string,
    newPassword: string,
  ): Promise<{ user: string }> {
    return this.post(
      '/api/v1/user/change-password',
      {
        current_password: currentPassword,
        new_password: newPassword,
      },
      { skipWorkspace: true },
    );
  }

  public getUserInfo(): Promise<{
    account_uuid: string;
    user: string;
    account_type: 'local' | 'space';
    has_password: boolean;
  }> {
    return this.get('/api/v1/user/info', undefined, { skipWorkspace: true });
  }

  public getWorkspaceSpaceBilling(): Promise<WorkspaceSpaceBilling> {
    return this.get('/api/v1/user/space-credits');
  }

  public getAccountInfo(): Promise<{
    initialized: boolean;
    authenticated_invitation_acceptance_enabled?: boolean;
    invitation_registration_enabled?: boolean;
    password_login_enabled?: boolean;
    space_login_enabled?: boolean;
  }> {
    return this.get('/api/v1/user/account-info', undefined, {
      skipWorkspace: true,
    });
  }

  // ============ Workspace API ============
  public getWorkspaceBootstrap(): Promise<WorkspaceBootstrapResponse> {
    return this.get('/api/v1/workspaces/bootstrap', undefined, {
      skipWorkspace: true,
    });
  }

  public getWorkspaces(): Promise<{ workspaces: Workspace[] }> {
    return this.get('/api/v1/workspaces', undefined, { skipWorkspace: true });
  }

  public getCurrentWorkspace(): Promise<CurrentWorkspace> {
    return this.get('/api/v1/workspaces/current');
  }

  public getWorkspace(
    workspaceUuid: string,
  ): Promise<{ workspace: Workspace }> {
    return this.get(`/api/v1/workspaces/${workspaceUuid}`);
  }

  public getWorkspaceMembers(
    workspaceUuid: string,
  ): Promise<{ members: WorkspaceMembership[] }> {
    return this.get(`/api/v1/workspaces/${workspaceUuid}/members`);
  }

  public createWorkspaceInvitation(
    workspaceUuid: string,
    email: string,
    role: Exclude<WorkspaceRole, 'owner'>,
  ): Promise<{
    invitation: WorkspaceInvitation;
    token: string;
    link: string;
    delivery: WorkspaceInvitationDelivery;
  }> {
    return this.post(`/api/v1/workspaces/${workspaceUuid}/invitations`, {
      email,
      role,
    });
  }

  public getWorkspaceInvitations(
    workspaceUuid: string,
  ): Promise<{ invitations: WorkspaceInvitation[] }> {
    return this.get(`/api/v1/workspaces/${workspaceUuid}/invitations`);
  }

  public revokeWorkspaceInvitation(
    workspaceUuid: string,
    invitationUuid: string,
  ): Promise<object> {
    return this.delete(
      `/api/v1/workspaces/${workspaceUuid}/invitations/${invitationUuid}`,
    );
  }

  public inspectWorkspaceInvitation(
    token: string,
  ): Promise<{ invitation: WorkspaceInvitation; workspace: Workspace }> {
    return this.post(
      '/api/v1/invitations/inspect',
      { token },
      { skipWorkspace: true },
    );
  }

  public acceptWorkspaceInvitation(
    token: string,
    registration?: { email: string; password: string },
  ): Promise<{ token: string; workspace_uuid: string }> {
    return this.post(
      '/api/v1/invitations/accept',
      {
        token,
        registration,
      },
      { skipWorkspace: true },
    );
  }

  public updateWorkspaceMemberRole(
    workspaceUuid: string,
    accountUuid: string,
    role: WorkspaceRole,
  ): Promise<{ member: WorkspaceMembership }> {
    return this.patch(
      `/api/v1/workspaces/${workspaceUuid}/members/${accountUuid}`,
      { role },
    );
  }

  public removeWorkspaceMember(
    workspaceUuid: string,
    accountUuid: string,
  ): Promise<object> {
    return this.delete(
      `/api/v1/workspaces/${workspaceUuid}/members/${accountUuid}`,
    );
  }

  public setPassword(
    newPassword: string,
    currentPassword?: string,
  ): Promise<{ user: string }> {
    return this.post(
      '/api/v1/user/set-password',
      {
        new_password: newPassword,
        current_password: currentPassword,
      },
      { skipWorkspace: true },
    );
  }

  public async bindSpaceAccount(
    code: string,
    state: string,
    redirectUri: string,
  ): Promise<{
    token: string;
    user: string;
    account_type: 'local' | 'space';
  }> {
    const response = await this.instance.post(
      '/api/v1/user/bind-space',
      { code, state, redirect_uri: redirectUri },
      { skipWorkspace: true } as RequestConfig,
    );
    if (response.data.code !== 0) {
      throw {
        code: response.data.code,
        msg: response.data.msg || 'Unknown error',
      };
    }
    return response.data.data;
  }

  // ============ Space OAuth API (Redirect Flow) ============
  public getSpaceAuthorizeUrl(redirectUri: string): Promise<{
    authorize_url: string;
  }> {
    return this.get(
      '/api/v1/user/space/authorize-url',
      { redirect_uri: redirectUri },
      { skipWorkspace: true },
    );
  }

  public getSpaceBindAuthorizeUrl(redirectUri: string): Promise<{
    authorize_url: string;
  }> {
    return this.get(
      '/api/v1/user/space/bind-authorize-url',
      { redirect_uri: redirectUri },
      { skipWorkspace: true },
    );
  }

  public async exchangeSpaceOAuthCode(
    code: string,
    state: string,
    redirectUri: string,
    workspaceUuid?: string,
    launchAssertion?: string,
  ): Promise<{
    token: string;
    user?: string;
    workspace_uuid?: string;
    principal_type?: 'account' | 'support_admin';
    actor_account_uuid?: string;
  }> {
    const response = await this.instance.post(
      '/api/v1/user/space/callback',
      {
        code,
        state,
        redirect_uri: redirectUri,
        workspace_uuid: workspaceUuid,
        launch_assertion: launchAssertion,
      },
      { skipWorkspace: true } as RequestConfig,
    );
    if (response.data.code !== 0) {
      throw {
        code: response.data.code,
        msg: response.data.msg || 'Unknown error',
      };
    }
    return response.data.data;
  }

  // ============ Monitoring API ============
  public getMonitoringData(params: {
    botId?: string[];
    pipelineId?: string[];
    startTime?: string;
    endTime?: string;
    limit?: number;
  }): Promise<{
    overview: {
      total_messages: number;
      llm_calls: number;
      embedding_calls: number;
      model_calls: number;
      success_rate: number;
      active_sessions: number;
    };
    messages: Array<{
      id: string;
      timestamp: string;
      bot_id: string;
      bot_name: string;
      pipeline_id: string;
      pipeline_name: string;
      message_content: string;
      session_id: string;
      status: string;
      level: string;
      platform?: string;
      user_id?: string;
      user_name?: string;
      runner_name?: string;
      variables?: string;
      role?: string;
    }>;
    llmCalls: Array<{
      id: string;
      timestamp: string;
      model_name: string;
      input_tokens: number;
      output_tokens: number;
      total_tokens: number;
      duration: number;
      cost?: number;
      status: string;
      bot_id: string;
      bot_name: string;
      pipeline_id: string;
      pipeline_name: string;
      session_id?: string;
      error_message?: string;
      message_id?: string;
    }>;
    toolCalls: Array<{
      id: string;
      timestamp: string;
      tool_name: string;
      tool_source: string;
      duration: number;
      status: string;
      bot_id: string;
      bot_name: string;
      pipeline_id: string;
      pipeline_name: string;
      session_id?: string;
      message_id?: string;
      arguments?: string;
      result?: string;
      error_message?: string;
    }>;
    embeddingCalls: Array<{
      id: string;
      timestamp: string;
      model_name: string;
      prompt_tokens: number;
      total_tokens: number;
      duration: number;
      input_count: number;
      status: string;
      error_message?: string;
      knowledge_base_id?: string;
      query_text?: string;
      session_id?: string;
      message_id?: string;
      call_type?: string;
    }>;
    sessions: Array<{
      session_id: string;
      bot_id: string;
      bot_name: string;
      pipeline_id: string;
      pipeline_name: string;
      message_count: number;
      last_activity: string;
      start_time: string;
      platform?: string;
      user_id?: string;
    }>;
    errors: Array<{
      id: string;
      timestamp: string;
      error_type: string;
      error_message: string;
      bot_id: string;
      bot_name: string;
      pipeline_id: string;
      pipeline_name: string;
      session_id?: string;
      stack_trace?: string;
      message_id?: string;
    }>;
    totalCount: {
      messages: number;
      llmCalls: number;
      toolCalls?: number;
      embeddingCalls: number;
      sessions: number;
      errors: number;
    };
  }> {
    const queryParams = new URLSearchParams();
    if (params.botId) {
      params.botId.forEach((id) => queryParams.append('botId', id));
    }
    if (params.pipelineId) {
      params.pipelineId.forEach((id) => queryParams.append('pipelineId', id));
    }
    if (params.startTime) {
      queryParams.append('startTime', params.startTime);
    }
    if (params.endTime) {
      queryParams.append('endTime', params.endTime);
    }
    if (params.limit) {
      queryParams.append('limit', params.limit.toString());
    }

    return this.get(`/api/v1/monitoring/data?${queryParams.toString()}`);
  }

  public getMonitoringOverview(params: {
    botId?: string[];
    pipelineId?: string[];
    startTime?: string;
    endTime?: string;
  }): Promise<{
    total_messages: number;
    llm_calls: number;
    success_rate: number;
    active_sessions: number;
  }> {
    const queryParams = new URLSearchParams();
    if (params.botId) {
      params.botId.forEach((id) => queryParams.append('botId', id));
    }
    if (params.pipelineId) {
      params.pipelineId.forEach((id) => queryParams.append('pipelineId', id));
    }
    if (params.startTime) {
      queryParams.append('startTime', params.startTime);
    }
    if (params.endTime) {
      queryParams.append('endTime', params.endTime);
    }

    return this.get(`/api/v1/monitoring/overview?${queryParams.toString()}`);
  }

  public getTokenStatistics(params: {
    botId?: string[];
    pipelineId?: string[];
    startTime?: string;
    endTime?: string;
    bucket?: 'hour' | 'day';
  }): Promise<{
    summary: {
      total_calls: number;
      success_calls: number;
      error_calls: number;
      total_input_tokens: number;
      total_output_tokens: number;
      total_tokens: number;
      total_cost: number;
      avg_tokens_per_call: number;
      avg_duration_ms: number;
      avg_tokens_per_second: number;
      zero_token_success_calls: number;
    };
    by_model: Array<{
      model_name: string;
      calls: number;
      error_calls: number;
      input_tokens: number;
      output_tokens: number;
      total_tokens: number;
      cost: number;
      avg_tokens_per_call: number;
      avg_duration_ms: number;
    }>;
    timeseries: Array<{
      bucket: string;
      input_tokens: number;
      output_tokens: number;
      total_tokens: number;
      calls: number;
    }>;
    bucket: string;
  }> {
    const queryParams = new URLSearchParams();
    if (params.botId) {
      params.botId.forEach((id) => queryParams.append('botId', id));
    }
    if (params.pipelineId) {
      params.pipelineId.forEach((id) => queryParams.append('pipelineId', id));
    }
    if (params.startTime) {
      queryParams.append('startTime', params.startTime);
    }
    if (params.endTime) {
      queryParams.append('endTime', params.endTime);
    }
    if (params.bucket) {
      queryParams.append('bucket', params.bucket);
    }

    return this.get(
      `/api/v1/monitoring/token-statistics?${queryParams.toString()}`,
    );
  }

  // ============ Survey API ============
  public getSurveyPending(): Promise<{
    survey: {
      survey_id: string;
      version: number;
      title: Record<string, string>;
      description: Record<string, string>;
      questions: SurveyQuestion[];
    } | null;
  }> {
    return this.get('/api/v1/survey/pending');
  }

  public submitSurveyResponse(
    surveyId: string,
    answers: Record<string, unknown>,
    completed: boolean = true,
  ): Promise<object> {
    return this.post('/api/v1/survey/respond', {
      survey_id: surveyId,
      answers,
      completed,
    });
  }

  public dismissSurvey(surveyId: string): Promise<object> {
    return this.post('/api/v1/survey/dismiss', { survey_id: surveyId });
  }

  public submitFeedback(data: {
    content: string;
    attachments?: Array<{
      name: string;
      mime_type: string;
      data_url: string;
    }>;
  }): Promise<object> {
    return this.post('/api/v1/survey/feedback', data);
  }

  // ============ Skills API ============

  public getSkills(): Promise<ApiRespSkills> {
    return this.get('/api/v1/skills');
  }

  public getSkill(name: string): Promise<ApiRespSkill> {
    return this.get(`/api/v1/skills/${name}`);
  }

  public createSkill(
    skill: Omit<Skill, 'name'> & { name: string },
  ): Promise<ApiRespSkill> {
    return this.post('/api/v1/skills', skill);
  }

  public updateSkill(
    name: string,
    skill: Partial<Skill>,
  ): Promise<ApiRespSkill> {
    return this.put(`/api/v1/skills/${name}`, skill);
  }

  public deleteSkill(name: string): Promise<object> {
    return this.delete(`/api/v1/skills/${name}`);
  }

  public previewSkill(name: string): Promise<{ instructions: string }> {
    return this.get(`/api/v1/skills/${name}/preview`);
  }

  public getSkillIndex(pipelineUuid?: string): Promise<{ index: string }> {
    const params = pipelineUuid ? { pipeline_uuid: pipelineUuid } : {};
    return this.get('/api/v1/skills/index', params);
  }

  public scanSkillDirectory(path: string): Promise<{
    package_root: string;
    name: string;
    display_name?: string;
    description: string;
    instructions: string;
  }> {
    return this.get('/api/v1/skills/scan', { path });
  }

  public listSkillFiles(
    skillName: string,
    path: string = '.',
    includeHidden: boolean = false,
  ): Promise<{
    skill: { name: string };
    base_path: string;
    entries: Array<{
      path: string;
      name: string;
      is_dir: boolean;
      size: number | null;
    }>;
    truncated: boolean;
  }> {
    return this.get(`/api/v1/skills/${skillName}/files`, {
      path,
      include_hidden: includeHidden,
    });
  }

  public readSkillFile(
    skillName: string,
    filePath: string,
  ): Promise<{
    skill: { name: string };
    path: string;
    content: string;
  }> {
    return this.get(`/api/v1/skills/${skillName}/files/${filePath}`);
  }

  public writeSkillFile(
    skillName: string,
    filePath: string,
    content: string,
  ): Promise<{
    skill: { name: string };
    path: string;
    bytes_written: number;
  }> {
    return this.put(`/api/v1/skills/${skillName}/files/${filePath}`, {
      content,
    });
  }
}

export interface SurveyQuestion {
  id: string;
  type: 'single_select' | 'multi_select' | 'text';
  title: Record<string, string>;
  subtitle?: Record<string, string>;
  required: boolean;
  options?: SurveyOption[];
  placeholder?: Record<string, string>;
  max_length?: number;
}

export interface SurveyOption {
  id: string;
  label: Record<string, string>;
  has_input?: boolean;
}
