import { ASRModel, Assistant, CallLog, InteractionDetail, KnowledgeBase, KnowledgeDocument, LLMModel, Tool, Voice, Workflow, WorkflowEdge, WorkflowNode } from '../types';
import { apiRequest } from './apiClient';

type AnyRecord = Record<string, any>;

const readField = <T>(obj: AnyRecord, keys: string[], fallback: T): T => {
  for (const key of keys) {
    if (obj[key] !== undefined && obj[key] !== null) {
      return obj[key] as T;
    }
  }
  return fallback;
};

const normalizeDateLabel = (value: string): string => {
  if (!value) return '';
  return value.includes('T') ? value.replace('T', ' ').slice(0, 16) : value.slice(0, 16);
};

const formatDuration = (seconds?: number | null): string => {
  if (!seconds || seconds <= 0) return '0s';
  const m = Math.floor(seconds / 60);
  const s = seconds % 60;
  if (m === 0) return `${s}s`;
  return `${m}m ${s}s`;
};

const mapAssistant = (raw: AnyRecord): Assistant => ({
  id: String(readField(raw, ['id'], '')),
  name: readField(raw, ['name'], ''),
  callCount: Number(readField(raw, ['callCount', 'call_count'], 0)),
  opener: readField(raw, ['opener'], ''),
  prompt: readField(raw, ['prompt'], ''),
  knowledgeBaseId: readField(raw, ['knowledgeBaseId', 'knowledge_base_id'], ''),
  language: readField(raw, ['language'], 'zh') as 'zh' | 'en',
  voice: readField(raw, ['voice'], ''),
  speed: Number(readField(raw, ['speed'], 1)),
  hotwords: readField(raw, ['hotwords'], []),
  tools: readField(raw, ['tools'], []),
  interruptionSensitivity: Number(readField(raw, ['interruptionSensitivity', 'interruption_sensitivity'], 500)),
  configMode: readField(raw, ['configMode', 'config_mode'], 'platform') as 'platform' | 'dify' | 'fastgpt' | 'none',
  apiUrl: readField(raw, ['apiUrl', 'api_url'], ''),
  apiKey: readField(raw, ['apiKey', 'api_key'], ''),
  llmModelId: readField(raw, ['llmModelId', 'llm_model_id'], ''),
  asrModelId: readField(raw, ['asrModelId', 'asr_model_id'], ''),
  embeddingModelId: readField(raw, ['embeddingModelId', 'embedding_model_id'], ''),
  rerankModelId: readField(raw, ['rerankModelId', 'rerank_model_id'], ''),
});

const mapVoice = (raw: AnyRecord): Voice => ({
  id: String(readField(raw, ['id'], '')),
  name: readField(raw, ['name'], ''),
  vendor: ((): string => {
    const vendor = String(readField(raw, ['vendor'], ''));
    return vendor.toLowerCase() === 'siliconflow' ? '硅基流动' : vendor;
  })(),
  gender: readField(raw, ['gender'], ''),
  language: readField(raw, ['language'], ''),
  description: readField(raw, ['description'], ''),
  model: readField(raw, ['model'], ''),
  voiceKey: readField(raw, ['voiceKey', 'voice_key'], ''),
  apiKey: readField(raw, ['apiKey', 'api_key'], ''),
  baseUrl: readField(raw, ['baseUrl', 'base_url'], ''),
  speed: Number(readField(raw, ['speed'], 1)),
  gain: Number(readField(raw, ['gain'], 0)),
  pitch: Number(readField(raw, ['pitch'], 0)),
  enabled: Boolean(readField(raw, ['enabled'], true)),
  isSystem: Boolean(readField(raw, ['isSystem', 'is_system'], false)),
});

const mapASRModel = (raw: AnyRecord): ASRModel => ({
  id: String(readField(raw, ['id'], '')),
  name: readField(raw, ['name'], ''),
  vendor: readField(raw, ['vendor'], 'OpenAI Compatible'),
  language: readField(raw, ['language'], 'zh'),
  baseUrl: readField(raw, ['baseUrl', 'base_url'], ''),
  apiKey: readField(raw, ['apiKey', 'api_key'], ''),
  modelName: readField(raw, ['modelName', 'model_name'], ''),
  hotwords: readField(raw, ['hotwords'], []),
  enablePunctuation: Boolean(readField(raw, ['enablePunctuation', 'enable_punctuation'], true)),
  enableNormalization: Boolean(readField(raw, ['enableNormalization', 'enable_normalization'], true)),
  enabled: Boolean(readField(raw, ['enabled'], true)),
});

const mapLLMModel = (raw: AnyRecord): LLMModel => ({
  id: String(readField(raw, ['id'], '')),
  name: readField(raw, ['name'], ''),
  vendor: readField(raw, ['vendor'], 'OpenAI Compatible'),
  type: readField(raw, ['type'], 'text'),
  baseUrl: readField(raw, ['baseUrl', 'base_url'], ''),
  apiKey: readField(raw, ['apiKey', 'api_key'], ''),
  modelName: readField(raw, ['modelName', 'model_name'], ''),
  temperature: Number(readField(raw, ['temperature'], 0.7)),
  contextLength: Number(readField(raw, ['contextLength', 'context_length'], 0)),
  enabled: Boolean(readField(raw, ['enabled'], true)),
});

const mapTool = (raw: AnyRecord): Tool => ({
  id: String(readField(raw, ['id'], '')),
  name: readField(raw, ['name'], ''),
  description: readField(raw, ['description'], ''),
  category: readField(raw, ['category'], 'system') as 'system' | 'query',
  icon: readField(raw, ['icon'], 'Wrench'),
  isSystem: Boolean(readField(raw, ['isSystem', 'is_system'], false)),
  enabled: Boolean(readField(raw, ['enabled'], true)),
  isCustom: !Boolean(readField(raw, ['isSystem', 'is_system'], false)),
});

const mapWorkflowNode = (raw: AnyRecord): WorkflowNode => ({
  name: readField(raw, ['name'], ''),
  type: readField(raw, ['type'], 'conversation') as 'conversation' | 'tool' | 'human' | 'end',
  isStart: readField(raw, ['isStart', 'is_start'], undefined),
  metadata: readField(raw, ['metadata'], { position: { x: 200, y: 200 } }),
  prompt: readField(raw, ['prompt'], ''),
  messagePlan: readField(raw, ['messagePlan', 'message_plan'], undefined),
  variableExtractionPlan: readField(raw, ['variableExtractionPlan', 'variable_extraction_plan'], undefined),
  tool: readField(raw, ['tool'], undefined),
  globalNodePlan: readField(raw, ['globalNodePlan', 'global_node_plan'], undefined),
});

const mapWorkflowEdge = (raw: AnyRecord): WorkflowEdge => ({
  from: readField(raw, ['from', 'from_'], ''),
  to: readField(raw, ['to'], ''),
  label: readField(raw, ['label'], undefined),
});

const mapWorkflow = (raw: AnyRecord): Workflow => ({
  id: String(readField(raw, ['id'], '')),
  name: readField(raw, ['name'], ''),
  nodeCount: Number(readField(raw, ['nodeCount', 'node_count'], Array.isArray(raw.nodes) ? raw.nodes.length : 0)),
  createdAt: normalizeDateLabel(readField(raw, ['createdAt', 'created_at'], '')),
  updatedAt: normalizeDateLabel(readField(raw, ['updatedAt', 'updated_at'], '')),
  nodes: readField(raw, ['nodes'], []).map((node: AnyRecord) => mapWorkflowNode(node)),
  edges: readField(raw, ['edges'], []).map((edge: AnyRecord) => mapWorkflowEdge(edge)),
  globalPrompt: readField(raw, ['globalPrompt', 'global_prompt'], ''),
});

const mapKnowledgeDocument = (raw: AnyRecord): KnowledgeDocument => ({
  id: String(readField(raw, ['id'], '')),
  name: readField(raw, ['name'], ''),
  size: readField(raw, ['size'], ''),
  uploadDate: normalizeDateLabel(readField(raw, ['uploadDate', 'upload_date', 'created_at'], '')),
});

const mapKnowledgeBase = (raw: AnyRecord): KnowledgeBase => ({
  id: String(readField(raw, ['id'], '')),
  name: readField(raw, ['name'], ''),
  creator: 'Admin',
  createdAt: normalizeDateLabel(readField(raw, ['createdAt', 'created_at'], '')),
  description: readField(raw, ['description'], ''),
  embeddingModel: readField(raw, ['embeddingModel', 'embedding_model'], ''),
  chunkSize: Number(readField(raw, ['chunkSize', 'chunk_size'], 500)),
  chunkOverlap: Number(readField(raw, ['chunkOverlap', 'chunk_overlap'], 50)),
  status: readField(raw, ['status'], 'active'),
  documents: readField(raw, ['documents'], []).map((doc: AnyRecord) => mapKnowledgeDocument(doc)),
});

const toHistoryRow = (raw: AnyRecord, assistantNameMap: Map<string, string>): CallLog => {
  const assistantId = readField(raw, ['assistant_id', 'assistantId'], '');
  const startTime = normalizeDateLabel(readField(raw, ['started_at', 'startTime'], ''));
  const type = readField(raw, ['type'], 'text');
  return {
    id: String(readField(raw, ['id'], '')),
    source: readField(raw, ['source'], 'debug') as 'debug' | 'external',
    status: readField(raw, ['status'], 'connected') as 'connected' | 'missed',
    startTime,
    duration: formatDuration(readField(raw, ['duration_seconds', 'durationSeconds'], 0)),
    agentName: assistantNameMap.get(String(assistantId)) || String(assistantId || 'Unknown Assistant'),
    type: type === 'audio' || type === 'video' ? type : 'text',
    details: [],
  };
};

const toHistoryDetails = (raw: AnyRecord): InteractionDetail[] => {
  const transcripts = readField(raw, ['transcripts'], []);
  return transcripts.map((t: AnyRecord) => ({
    role: readField(t, ['speaker'], 'human') === 'human' ? 'user' : 'assistant',
    content: readField(t, ['content'], ''),
    timestamp: `${Math.floor(Number(readField(t, ['startMs', 'start_ms'], 0)) / 1000)}s`,
    audioUrl: readField(t, ['audioUrl', 'audio_url'], undefined),
  }));
};

export const fetchAssistants = async (): Promise<Assistant[]> => {
  const response = await apiRequest<{ list?: AnyRecord[] } | AnyRecord[]>('/assistants');
  const list = Array.isArray(response) ? response : (response.list || []);
  return list.map((item) => mapAssistant(item));
};

export const createAssistant = async (data: Partial<Assistant>): Promise<Assistant> => {
  const payload = {
    name: data.name || 'New Assistant',
    opener: data.opener || '',
    prompt: data.prompt || '',
    knowledgeBaseId: data.knowledgeBaseId || '',
    language: data.language || 'zh',
    voice: data.voice || '',
    speed: data.speed ?? 1,
    hotwords: data.hotwords || [],
    tools: data.tools || [],
    interruptionSensitivity: data.interruptionSensitivity ?? 500,
    configMode: data.configMode || 'platform',
    apiUrl: data.apiUrl || '',
    apiKey: data.apiKey || '',
    llmModelId: data.llmModelId || '',
    asrModelId: data.asrModelId || '',
    embeddingModelId: data.embeddingModelId || '',
    rerankModelId: data.rerankModelId || '',
  };
  const response = await apiRequest<AnyRecord>('/assistants', { method: 'POST', body: payload });
  return mapAssistant(response);
};

export const updateAssistant = async (id: string, data: Partial<Assistant>): Promise<Assistant> => {
  const payload = {
    name: data.name,
    opener: data.opener,
    prompt: data.prompt,
    knowledgeBaseId: data.knowledgeBaseId,
    language: data.language,
    voice: data.voice,
    speed: data.speed,
    hotwords: data.hotwords,
    tools: data.tools,
    interruptionSensitivity: data.interruptionSensitivity,
    configMode: data.configMode,
    apiUrl: data.apiUrl,
    apiKey: data.apiKey,
    llmModelId: data.llmModelId,
    asrModelId: data.asrModelId,
    embeddingModelId: data.embeddingModelId,
    rerankModelId: data.rerankModelId,
  };
  const response = await apiRequest<AnyRecord>(`/assistants/${id}`, { method: 'PUT', body: payload });
  return mapAssistant(response);
};

export const deleteAssistant = async (id: string): Promise<void> => {
  await apiRequest(`/assistants/${id}`, { method: 'DELETE' });
};

export interface AssistantRuntimeConfigResponse {
  assistantId: string;
  sessionStartMetadata: Record<string, any>;
  sources?: {
    llmModelId?: string;
    asrModelId?: string;
    voiceId?: string;
  };
  warnings?: string[];
}

export const fetchAssistantRuntimeConfig = async (assistantId: string): Promise<AssistantRuntimeConfigResponse> => {
  return apiRequest<AssistantRuntimeConfigResponse>(`/assistants/${assistantId}/runtime-config`);
};

export const fetchVoices = async (): Promise<Voice[]> => {
  const response = await apiRequest<{ list?: AnyRecord[] } | AnyRecord[]>('/voices');
  const list = Array.isArray(response) ? response : (response.list || []);
  return list.map((item) => mapVoice(item));
};

export const createVoice = async (data: Partial<Voice>): Promise<Voice> => {
  const payload = {
    id: data.id || undefined,
    name: data.name || 'New Voice',
    vendor: data.vendor === '硅基流动' ? 'SiliconFlow' : (data.vendor || 'SiliconFlow'),
    gender: data.gender || 'Female',
    language: data.language || 'zh',
    description: data.description || '',
    model: data.model || undefined,
    voice_key: data.voiceKey || undefined,
    api_key: data.apiKey || undefined,
    base_url: data.baseUrl || undefined,
    speed: data.speed ?? 1,
    gain: data.gain ?? 0,
    pitch: data.pitch ?? 0,
    enabled: data.enabled ?? true,
  };
  const response = await apiRequest<AnyRecord>('/voices', { method: 'POST', body: payload });
  return mapVoice(response);
};

export const updateVoice = async (id: string, data: Partial<Voice>): Promise<Voice> => {
  const payload = {
    name: data.name,
    vendor: data.vendor === '硅基流动' ? 'SiliconFlow' : data.vendor,
    gender: data.gender,
    language: data.language,
    description: data.description,
    model: data.model,
    voice_key: data.voiceKey,
    api_key: data.apiKey,
    base_url: data.baseUrl,
    speed: data.speed,
    gain: data.gain,
    pitch: data.pitch,
    enabled: data.enabled,
  };
  const response = await apiRequest<AnyRecord>(`/voices/${id}`, { method: 'PUT', body: payload });
  return mapVoice(response);
};

export const deleteVoice = async (id: string): Promise<void> => {
  await apiRequest(`/voices/${id}`, { method: 'DELETE' });
};

export const previewVoice = async (id: string, text: string, speed?: number, apiKey?: string): Promise<string> => {
  const response = await apiRequest<{ success: boolean; audio_url?: string; error?: string }>(`/voices/${id}/preview`, {
    method: 'POST',
    body: { text, speed, api_key: apiKey },
  });
  if (!response.success || !response.audio_url) {
    throw new Error(response.error || 'Preview failed');
  }
  return response.audio_url;
};

export const fetchASRModels = async (): Promise<ASRModel[]> => {
  const response = await apiRequest<{ list?: AnyRecord[] } | AnyRecord[]>('/asr');
  const list = Array.isArray(response) ? response : (response.list || []);
  return list.map((item) => mapASRModel(item));
};

export const createASRModel = async (data: Partial<ASRModel>): Promise<ASRModel> => {
  const payload = {
    id: data.id || undefined,
    name: data.name || 'New ASR Model',
    vendor: data.vendor || 'OpenAI Compatible',
    language: data.language || 'zh',
    base_url: data.baseUrl || 'https://api.siliconflow.cn/v1',
    api_key: data.apiKey || '',
    model_name: data.modelName || undefined,
    hotwords: data.hotwords || [],
    enable_punctuation: data.enablePunctuation ?? true,
    enable_normalization: data.enableNormalization ?? true,
    enabled: data.enabled ?? true,
  };
  const response = await apiRequest<AnyRecord>('/asr', { method: 'POST', body: payload });
  return mapASRModel(response);
};

export const updateASRModel = async (id: string, data: Partial<ASRModel>): Promise<ASRModel> => {
  const payload = {
    name: data.name,
    vendor: data.vendor,
    language: data.language,
    base_url: data.baseUrl,
    api_key: data.apiKey,
    model_name: data.modelName,
    hotwords: data.hotwords,
    enable_punctuation: data.enablePunctuation,
    enable_normalization: data.enableNormalization,
    enabled: data.enabled,
  };
  const response = await apiRequest<AnyRecord>(`/asr/${id}`, { method: 'PUT', body: payload });
  return mapASRModel(response);
};

export const deleteASRModel = async (id: string): Promise<void> => {
  await apiRequest(`/asr/${id}`, { method: 'DELETE' });
};

export type ASRPreviewResult = {
  success: boolean;
  transcript?: string;
  language?: string;
  confidence?: number;
  latency_ms?: number;
  message?: string;
  error?: string;
};

export const previewASRModel = async (
  id: string,
  file: File,
  options?: { language?: string; apiKey?: string }
): Promise<ASRPreviewResult> => {
  const formData = new FormData();
  formData.append('file', file);
  if (options?.language) {
    formData.append('language', options.language);
  }
  if (options?.apiKey) {
    formData.append('api_key', options.apiKey);
  }

  const base = (import.meta.env.VITE_API_BASE_URL || 'http://127.0.0.1:8100/api').replace(/\/+$/, '');
  const url = `${base}/asr/${id}/preview`;
  const response = await fetch(url, {
    method: 'POST',
    body: formData,
  });

  let data: ASRPreviewResult | null = null;
  try {
    data = await response.json();
  } catch {
    data = null;
  }

  if (!response.ok) {
    const detail = (data as AnyRecord | null)?.error || (data as AnyRecord | null)?.detail || `Request failed: ${response.status}`;
    throw new Error(typeof detail === 'string' ? detail : `Request failed: ${response.status}`);
  }

  return data || { success: false, error: 'Invalid preview response' };
};

export const fetchLLMModels = async (): Promise<LLMModel[]> => {
  const response = await apiRequest<{ list?: AnyRecord[] } | AnyRecord[]>('/llm');
  const list = Array.isArray(response) ? response : (response.list || []);
  return list.map((item) => mapLLMModel(item));
};

export const createLLMModel = async (data: Partial<LLMModel>): Promise<LLMModel> => {
  const payload = {
    id: data.id || undefined,
    name: data.name || 'New LLM Model',
    vendor: data.vendor || 'OpenAI Compatible',
    type: data.type || 'text',
    base_url: data.baseUrl || '',
    api_key: data.apiKey || '',
    model_name: data.modelName || undefined,
    temperature: data.temperature,
    context_length: data.contextLength,
    enabled: data.enabled ?? true,
  };
  const response = await apiRequest<AnyRecord>('/llm', { method: 'POST', body: payload });
  return mapLLMModel(response);
};

export const updateLLMModel = async (id: string, data: Partial<LLMModel>): Promise<LLMModel> => {
  const payload = {
    name: data.name,
    vendor: data.vendor,
    type: data.type,
    base_url: data.baseUrl,
    api_key: data.apiKey,
    model_name: data.modelName,
    temperature: data.temperature,
    context_length: data.contextLength,
    enabled: data.enabled,
  };
  const response = await apiRequest<AnyRecord>(`/llm/${id}`, { method: 'PUT', body: payload });
  return mapLLMModel(response);
};

export const deleteLLMModel = async (id: string): Promise<void> => {
  await apiRequest(`/llm/${id}`, { method: 'DELETE' });
};

export type LLMPreviewResult = {
  success: boolean;
  reply?: string;
  usage?: Record<string, number>;
  latency_ms?: number;
  error?: string;
};

export const previewLLMModel = async (
  id: string,
  payload: { message: string; system_prompt?: string; max_tokens?: number; temperature?: number; api_key?: string }
): Promise<LLMPreviewResult> => {
  return apiRequest<LLMPreviewResult>(`/llm/${id}/preview`, {
    method: 'POST',
    body: payload,
  });
};

export const fetchTools = async (): Promise<Tool[]> => {
  const response = await apiRequest<{ list?: AnyRecord[] } | AnyRecord[]>('/tools/resources');
  const list = Array.isArray(response) ? response : (response.list || []);
  return list.map((item) => mapTool(item));
};

export const createTool = async (data: Partial<Tool>): Promise<Tool> => {
  const payload = {
    id: data.id || undefined,
    name: data.name || 'New Tool',
    description: data.description || '',
    category: data.category || 'system',
    icon: data.icon || (data.category === 'query' ? 'Globe' : 'Terminal'),
    enabled: data.enabled ?? true,
  };
  const response = await apiRequest<AnyRecord>('/tools/resources', { method: 'POST', body: payload });
  return mapTool(response);
};

export const updateTool = async (id: string, data: Partial<Tool>): Promise<Tool> => {
  const payload = {
    name: data.name,
    description: data.description,
    category: data.category,
    icon: data.icon,
    enabled: data.enabled,
  };
  const response = await apiRequest<AnyRecord>(`/tools/resources/${id}`, { method: 'PUT', body: payload });
  return mapTool(response);
};

export const deleteTool = async (id: string): Promise<void> => {
  await apiRequest(`/tools/resources/${id}`, { method: 'DELETE' });
};

export const fetchWorkflows = async (): Promise<Workflow[]> => {
  const response = await apiRequest<{ list?: AnyRecord[] } | AnyRecord[]>('/workflows');
  const list = Array.isArray(response) ? response : (response.list || []);
  return list.map((item) => mapWorkflow(item));
};

export const fetchWorkflowById = async (id: string): Promise<Workflow> => {
  const list = await fetchWorkflows();
  const workflow = list.find((item) => item.id === id);
  if (!workflow) {
    throw new Error('Workflow not found');
  }
  return workflow;
};

export const createWorkflow = async (data: Partial<Workflow>): Promise<Workflow> => {
  const payload = {
    name: data.name || '新工作流',
    nodeCount: data.nodeCount ?? data.nodes?.length ?? 0,
    createdAt: data.createdAt || '',
    updatedAt: data.updatedAt || '',
    globalPrompt: data.globalPrompt || '',
    nodes: data.nodes || [],
    edges: data.edges || [],
  };
  const response = await apiRequest<AnyRecord>('/workflows', { method: 'POST', body: payload });
  return mapWorkflow(response);
};

export const updateWorkflow = async (id: string, data: Partial<Workflow>): Promise<Workflow> => {
  const payload = {
    name: data.name,
    nodeCount: data.nodeCount ?? data.nodes?.length,
    nodes: data.nodes,
    edges: data.edges,
    globalPrompt: data.globalPrompt,
  };
  const response = await apiRequest<AnyRecord>(`/workflows/${id}`, { method: 'PUT', body: payload });
  return mapWorkflow(response);
};

export const deleteWorkflow = async (id: string): Promise<void> => {
  await apiRequest(`/workflows/${id}`, { method: 'DELETE' });
};

export const fetchKnowledgeBases = async (): Promise<KnowledgeBase[]> => {
  const response = await apiRequest<{ list?: AnyRecord[] } | AnyRecord[]>('/knowledge/bases');
  const list = Array.isArray(response) ? response : (response.list || []);
  return list.map((item) => mapKnowledgeBase(item));
};

export const fetchKnowledgeBaseById = async (kbId: string): Promise<KnowledgeBase> => {
  const response = await apiRequest<AnyRecord>(`/knowledge/bases/${kbId}`);
  return mapKnowledgeBase(response);
};

export const createKnowledgeBase = async (data: {
  name: string;
  description?: string;
  embeddingModel?: string;
  chunkSize?: number;
  chunkOverlap?: number;
}): Promise<KnowledgeBase> => {
  const payload = {
    name: data.name,
    description: data.description || '',
    embeddingModel: data.embeddingModel || 'text-embedding-3-small',
    chunkSize: data.chunkSize ?? 500,
    chunkOverlap: data.chunkOverlap ?? 50,
  };
  const response = await apiRequest<AnyRecord>('/knowledge/bases', { method: 'POST', body: payload });
  return mapKnowledgeBase(response);
};

export const updateKnowledgeBase = async (kbId: string, data: Partial<KnowledgeBase>): Promise<KnowledgeBase> => {
  const payload = {
    name: data.name,
    description: data.description,
    embeddingModel: data.embeddingModel,
    chunkSize: data.chunkSize,
    chunkOverlap: data.chunkOverlap,
    status: data.status,
  };
  const response = await apiRequest<AnyRecord>(`/knowledge/bases/${kbId}`, { method: 'PUT', body: payload });
  return mapKnowledgeBase(response);
};

export const deleteKnowledgeBase = async (kbId: string): Promise<void> => {
  await apiRequest(`/knowledge/bases/${kbId}`, { method: 'DELETE' });
};

export const uploadKnowledgeDocument = async (kbId: string, file: File): Promise<void> => {
  const payload = {
    name: file.name,
    size: `${(file.size / 1024).toFixed(1)} KB`,
    fileType: file.type || 'txt',
  };
  await apiRequest(`/knowledge/bases/${kbId}/documents`, { method: 'POST', body: payload });
};

export const deleteKnowledgeDocument = async (kbId: string, docId: string): Promise<void> => {
  await apiRequest(`/knowledge/bases/${kbId}/documents/${docId}`, { method: 'DELETE' });
};

export const fetchHistory = async (): Promise<CallLog[]> => {
  const [historyResp, assistantsResp] = await Promise.all([
    apiRequest<{ list?: AnyRecord[] } | AnyRecord[]>('/history'),
    apiRequest<{ list?: AnyRecord[] } | AnyRecord[]>('/assistants'),
  ]);

  const assistantList = Array.isArray(assistantsResp) ? assistantsResp : (assistantsResp.list || []);
  const assistantNameMap = new Map<string, string>(assistantList.map((a: AnyRecord) => [String(readField(a, ['id'], '')), readField(a, ['name'], '')]));
  const historyList = Array.isArray(historyResp) ? historyResp : (historyResp.list || []);
  return historyList.map((item) => toHistoryRow(item, assistantNameMap));
};

export const fetchHistoryDetail = async (id: string, base: CallLog): Promise<CallLog> => {
  const response = await apiRequest<AnyRecord>(`/history/${id}`);
  const details = toHistoryDetails(response);
  const duration = formatDuration(readField(response, ['duration_seconds', 'durationSeconds'], 0));
  const startTime = normalizeDateLabel(readField(response, ['started_at'], base.startTime));
  return {
    ...base,
    startTime,
    duration,
    details,
  };
};
