import type { ServerSentEventMessage } from 'fetch-event-stream';

import type { AgentInfo } from '../agents/types';

import { api, SseClient } from '#/api/request';

const agentChatSseClient = new SseClient();

export interface RequestResult<T = any> {
  data: T;
  errorCode: number;
  message?: string;
}

export interface AgentChatSessionView {
  accessAt?: string;
  assistantCode?: string;
  assistantId?: number | string;
  assistantName?: string;
  continuable?: boolean;
  lastMessageAt?: string;
  lastMessagePreview?: string;
  messageCount?: number;
  readOnlyReason?: unknown;
  sessionId?: number | string;
  title?: string;
}

export interface AgentChatKnowledgeView {
  alias?: string;
  description?: string;
  icon?: string;
  id?: number | string;
  title?: string;
}

export interface AgentChatSessionDetailView extends AgentChatSessionView {
  boundKnowledges?: AgentChatKnowledgeView[];
  extraKnowledges?: AgentChatKnowledgeView[];
  removedExtraKnowledgeNames?: string[];
}

export interface AgentChatSessionPage {
  pageNumber?: number;
  pageSize?: number;
  records?: AgentChatSessionView[];
  total?: number;
}

export interface AgentChatMessageRecord {
  assistantId?: number | string;
  contentPayload?: Record<string, any>;
  contentText?: string;
  contentType?: string;
  created?: string;
  id?: number | string;
  messageKind?: string;
  roundId?: number | string;
  roundNo?: number;
  selectedVariantIndex?: number;
  senderName?: string;
  senderRole?: string;
  sessionId?: number | string;
  switchable?: boolean;
  variantCount?: number;
  variantIndex?: number;
}

export interface AgentChatConversationView {
  records?: AgentChatMessageRecord[];
  total?: number;
  variantsByRound?: Record<string, AgentChatMessageRecord[]>;
}

export interface AgentChatCapabilityPayload {
  resourceIds: Array<number | string>;
  type: 'KNOWLEDGE';
}

export function getPublishedAgents() {
  return api.get<RequestResult<AgentInfo[]>>('/api/v1/agent/list', {
    params: { publishedOnly: true },
  });
}

export function generateAgentSessionId() {
  return api.get<RequestResult<string>>('/api/v1/agent/session/generateId');
}

export function getAgentSession(sessionId: number | string) {
  return api.get<RequestResult<AgentChatSessionDetailView>>(
    `/api/v1/agent/session/${sessionId}`,
  );
}

export function getPublishedKnowledges() {
  return api.get<RequestResult<AgentChatKnowledgeView[]>>(
    '/api/v1/documentCollection/list',
    {
      params: { publishedOnly: true },
    },
  );
}

export function getAgentSessions(params?: {
  agentId?: number | string;
  pageNumber?: number;
  pageSize?: number;
}) {
  return api.get<RequestResult<AgentChatSessionPage>>(
    '/api/v1/agent/session/list',
    {
      params: {
        pageNumber: params?.pageNumber ?? 1,
        pageSize: params?.pageSize ?? 50,
        ...(params?.agentId ? { agentId: params.agentId } : {}),
      },
    },
  );
}

export function getAgentConversation(sessionId: number | string) {
  return api.get<RequestResult<AgentChatConversationView>>(
    `/api/v1/agent/session/${sessionId}/conversation`,
  );
}

export function renameAgentSession(sessionId: number | string, title: string) {
  return api.post<RequestResult>(`/api/v1/agent/session/${sessionId}/rename`, {
    title,
  });
}

export function saveAgentSessionExtraKnowledges(
  sessionId: number | string,
  knowledgeIds: Array<number | string>,
) {
  return api.post<RequestResult<AgentChatSessionDetailView>>(
    `/api/v1/agent/session/${sessionId}/extraKnowledges`,
    {
      knowledgeIds,
    },
  );
}

export function deleteAgentSession(sessionId: number | string) {
  return api.post<RequestResult>(`/api/v1/agent/session/${sessionId}/delete`);
}

export function approveAgentRun(requestId: string, resumeToken: string) {
  return api.post<RequestResult>('/api/v1/agent/run/approve', {
    requestId,
    resumeToken,
  });
}

export function rejectAgentRun(
  requestId: string,
  resumeToken: string,
  reason?: string,
) {
  return api.post<RequestResult>('/api/v1/agent/run/reject', {
    requestId,
    resumeToken,
    reason,
  });
}

export function sendAgentChat(
  data: {
    agentId: number | string;
    capabilities?: AgentChatCapabilityPayload[];
    imageUploadIds?: string[];
    prompt: string;
    sessionId?: number | string;
  },
  options: {
    onError?: (error: unknown) => void;
    onFinished?: () => void;
    onMessage?: (message: ServerSentEventMessage) => void;
  },
) {
  return agentChatSseClient.post('/api/v1/agent/chat', data, options);
}

export function stopAgentChatStream() {
  agentChatSseClient.abort();
}
