const BASE = '/api'

function qs(query) {
  if (!query) return ''
  const p = new URLSearchParams()
  for (const [k, v] of Object.entries(query)) {
    if (v !== undefined && v !== null) p.set(k, v)
  }
  const s = p.toString()
  return s ? `?${s}` : ''
}

// Ein Request-Weg für ALLE Aufrufe: Backend-Fehler (400/409/500) werfen statt sie zu
// verschlucken, mit err.status für Aufrufer, die 404 ("noch nichts da") gesondert behandeln.
async function req(path, { method = 'GET', body, query } = {}) {
  const opts = { method }
  if (body !== undefined) {
    opts.headers = { 'Content-Type': 'application/json' }
    opts.body = JSON.stringify(body)
  }
  const res = await fetch(`${BASE}${path}${qs(query)}`, opts)
  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 */ }
    const err = new Error(detail)
    err.status = res.status
    throw err
  }
  const text = await res.text()  // DELETE/manche POSTs liefern keinen Body
  return text ? JSON.parse(text) : null
}

export const fetchGuides = () => req('/guides')

export const createGuide = (topic, format, instructions = '', provider = 'claude') =>
  req('/guides', { method: 'POST', body: { topic, format, instructions, provider } })

export const fetchActiveBlocks = () => req('/blocks/active')

export const fetchBlocksStatus = (topic) => req('/blocks/status', { query: { topic } })

export const createBlocks = (topic, instructions = '', provider = 'claude', sourceType = 'thema', sourceOrt = '', research = true, qaForce = false, auto = {}) =>
  req('/blocks', { method: 'POST', body: {
    topic, instructions, provider, source_type: sourceType, source_location: sourceOrt, research, qa_force: qaForce,
    auto_inventory: auto.inventory ?? true, auto_artefacts: auto.artefacts ?? true, auto_guide: auto.guide ?? true,
  } })

// Live-Kanban-Board der Blocks-Erzeugung (Spalten + Karten + Agenten + Dead-Letter).
export const fetchBlocksBoard = (topic) => req('/blocks/board', { query: { topic } })

// Manueller QA-Lauf (wie das Gate, inkl. LLM-Stichprobe); Badge liest den neuen Report.
export const runQa = (topic, llm = true) => req('/blocks/qa', { method: 'POST', body: { topic, llm } })

// QA-Befunde gezielt beheben; ebene = 'inventory' | 'artefacts' | undefined (alle).
export const runRepair = (topic, ebene = null) => req('/blocks/repair', { method: 'POST', body: { topic, ebene } })

// Artefakte-Ebene leeren (Board-2-Daten weg, Inventar bleibt).
export const removeArtefacts = (topic) => req('/blocks/artefacts', { method: 'DELETE', query: { topic } })

// Einen weiteren Research-Agenten anhängen (Attach-or-Start).
export const addBlocksResearch = (topic, provider = 'claude') =>
  req('/blocks/research', { method: 'POST', query: { topic, provider } })

export const removeGuideFormat = (topic, format) =>
  req('/guides/board/remove', { method: 'POST', body: { topic, format } })

export const requeueBlocksDead = (topic) =>
  req('/blocks/requeue-dead', { method: 'POST', query: { topic } })

// Live-Board der Guide-Erzeugung.
export const fetchGuideBoard = (topic, format = 'Guide') =>
  req('/guides/board', { query: { topic, format } })

// Befunde beheben: Karten mit QA-Befunden zurück auf Prüfen + Resume-Lauf.
export const repairGuideBoard = (topic, format) =>
  req('/guides/board/repair', { method: 'POST', body: { topic, format } })

export const cancelBlocks = (topic) => req('/blocks/cancel', { method: 'POST', query: { topic } })

export const deleteBlocks = (topic) => req('/blocks', { method: 'DELETE', query: { topic } })

// Lauf-Historie (Blocks + Guide): Zeitspanne, Agenten, Tokens, Fehler je run_id.
export const fetchRuns = (topic, limit = 10) => req('/runs', { query: { topic, limit } })

// --- Block-Learning: Chat, Exam ---

export const fetchBlockLearnState = (topic) => req('/blocks/learnstate', { query: { topic } })

export const chatBlock = ({ topic, block, section, section_compact = '', messages, provider }) =>
  req('/blocks/chat', { method: 'POST', body: { topic, block, section, section_compact, messages, provider } })

export const examBlock = ({
  topic, block, section, section_compact = '', provider,
  action = 'question', question = '', last_rating = '', avoid = [],
  asked_again = false, reason = '', pattern = '', cap = 6, messages = [], thorough = false,
  selection = [], correct = [], solution = '', alternatives = [], input = '', schwer = false,
}) => req('/blocks/exam', {
  method: 'POST',
  body: { topic, block, section, section_compact, action, question, last_rating, avoid, asked_again, reason, pattern, cap, messages, provider, thorough, selection, correct, solution, alternatives, input, schwer },
})

export const fetchQuestionPattern = (topic, block) =>
  req('/blocks/question-pattern', { query: { topic, block } })

export const fetchTopicProgress = (topic) => req('/topics/progress', { query: { topic } })

export const fetchStats = () => req('/stats')

export const fetchProviders = () => req('/providers')

export const fetchFolders = (kind) => req('/folders', { query: { kind } })

export const fetchSource = (topic) => req('/blocks/source', { query: { topic } })

export const updateSource = (topic, { type, ort = '', spec = '' }) =>
  req('/blocks/source', { method: 'PUT', body: { topic, type, location: ort, spec } })

export const fetchBlocksCompleteness = (topic) => req('/blocks/completeness', { query: { topic } })

export const fetchBlocksOverview = (topic) => req('/blocks/overview', { query: { topic } })

export const cancelGuide = (id) => req(`/guides/${id}/cancel`, { method: 'POST' })

export const deleteGuide = (id, slots = false) =>
  req(`/guides/${id}`, { method: 'DELETE', query: slots ? { slots: 1 } : undefined })

export const fetchGuideContent = (id, level = 4) => req(`/guides/${id}/content`, { query: { level } })

// Übungspool: fällige + neue Flashcards des Themas (Leitner, ein Stapel).
export const fetchPracticeDeck = (topic) => req('/practice/deck', { query: { topic } })

// Leitner-Schritt buchen (correct = „Gewusst").
export const answerPracticeCard = ({ topic, block_norm, sub_norm, correct }) =>
  req('/practice/answer', { method: 'POST', body: { topic, block_norm, sub_norm, correct } })

// Einen Markdown-Block on-demand gegen die Guide-Rules prüfen (Fokus, Rechtsklick).
export const pruefeBlock = (id, { block, spot, snippet, hint = '', provider }) =>
  req(`/guides/${id}/block/pruefen`, { method: 'POST', body: { block, spot, snippet, hint, provider } })

// Geprüften Block persistent übernehmen (alt → new im jeweiligen Feld).
export const uebernehmeBlock = (id, { block, spot, alt, revised, provider }) =>
  req(`/guides/${id}/block/uebernehmen`, { method: 'POST', body: { block, spot, alt, revised, provider } })

// Reset a block's learning progress to zero (score/streak/flags/open question).
export const resetBlockProgress = (topic, block) =>
  req('/blocks/progress', { method: 'DELETE', query: { topic, block } })

export const fetchTopics = () => req('/topics')

export const createTopic = (name) => req('/topics', { method: 'POST', body: { name } })

export const deleteTopic = (name) => req('/topics', { method: 'DELETE', query: { topic: name } })

export const chatGuide = (id, { section, outline, messages, provider = 'claude' }) =>
  req(`/guides/${id}/chat`, { method: 'POST', body: { section, outline, messages, provider } })
