import api from '../../api';
import type {
  AiApiResponse,
  AiAttachment,
  AiConversation,
  AiMessageFeedback,
  AiMessagePage,
  AiReviewSchema,
  AiReviewSection,
  AiReviewSectionType,
  AiSkill,
} from './types';

const basePath = '/ai/chat/conversations';

export const aiChatApi = {
  listSkills: async () => (await api.get<AiApiResponse<AiSkill[]>>('/ai/chat/skills')).data,
  listConversations: async () =>
    (await api.get<AiApiResponse<AiConversation[]>>(basePath)).data,
  createConversation: async (input?: { title?: string; lockedSkillKey?: string | null }) =>
    (await api.post<AiApiResponse<AiConversation>>(basePath, input ?? {})).data,
  updateConversation: async (
    id: number,
    input: { title?: string; lockedSkillKey?: string | null },
  ) => (await api.patch<AiApiResponse<AiConversation>>(`${basePath}/${id}`, input)).data,
  deleteConversation: (id: number) => api.delete<void>(`${basePath}/${id}`),
  deleteAllConversations: async () =>
    (await api.delete<{ success: boolean; data: { deleted: number } }>(basePath)).data,
  uploadAttachment: async (file: File): Promise<AiAttachment> => {
    const form = new FormData();
    form.append('file', file);
    return (
      await api.post<AiApiResponse<AiAttachment>>('/ai/chat/attachments', form, {
        headers: { 'Content-Type': 'multipart/form-data' },
        timeout: 120_000,
      })
    ).data;
  },
  deleteAttachment: (id: number) => api.delete<void>(`/ai/chat/attachments/${id}`),
  setFeedback: async (
    messageId: number,
    feedback: AiMessageFeedback,
    reason?: string,
  ) =>
    (
      await api.patch<AiApiResponse<{ id: number; feedback: AiMessageFeedback }>>(
        `/ai/chat/messages/${messageId}/feedback`,
        { feedback, reason },
      )
    ).data,
  confirmReviewStep: async (
    reviewId: string,
    sectionKey: AiReviewSection['key'],
  ): Promise<AiReviewSchema> =>
    (
      await api.post<AiApiResponse<AiReviewSchema>>(
        `/ai/chat/reviews/${reviewId}/steps/${sectionKey}/confirm`,
      )
    ).data,
  confirmReviewGroup: async (
    reviewId: string,
    type: AiReviewSectionType,
  ): Promise<AiReviewSchema> =>
    (
      await api.post<AiApiResponse<AiReviewSchema>>(
        `/ai/chat/reviews/${reviewId}/types/${type}/confirm`,
      )
    ).data,
  listMessages: async (id: number): Promise<AiMessagePage> => {
    const first = (
      await api.get<AiApiResponse<AiMessagePage>>(`${basePath}/${id}/messages`, {
        params: { page: 1, limit: 100 },
      })
    ).data;
    const pageCount = Math.ceil(first.total / first.limit);
    if (pageCount <= 1) return first;
    const rest = await Promise.all(
      Array.from({ length: pageCount - 1 }, (_, index) =>
        api
          .get<AiApiResponse<AiMessagePage>>(`${basePath}/${id}/messages`, {
            params: { page: index + 2, limit: first.limit },
          })
          .then((response) => response.data),
      ),
    );
    return { ...first, items: [first, ...rest].flatMap((page) => page.items) };
  },
};

export function conversationStreamUrl(id: number): string {
  return `/api${basePath}/${id}/stream`;
}

export function regenerateStreamUrl(conversationId: number, messageId: number): string {
  return `/api${basePath}/${conversationId}/messages/${messageId}/regenerate/stream`;
}
