import {
  API_KEY,
  DOCS_BLOB_BASE_URL,
  DOCS_FOLDERS_URL,
  DOCS_NODES_BASE_URL,
  DOCS_NODES_URL,
  DOCS_TEXT_FILES_URL,
  DOCS_UPLOAD_URL,
} from './config.js'

function buildHeaders(extra = {}) {
  return API_KEY
    ? {
        'X-API-Key': API_KEY,
        ...extra,
      }
    : { ...extra }
}

async function parseJsonResponse(res) {
  if (!res.ok) {
    let message = `HTTP ${res.status}`
    try {
      const data = await res.json()
      message = data.detail || data.error || message
    } catch {
      const text = await res.text()
      if (text) message = text
    }
    throw new Error(message)
  }
  return res.json()
}

export async function fetchDocNodes() {
  const res = await fetch(DOCS_NODES_URL, {
    headers: buildHeaders(),
    credentials: 'include',
  })
  const data = await parseJsonResponse(res)
  return Array.isArray(data.nodes) ? data.nodes : []
}

export async function createDocFolder(name, parentId = null) {
  const res = await fetch(DOCS_FOLDERS_URL, {
    method: 'POST',
    headers: buildHeaders({ 'Content-Type': 'application/json' }),
    credentials: 'include',
    body: JSON.stringify({ name, parentId }),
  })
  const data = await parseJsonResponse(res)
  return data.node
}

export async function createDocTextFile(name, parentId = null, content = '') {
  const res = await fetch(DOCS_TEXT_FILES_URL, {
    method: 'POST',
    headers: buildHeaders({ 'Content-Type': 'application/json' }),
    credentials: 'include',
    body: JSON.stringify({ name, parentId, content }),
  })
  const data = await parseJsonResponse(res)
  return data.node
}

export async function uploadDocFile(file, parentId = null) {
  const formData = new FormData()
  formData.append('file', file)
  formData.append('parent_id', parentId || '')
  const res = await fetch(DOCS_UPLOAD_URL, {
    method: 'POST',
    headers: buildHeaders(),
    credentials: 'include',
    body: formData,
  })
  const data = await parseJsonResponse(res)
  return data.node
}

export async function updateDocNode(nodeId, payload) {
  const res = await fetch(`${DOCS_NODES_BASE_URL}/${encodeURIComponent(nodeId)}`, {
    method: 'PATCH',
    headers: buildHeaders({ 'Content-Type': 'application/json' }),
    credentials: 'include',
    body: JSON.stringify(payload),
  })
  const data = await parseJsonResponse(res)
  return data.node
}

export async function replaceDocBlob(nodeId, file) {
  const formData = new FormData()
  formData.append('file', file, file.name || 'file')
  const res = await fetch(`${DOCS_BLOB_BASE_URL}/${encodeURIComponent(nodeId)}/blob`, {
    method: 'PUT',
    headers: buildHeaders(),
    credentials: 'include',
    body: formData,
  })
  const data = await parseJsonResponse(res)
  return data.node
}

export async function deleteDocNode(nodeId) {
  const res = await fetch(`${DOCS_NODES_BASE_URL}/${encodeURIComponent(nodeId)}`, {
    method: 'DELETE',
    headers: buildHeaders(),
    credentials: 'include',
  })
  return parseJsonResponse(res)
}

export async function fetchDocBlob(nodeId) {
  const res = await fetch(`${DOCS_BLOB_BASE_URL}/${encodeURIComponent(nodeId)}/blob`, {
    headers: buildHeaders(),
    credentials: 'include',
  })
  if (!res.ok) {
    let message = `HTTP ${res.status}`
    try {
      const data = await res.json()
      message = data.detail || data.error || message
    } catch {
      const text = await res.text()
      if (text) message = text
    }
    throw new Error(message)
  }
  return res.blob()
}
