import axios from './api/index'
import { getAppConfig, getXsrfToken } from '@/lib/utils'

export const API = {
  getAgents: () => axios.get('/api/agents'),
  getAgent: (agentId: string) => axios.get(`/api/agents/${agentId}`),
  createAgent: (formData: FormData) => axios.post('/api/agents', formData),
  deleteAgent: (agentId: string) => axios.delete(`/api/agents/${agentId}`),
  updateAgentShares: (agentId: string, shares: any[]) =>
    axios.put(`/api/agents/${agentId}/shares`, { shares }),

  getAgentShares: (agentId: string) => axios.get(`/api/agents/${agentId}/shares`),

  getCurrentUser: () => axios.get('/api/users/me'),
  listAgentOwners: () => axios.get('/api/users/agent-owners'),

  searchPrincipals: (q: string, kind?: 'user' | 'group', excludeGroups?: string[]) =>
    axios.get('/api/principals/search', {
      params: { q, kind, excludeGroups: excludeGroups?.join(',') },
    }),

  searchGroups: () => axios.get('/api/groups/search'),
  publishAgent: (agentId: string) => axios.post(`/api/agents/${agentId}/publish`),

  getPublishingStatus: (agentId: string) => axios.get(`/api/agents/${agentId}/publishing_status`),

  discardAgentChanges: (agentId: string) => axios.post(`/api/agents/${agentId}/discard`),

  getTools: () => axios.get('/api/tools'),

  getPreferences: () => axios.get('/api/preferences'),
  updatePreferences: (payload: Record<string, any>) => axios.put('/api/preferences', payload),

  getLlms: () => axios.get('/api/llms'),

  uploadAgentDocument: (agentId: string, files: File[]) => {
    const form = new FormData()
    files.forEach((f) => form.append('documents', f))
    return axios.post(`/api/agents/${agentId}/documents`, form)
  },
  indexAgentDocuments: (agentId: string) => axios.post(`/api/agents/${agentId}/documents/index`),
  deleteAgentDocument: (agentId: string, filename: string) =>
    axios.delete(`/api/agents/${agentId}/documents/${encodeURIComponent(filename)}`),

  deleteAgentDocuments: (agentId: string, filenames: string[]) =>
    axios.delete(`/api/agents/${agentId}/documents`, { data: { filenames } }),

  getIndexStatus: (agentId: string) => axios.get(`/api/agents/${agentId}/index_status`),

  getIndexStatusBulk: (agentIds: string[]) =>
    axios.post(`/api/agents/index_status_bulk`, { agentIds }),

  getConversations: () => axios.get('/api/conversations'),
  getConversation: (conversationId: string) => axios.get(`/api/conversations/${conversationId}`),
  getConversationsMetadata: () => axios.get('/api/conversations/metadata'),
  deleteConversation: (conversationId: string) =>
    axios.delete(`/api/conversations/${conversationId}`),
  deleteAllConversations: () => axios.delete(`/api/conversations`),
  updateConversationTitle: (conversationId: string, payload: { title: string }) =>
    axios.put(`/api/conversations/${conversationId}`, payload),

  getMessageEvents: (messageId: string, params: Record<string, string> = {}) =>
    axios.get(`/api/conversations/message_events/${messageId}`, { params }),

  deleteDraftConversation: (agentId: string) => axios.delete(`/api/conversations/draft/${agentId}`),

  getDraftConversation: (agentId: string) => axios.get(`/api/conversations/draft/${agentId}`),
  createStory: (data: any) => axios.post('api/stories', data),
  createChartPlan: (data: any) => axios.post('api/chart/plan', data),
  getUIConfig: () => axios.get('api/config'),
  getAgentConfig: (data: any) => axios.post('api/config/smart_agent_details', data),
  markAgentAsFavorite: (agentId: string, favorite: boolean) =>
    axios.post(`/api/agents/${agentId}/favorite`, { favorite }),

  // Message feedback
  getMessageFeedback: (messageId: string) =>
    axios.get(`/api/conversations/messages/${messageId}/feedback`),

  upsertMessageFeedback: (messageId: string, payload: { rating: 1 | 0; text?: string }) =>
    axios.put(`/api/conversations/messages/${messageId}/feedback`, payload),

  clearMessageFeedback: (messageId: string) =>
    axios.delete(`/api/conversations/messages/${messageId}/feedback`),

  getDashboardTiles: (
    params: {
      from: string
      to: string
      agentType?: 'all' | 'user' | 'enterprise'
      ownerId?: string | null
    },
    options?: { signal?: AbortSignal }
  ) => axios.get('/api/dashboard/tiles', { params, ...(options ?? {}) }),

  getDashboardUsage: (
    params: {
      bucket: 'day' | 'week' | 'month'
      from: string
      to: string
      agentId?: string
      agentType?: 'all' | 'user' | 'enterprise'
      ownerId?: string | null
    },
    options?: { signal?: AbortSignal }
  ) => axios.get('/api/dashboard/usage', { params, ...(options ?? {}) }),

  getDashboardFeedback: (
    params: {
      from: string
      to: string
      agentId?: string
      agentType?: 'all' | 'user' | 'enterprise'
      ownerId?: string | null
    },
    options?: { signal?: AbortSignal }
  ) => axios.get('/api/dashboard/feedback', { params, ...(options ?? {}) }),

  getDashboardActivity: (
    params: {
      from: string
      to: string
      agentId?: string
      limit?: number
      offset?: number
      q?: string
      sortBy?: string
      sortDir?: string
      groupBy?: string
      agentType?: 'all' | 'user' | 'enterprise'
      ownerId?: string | null
    },
    options?: { signal?: AbortSignal }
  ) =>
    axios.get('/api/dashboard/activity', {
      params,
      ...(options ?? {}),
    }),

  getDashboardMyAgents: (params?: { ownerId?: string | null }) =>
    axios.get('/api/dashboard/my-agents', { params }),

  // -------------------- Plugins / Public info --------------------
  getPluginInfo: async (pluginId: string): Promise<{ installed: boolean; version?: string }> => {
    try {
      const response = await axios.get(`/api/plugins/${pluginId}/info`)
      return {
        installed: true,
        version: response.data.version,
      }
    } catch (error: any) {
      if (error.response?.status === 404) {
        return { installed: false, version: undefined }
      }
      console.error('Error fetching plugin info:', error)
      throw error
    }
  },

  getPublicInfo: async (projectKey: string, webAppId: string): Promise<any> => {
    try {
      const appConfig = getAppConfig()
      if (!appConfig) throw new Error('App config is not available.')

      const xsrfToken = getXsrfToken()
      if (!xsrfToken) throw new Error('XSRF token is missing from app config.')

      const response = await axios.get(
        `${window.location.origin}/dip/api/webapps/get-public-info`,
        {
          params: { projectKey, webAppId },
          headers: {
            'Content-Type': 'application/json',
            'X-Requested-With': 'XMLHttpRequest',
            'X-XSRF-TOKEN': xsrfToken,
          },
          withCredentials: true,
        }
      )
      return response.data
    } catch (error) {
      console.error(
        `Error fetching public info for web app ${webAppId} in project ${projectKey}:`,
        error
      )
      throw error
    }
  },

  async updateMessage(conversationId: string, messageId: string, payload: { content: string }) {
    return await axios.put(`api/conversations/${conversationId}/messages/${messageId}`, payload)
  },

  downloadArtifacts: (msgId: string) =>
    axios.get(`/api/downloads/messages/${msgId}`, { responseType: 'blob' }),
  downloadArtifactsById: (msgId: string, artId: string, artIndex: number) =>
    axios.get(`/api/downloads/messages/${msgId}/artifacts/${artId}/${artIndex}`, {
      responseType: 'blob',
    }),
  downloadAttachment: (documentPath: string, filename?: string, type?: string) => {
    const params = new URLSearchParams({ path: documentPath })
    if (filename) params.append('filename', filename)
    if (type) params.append('type', type)
    return axios.get(`/api/downloads/attachments?${params.toString()}`, {
      responseType: 'blob',
    })
  },
  // Add this new API endpoint method
  getMessageTrace: (messageId: string, params: Record<string, string> = {}) =>
    axios.get(`/api/conversations/messages/${messageId}/trace`, { params }),

  uploadFiles: (form: FormData) => axios.post('/api/upload', form),

  // Add API method for creating new conversation (used when uploading attachements and refreshing the page)
  createConversation: (payload: { title?: string; agentIds?: string[] }) => {
    return axios.post('/api/conversations', payload)
  },

  deleteUploadedAttachment: (path: string) => axios.delete('/api/uploads', { data: { path } }),

  // -------------------- Admin config & prompts library --------------------
  getAdminConfig: () => axios.get('/api/admin/config').then((r) => r.data),
  saveAdminConfig: (payload: { config: any; etag?: string; socketId?: string }) =>
    axios.put('/api/admin/config', payload).then((r) => r.data),

  listEnterpriseProjects: () => axios.get('/api/admin/enterprise/projects').then((r) => r.data),

  listEnterpriseProjectAgents: (projectKey: string) =>
    axios
      .get(`/api/admin/enterprise/projects/${encodeURIComponent(projectKey)}/agents`)
      .then((r) => r.data),

  listMyAgentsOptions: () => axios.get('/api/admin/myagents/options').then((r) => r.data),

  listAvailableLLMs: () => axios.get('/api/admin/llms/available').then((r) => r.data),

  getManagedFolders: () => axios.get('/api/admin/managed-folders').then((r) => r.data),

  getPromptsLibrary: () => axios.get('/api/admin/prompts/library').then((r) => r.data),

  savePromptsLibrary: (payload: {
    data: { version: string; prompts: any[] }
    etag?: string
    socketId?: string
  }) => axios.put('/api/admin/prompts/library', payload).then((r) => r.data),

  getPromptsLibraryForUsers: () => axios.get('/api/prompts/library').then((r) => r.data),
}

export const APIErrors: any[] = []
