const API_BASE = import.meta.env.VITE_API_URL || '/api'

let token: string | null = localStorage.getItem('token')

export function setToken(t: string | null) {
  token = t
  if (t) localStorage.setItem('token', t)
  else localStorage.removeItem('token')
}

export function getToken() {
  return token
}

async function request<T>(path: string, options: RequestInit = {}): Promise<T> {
  const headers: Record<string, string> = {
    'Content-Type': 'application/json',
    ...(options.headers as Record<string, string> || {}),
  }

  if (token) {
    headers['Authorization'] = `Bearer ${token}`
  }

  const res = await fetch(`${API_BASE}${path}`, { ...options, headers })

  if (!res.ok) {
    const err = await res.json().catch(() => ({ detail: res.statusText }))
    throw new Error(err.detail || 'Request failed')
  }

  if (res.status === 204) return undefined as T
  return res.json()
}

export interface User {
  id: string
  email: string
  api_key: string
  plan: string
  created_at: string
}

export interface Collection {
  id: string
  user_id: string
  name: string
  ticket_count: number
  created_at: string
}

export interface SearchResult {
  answer: string | null
  sources: { ticket_id: string; score: number; category: string; full_text: string }[]
}

export const api = {
  register: (email: string, password: string, plan = 'free') =>
    request<{ access_token: string }>('/register', {
      method: 'POST',
      body: JSON.stringify({ email, password, plan }),
    }),

  login: (email: string, password: string) =>
    request<{ access_token: string }>('/login', {
      method: 'POST',
      body: JSON.stringify({ email, password }),
    }),

  me: () => request<User>('/me'),

  createCollection: (name: string) =>
    request<Collection>('/collections', {
      method: 'POST',
      body: JSON.stringify({ name }),
    }),

  listCollections: () => request<Collection[]>('/collections'),

  getCollection: (id: string) => request<Collection>(`/collections/${id}`),

  deleteCollection: (id: string) =>
    request<void>(`/collections/${id}`, { method: 'DELETE' }),

  search: (collectionId: string, query: string, generateAnswer = true) =>
    request<SearchResult>('/search', {
      method: 'POST',
      body: JSON.stringify({ collection_id: collectionId, query, generate_answer: generateAnswer }),
    }),

  uploadFile: async (collectionId: string, file: File) => {
    const formData = new FormData()
    formData.append('file', file)

    const currentToken = getToken()
    const headers: Record<string, string> = {}
    if (currentToken) headers['Authorization'] = `Bearer ${currentToken}`

    const res = await fetch(`${API_BASE}/collections/${collectionId}/tickets/upload`, {
      method: 'POST',
      headers,
      body: formData,
    })

    if (!res.ok) {
      const text = await res.text().catch(() => '')
      let detail = res.statusText
      try { const j = JSON.parse(text); detail = j.detail || detail } catch {}
      throw new Error(`Upload failed (${res.status}): ${detail}`)
    }

    return res.json() as Promise<{ processed: number; skipped: number; collection_ticket_count: number }>
  },

  uploadTickets: (collectionId: string, tickets: any[]) =>
    request<{ processed: number; skipped: number; collection_ticket_count: number }>(
      `/collections/${collectionId}/tickets`,
      {
        method: 'POST',
        body: JSON.stringify({ tickets }),
      },
    ),

  rotateApiKey: () => request<{ api_key: string }>('/api/v1/me/api-key', { method: 'PATCH' }),
}
