import apiClient from './client'
import type {
  AISessionCreateRequest,
  AISessionCreateResponse,
  StepResponseRequest,
  StepResponseResponse,
  ResolveSessionRequest,
  EscalateSessionRequest,
  SessionCloseResponse,
  SessionDocumentation,
  AISessionSummary,
  AISessionDetail,
  AISessionSearchResult,
  SimilarSession,
  PickupSessionRequest,
  StatusUpdateRequest,
  StatusUpdateResponse,
  ChatSessionCreateResponse,
  ChatMessageRequest,
  ChatMessageResponse,
} from '@/types/ai-session'

export const aiSessionsApi = {
  async createSession(data: AISessionCreateRequest): Promise<AISessionCreateResponse> {
    const response = await apiClient.post<AISessionCreateResponse>('/ai-sessions', data)
    return response.data
  },

  async createChatSession(data: AISessionCreateRequest): Promise<ChatSessionCreateResponse> {
    const response = await apiClient.post<ChatSessionCreateResponse>('/ai-sessions', {
      ...data,
      session_type: 'chat',
    })
    return response.data
  },

  async sendChatMessage(sessionId: string, data: ChatMessageRequest): Promise<ChatMessageResponse> {
    const response = await apiClient.post<ChatMessageResponse>(
      `/ai-sessions/${sessionId}/chat`,
      data
    )
    return response.data
  },

  async respondToStep(sessionId: string, data: StepResponseRequest): Promise<StepResponseResponse> {
    const response = await apiClient.post<StepResponseResponse>(
      `/ai-sessions/${sessionId}/respond`,
      data
    )
    return response.data
  },

  async resolveSession(sessionId: string, data: ResolveSessionRequest): Promise<SessionCloseResponse> {
    const response = await apiClient.post<SessionCloseResponse>(
      `/ai-sessions/${sessionId}/resolve`,
      data
    )
    return response.data
  },

  async escalateSession(sessionId: string, data: EscalateSessionRequest): Promise<SessionCloseResponse> {
    const response = await apiClient.post<SessionCloseResponse>(
      `/ai-sessions/${sessionId}/escalate`,
      data
    )
    return response.data
  },

  async listSessions(params?: {
    status?: string
    session_type?: string
    skip?: number
    limit?: number
    problem_domain?: string
    matched_flow_id?: string
    confidence_tier?: string
    ticket_id?: string
    date_from?: string
    date_to?: string
    q?: string
  }): Promise<AISessionSummary[]> {
    // Strip empty string values so they aren't sent as empty query params
    const cleanParams = params
      ? Object.fromEntries(Object.entries(params).filter(([, v]) => v !== '' && v !== undefined))
      : undefined
    const response = await apiClient.get<AISessionSummary[]>('/ai-sessions', { params: cleanParams })
    return response.data
  },

  async getSession(sessionId: string): Promise<AISessionDetail> {
    const response = await apiClient.get<AISessionDetail>(`/ai-sessions/${sessionId}`)
    return response.data
  },

  async getDocumentation(sessionId: string): Promise<SessionDocumentation> {
    const response = await apiClient.get<SessionDocumentation>(
      `/ai-sessions/${sessionId}/documentation`
    )
    return response.data
  },

  async streamDocumentation(
    sessionId: string,
    onChunk: (text: string) => void,
    onDone: () => void,
    onError: (error: string) => void,
  ): Promise<void> {
    const token = localStorage.getItem('access_token')
    const baseUrl = import.meta.env.VITE_API_URL || ''

    try {
      const response = await fetch(
        `${baseUrl}/api/v1/ai-sessions/${sessionId}/documentation/stream`,
        {
          headers: {
            Authorization: `Bearer ${token}`,
          },
        },
      )

      if (!response.ok) {
        onError(`HTTP ${response.status}`)
        return
      }

      const reader = response.body?.getReader()
      if (!reader) {
        onError('No response body')
        return
      }

      const decoder = new TextDecoder()
      let buffer = ''

      while (true) {
        const { done, value } = await reader.read()
        if (done) break

        buffer += decoder.decode(value, { stream: true })
        const lines = buffer.split('\n')
        buffer = lines.pop() || ''

        for (const line of lines) {
          if (line.startsWith('data: ')) {
            const data = line.slice(6)
            if (data === '[DONE]') {
              onDone()
              return
            }
            if (data.startsWith('[ERROR]')) {
              onError(data.slice(8))
              return
            }
            onChunk(data)
          }
        }
      }
      // Stream ended without [DONE]
      onDone()
    } catch (err) {
      onError(err instanceof Error ? err.message : 'Stream failed')
    }
  },

  async rateSession(sessionId: string, data: { rating: number; feedback?: string }): Promise<void> {
    await apiClient.post(`/ai-sessions/${sessionId}/rate`, data)
  },

  async retryPsaPush(sessionId: string): Promise<{ psa_push_status: string; psa_push_error: string | null }> {
    const response = await apiClient.post<{ psa_push_status: string; psa_push_error: string | null }>(
      `/ai-sessions/${sessionId}/retry-psa-push`
    )
    return response.data
  },

  async saveTaskLane(sessionId: string, data: {
    questions: Array<{ text: string; context?: string }>;
    actions: Array<{ label: string; command?: string | null; description?: string }>;
    responses: Array<Record<string, unknown>>;
  }): Promise<void> {
    await apiClient.put(`/ai-sessions/${sessionId}/task-lane`, data)
  },

  async pauseSession(sessionId: string): Promise<void> {
    await apiClient.post(`/ai-sessions/${sessionId}/pause`)
  },

  async resumeSession(sessionId: string): Promise<void> {
    await apiClient.post(`/ai-sessions/${sessionId}/resume`)
  },

  async abandonSession(sessionId: string, reason?: string): Promise<void> {
    await apiClient.post(`/ai-sessions/${sessionId}/abandon`, null, {
      params: reason ? { reason } : undefined,
    })
  },

  async deleteSession(sessionId: string): Promise<void> {
    await apiClient.delete(`/ai-sessions/${sessionId}`)
  },

  async pickupSession(sessionId: string, data: PickupSessionRequest): Promise<StepResponseResponse> {
    const response = await apiClient.post<StepResponseResponse>(
      `/ai-sessions/${sessionId}/pickup`,
      data
    )
    return response.data
  },

  async linkTicket(sessionId: string, data: { psa_ticket_id: string; psa_connection_id: string }): Promise<AISessionDetail> {
    const response = await apiClient.post<AISessionDetail>(
      `/ai-sessions/${sessionId}/link-ticket`,
      data
    )
    return response.data
  },

  async getEscalationQueue(): Promise<AISessionSummary[]> {
    const response = await apiClient.get<AISessionSummary[]>('/ai-sessions/escalation-queue')
    return response.data
  },

  async search(q: string, limit: number = 5): Promise<AISessionSearchResult[]> {
    const response = await apiClient.get<AISessionSearchResult[]>('/ai-sessions/search', {
      params: { q, limit },
    })
    return response.data
  },

  async getSimilar(sessionId: string, limit: number = 5): Promise<SimilarSession[]> {
    const response = await apiClient.get<SimilarSession[]>(`/ai-sessions/${sessionId}/similar`, {
      params: { limit },
    })
    return response.data
  },

  async generateStatusUpdate(sessionId: string, data: StatusUpdateRequest): Promise<StatusUpdateResponse> {
    const response = await apiClient.post<StatusUpdateResponse>(
      `/ai-sessions/${sessionId}/status-update`,
      data
    )
    return response.data
  },
}

export default aiSessionsApi
