import api from './client'

// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------

export interface CadObjects {
  cad_file_id: string
  original_name: string
  processing_status: 'pending' | 'processing' | 'completed' | 'failed'
  parsed_objects: Record<string, unknown> | null
}

export interface RegenerateThumbnailResponse {
  cad_file_id: string
  original_name: string
  status: 'queued'
  task_id: string | null
}

// ---------------------------------------------------------------------------
// API functions
// ---------------------------------------------------------------------------

/**
 * Returns the URL to the thumbnail PNG for a CAD file.
 * Use directly in <img src={getCadThumbnailUrl(id)} /> – the browser will
 * handle the authenticated request via the axios interceptor when called
 * programmatically, or you can construct the URL for use in img tags when
 * the auth token is set as a header.
 *
 * For use in <img> tags without auth headers, prefer fetching as a blob and
 * creating an object URL (see fetchThumbnailBlob below).
 */
export function getCadThumbnailUrl(cadFileId: string): string {
  return `/api/cad/${cadFileId}/thumbnail`
}

/**
 * Fetch the thumbnail PNG as a Blob and return an object URL suitable for
 * use in <img src=...> without needing explicit auth headers.
 * Remember to call URL.revokeObjectURL() when the component unmounts.
 */
export async function fetchThumbnailBlob(cadFileId: string): Promise<string> {
  const res = await api.get<Blob>(`/cad/${cadFileId}/thumbnail`, {
    responseType: 'blob',
  })
  return URL.createObjectURL(res.data)
}

/**
 * Fetch the glTF model file as a Blob and return an object URL.
 * Remember to call URL.revokeObjectURL() when the consumer is done.
 */
export async function fetchModelBlob(cadFileId: string): Promise<string> {
  const res = await api.get<Blob>(`/cad/${cadFileId}/model`, {
    responseType: 'blob',
  })
  return URL.createObjectURL(res.data)
}

/**
 * Return the parsed_objects JSON for a CAD file.
 */
export async function getCadObjects(cadFileId: string): Promise<CadObjects> {
  const res = await api.get<CadObjects>(`/cad/${cadFileId}/objects`)
  return res.data
}

/**
 * Download the cached STL for a CAD file as a file-save dialog.
 * quality: 'low' | 'high'
 * The backend returns a human-readable filename, but we derive it client-side too.
 */
export async function downloadStl(cadFileId: string, quality: 'low' | 'high', suggestedName?: string): Promise<void> {
  const res = await api.get<Blob>(`/cad/${cadFileId}/stl/${quality}`, {
    responseType: 'blob',
  })
  const url = URL.createObjectURL(res.data)
  const a = document.createElement('a')
  a.href = url
  a.download = suggestedName ? `${suggestedName}_${quality}.stl` : `model_${quality}.stl`
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
  URL.revokeObjectURL(url)
}

export async function generateStl(cadFileId: string, quality: 'low' | 'high'): Promise<{ task_id: string }> {
  const res = await api.post<{ task_id: string }>(`/cad/${cadFileId}/generate-stl/${quality}`)
  return res.data
}

/**
 * Ask the backend to re-queue STEP processing for a CAD file (admin only).
 * Returns the Celery task_id (or null if the worker is not available).
 */
export async function regenerateThumbnail(
  cadFileId: string,
): Promise<RegenerateThumbnailResponse> {
  const res = await api.post<RegenerateThumbnailResponse>(
    `/cad/${cadFileId}/regenerate-thumbnail`,
  )
  return res.data
}

export interface GenerateGltfResponse {
  status: 'queued'
  task_id: string
  cad_file_id: string
}

/**
 * Queue GLB geometry export from existing STL cache (trimesh, no Blender).
 * The STL low-quality cache must already exist.
 */
export async function generateGltfGeometry(cadFileId: string): Promise<GenerateGltfResponse> {
  const res = await api.post<GenerateGltfResponse>(`/cad/${cadFileId}/generate-gltf-geometry`)
  return res.data
}

export const exportGltfColored = (id: string): Promise<void> =>
  api.get(`/cad/${id}/export-gltf-colored`, { responseType: 'blob' }).then(r => {
    const url = URL.createObjectURL(r.data)
    const a = document.createElement('a')
    a.href = url
    a.download = `${id}_colored.glb`
    document.body.appendChild(a)
    a.click()
    document.body.removeChild(a)
    URL.revokeObjectURL(url)
  })
