const BASE = '/api'

// Backend-Fehler (400/409 mit detail) als Error werfen statt sie zu verschlucken
async function jsonOrThrow(res) {
  if (!res.ok) {
    let detail = `Fehler (HTTP ${res.status})`
    try {
      const data = await res.json()
      if (data.detail) detail = typeof data.detail === 'string' ? data.detail : JSON.stringify(data.detail)
    } catch { /* kein JSON-Body */ }
    throw new Error(detail)
  }
  return res.json()
}

export async function fetchGuides() {
  const res = await fetch(`${BASE}/guides`)
  return res.json()
}

export async function fetchGuideLocks(topic) {
  const res = await fetch(`${BASE}/guides/locks?topic=${encodeURIComponent(topic)}`)
  return res.json()
}

export async function createGuide(topic, format, instructions = '', provider = 'claude') {
  const res = await fetch(`${BASE}/guides`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ topic, format, instructions, provider }),
  })
  return jsonOrThrow(res)
}

export async function fetchActiveBausteine() {
  const res = await fetch(`${BASE}/bausteine/active`)
  return res.json()
}

export async function fetchBausteineStatus(topic) {
  const res = await fetch(`${BASE}/bausteine/status?topic=${encodeURIComponent(topic)}`)
  return res.json()
}

export async function createBausteine(topic, instructions = '', provider = 'claude', sourceType = 'thema', sourceOrt = '', abPhase = null) {
  const res = await fetch(`${BASE}/bausteine`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ topic, instructions, provider, source_type: sourceType, source_ort: sourceOrt, ab_phase: abPhase }),
  })
  return jsonOrThrow(res)
}

export async function cancelBausteine(topic) {
  await fetch(`${BASE}/bausteine/cancel?topic=${encodeURIComponent(topic)}`, { method: 'POST' })
}

export async function deleteBausteine(topic) {
  await fetch(`${BASE}/bausteine?topic=${encodeURIComponent(topic)}`, { method: 'DELETE' })
}

// --- Baustein-Lernen: Chat, Prüfung ---

export async function fetchBausteinLernstand(topic) {
  const res = await fetch(`${BASE}/bausteine/lernstand?topic=${encodeURIComponent(topic)}`)
  return jsonOrThrow(res)
}

export async function chatBaustein({ topic, baustein, section, section_kompakt = '', messages, provider }) {
  const res = await fetch(`${BASE}/bausteine/chat`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ topic, baustein, section, section_kompakt, messages, provider }),
  })
  return jsonOrThrow(res)
}

export async function pruefeBaustein({
  topic, baustein, section, section_kompakt = '', provider,
  aktion = 'frage', frage = '', letzte_bewertung = '', vermeide = [],
  nachgefragt = false, begruendung = '', muster = '', cap = 6, messages = [], gruendlich = false,
  auswahl = [], korrekt = [], loesung = '', alternativen = [], eingabe = '', schwer = false,
}) {
  const res = await fetch(`${BASE}/bausteine/pruefung`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ topic, baustein, section, section_kompakt, aktion, frage, letzte_bewertung, vermeide, nachgefragt, begruendung, muster, cap, messages, provider, gruendlich, auswahl, korrekt, loesung, alternativen, eingabe, schwer }),
  })
  return jsonOrThrow(res)
}

export async function fetchFrageMuster(topic, baustein) {
  const res = await fetch(`${BASE}/bausteine/frage-muster?topic=${encodeURIComponent(topic)}&baustein=${encodeURIComponent(baustein)}`)
  return jsonOrThrow(res)
}

export async function fetchTopicFortschritt(topic) {
  const res = await fetch(`${BASE}/topics/fortschritt?topic=${encodeURIComponent(topic)}`)
  return res.json()
}

export async function fetchStats() {
  const res = await fetch(`${BASE}/stats`)
  return res.json()
}

export async function fetchProviders() {
  const res = await fetch(`${BASE}/providers`)
  return res.json()
}

export async function fetchProjects() {
  const res = await fetch(`${BASE}/projects`)
  return res.json()
}

export async function fetchFolders(kind) {
  const res = await fetch(`${BASE}/folders?kind=${encodeURIComponent(kind)}`)
  return jsonOrThrow(res)
}

export async function fetchQuelle(topic) {
  const res = await fetch(`${BASE}/bausteine/quelle?topic=${encodeURIComponent(topic)}`)
  return jsonOrThrow(res)
}

export async function updateQuelle(topic, { type, ort = '', spec = '' }) {
  const res = await fetch(`${BASE}/bausteine/quelle`, {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ topic, type, ort, spec }),
  })
  return jsonOrThrow(res)
}

export async function fetchBausteineUebersicht(topic) {
  const res = await fetch(`${BASE}/bausteine/uebersicht?topic=${encodeURIComponent(topic)}`)
  return jsonOrThrow(res)
}

export async function deleteProject(name) {
  await fetch(`${BASE}/projects/${encodeURIComponent(name)}`, { method: 'DELETE' })
}

export async function cancelGuide(id) {
  await fetch(`${BASE}/guides/${id}/cancel`, { method: 'POST' })
}

export async function deleteGuide(id, slots = false) {
  await fetch(`${BASE}/guides/${id}${slots ? '?slots=1' : ''}`, { method: 'DELETE' })
}

export async function fetchGuideContent(id) {
  const res = await fetch(`${BASE}/guides/${id}/content`)
  if (!res.ok) throw new Error(`Inhalt nicht verfügbar (${res.status})`)
  return res.json()
}

export async function fetchTopics() {
  const res = await fetch(`${BASE}/topics`)
  return res.json()
}

export async function createTopic(name) {
  await fetch(`${BASE}/topics`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ name }),
  })
}

export async function deleteTopic(name) {
  await fetch(`${BASE}/topics?topic=${encodeURIComponent(name)}`, { method: 'DELETE' })
}

export async function chatGuide(id, { section, outline, messages, provider = 'claude' }) {
  const res = await fetch(`${BASE}/guides/${id}/chat`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ section, outline, messages, provider }),
  })
  return res.json()
}

export async function fetchElements(topic) {
  const res = await fetch(`${BASE}/elements?topic=${encodeURIComponent(topic)}`)
  return res.json()
}

export async function createElement(topic, hint = '', provider = 'claude') {
  const res = await fetch(`${BASE}/elements`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ topic, hint, provider }),
  })
  return res.json()
}

export async function chatElement(id, messages, provider = 'claude') {
  const res = await fetch(`${BASE}/elements/${id}/chat`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ messages, provider }),
  })
  return res.json()
}

export async function deleteElement(id) {
  await fetch(`${BASE}/elements/${id}`, { method: 'DELETE' })
}

export async function updateElement(id, fields) {
  const res = await fetch(`${BASE}/elements/${id}`, {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(fields),
  })
  return res.json()
}

export async function styleElement(id, provider = 'claude') {
  const res = await fetch(`${BASE}/elements/${id}/style`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ provider }),
  })
  if (!res.ok) throw new Error(`Stil-Prüfung fehlgeschlagen (${res.status})`)
  return res.json()
}

export async function refineSuggestion(id, suggestion, instruction, provider = 'claude') {
  const res = await fetch(`${BASE}/elements/${id}/refine`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ suggestion, instruction, provider }),
  })
  if (!res.ok) throw new Error(`Überarbeitung fehlgeschlagen (${res.status})`)
  return res.json()
}

export async function checkElement(id, provider = 'claude') {
  const res = await fetch(`${BASE}/elements/${id}/check`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ provider }),
  })
  if (!res.ok) throw new Error(`Prüfung fehlgeschlagen (${res.status})`)
  return res.json()
}
