const API_BASE = import.meta.env.VITE_API_BASE || 'http://localhost:8000' async function handleResponse(response) { if (!response.ok) { let detail = 'Erro inesperado' try { const data = await response.json() detail = data.detail || detail } catch { detail = response.statusText || detail } throw new Error(detail) } return response } async function postJson(path, body) { const response = await fetch(`${API_BASE}${path}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body), }) await handleResponse(response) return response.json() } async function postForm(path, formData) { const response = await fetch(`${API_BASE}${path}`, { method: 'POST', body: formData, }) await handleResponse(response) return response.json() } async function getJson(path) { const response = await fetch(`${API_BASE}${path}`) await handleResponse(response) return response.json() } async function getBlob(path) { const response = await fetch(`${API_BASE}${path}`) await handleResponse(response) return response.blob() } export function downloadBlob(blob, fileName) { const url = URL.createObjectURL(blob) const a = document.createElement('a') a.href = url a.download = fileName document.body.appendChild(a) a.click() a.remove() URL.revokeObjectURL(url) } export const api = { createSession: () => postJson('/api/sessions', {}), uploadElaboracaoFile(sessionId, file) { const form = new FormData() form.append('session_id', sessionId) form.append('file', file) return postForm('/api/elaboracao/upload', form) }, confirmSheet: (sessionId, sheetName) => postJson('/api/elaboracao/confirm-sheet', { session_id: sessionId, sheet_name: sheetName }), mapCoords: (sessionId, colLat, colLon) => postJson('/api/elaboracao/map-coords', { session_id: sessionId, col_lat: colLat, col_lon: colLon }), geocodificar: (sessionId, colCdlog, colNum, auto200) => postJson('/api/elaboracao/geocodificar', { session_id: sessionId, col_cdlog: colCdlog, col_num: colNum, auto_200: auto200 }), geocodificarCorrecoes: (sessionId, correcoes, auto200) => postJson('/api/elaboracao/geocodificar-correcoes', { session_id: sessionId, correcoes, auto_200: auto200 }), applySelection(payload) { return postJson('/api/elaboracao/apply-selection', payload) }, classifyElaboracaoX: (sessionId, colunasX) => postJson('/api/elaboracao/classify-x', { session_id: sessionId, colunas_x: colunasX }), searchTransformations: (sessionId, grauCoef, grauF) => postJson('/api/elaboracao/search-transformations', { session_id: sessionId, grau_min_coef: grauCoef, grau_min_f: grauF, }), adoptSuggestion: (sessionId, indice) => postJson('/api/elaboracao/adopt-suggestion', { session_id: sessionId, indice }), fitModel(payload) { return postJson('/api/elaboracao/fit-model', payload) }, updateModelDispersao: (sessionId, tipo) => postJson('/api/elaboracao/model-dispersao', { session_id: sessionId, tipo }), applyOutlierFilters: (sessionId, filtros) => postJson('/api/elaboracao/outliers/apply-filters', { session_id: sessionId, filtros }), restartOutlierIteration: (sessionId, outliersTexto, reincluirTexto, grauCoef, grauF) => postJson('/api/elaboracao/outliers/restart', { session_id: sessionId, outliers_texto: outliersTexto, reincluir_texto: reincluirTexto, grau_min_coef: grauCoef, grau_min_f: grauF, }), outlierSummary: (sessionId, outliersTexto, reincluirTexto) => postJson('/api/elaboracao/outliers/summary', { session_id: sessionId, outliers_texto: outliersTexto, reincluir_texto: reincluirTexto, }), clearOutlierHistory: (sessionId) => postJson('/api/elaboracao/outliers/clear-history', { session_id: sessionId }), evaluationFieldsElab: (sessionId) => postJson('/api/elaboracao/evaluation/fields', { session_id: sessionId }), evaluationCalculateElab: (sessionId, valoresX, indiceBase) => postJson('/api/elaboracao/evaluation/calculate', { session_id: sessionId, valores_x: valoresX, indice_base: indiceBase, }), evaluationClearElab: (sessionId) => postJson('/api/elaboracao/evaluation/clear', { session_id: sessionId }), evaluationDeleteElab: (sessionId, indice, indiceBase) => postJson('/api/elaboracao/evaluation/delete', { session_id: sessionId, indice, indice_base: indiceBase, }), getAvaliadores: () => getJson('/api/elaboracao/avaliadores'), evaluationBaseElab: (sessionId, indiceBase) => postJson('/api/elaboracao/evaluation/base', { session_id: sessionId, indice_base: indiceBase, }), exportEvaluationElab: async (sessionId) => getBlob(`/api/elaboracao/evaluation/export?session_id=${encodeURIComponent(sessionId)}`), exportModel: async (sessionId, nomeArquivo, elaborador) => { const response = await fetch(`${API_BASE}/api/elaboracao/export-model`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ session_id: sessionId, nome_arquivo: nomeArquivo, elaborador }), }) await handleResponse(response) return response.blob() }, exportBase: (sessionId, filtered = true) => getBlob(`/api/elaboracao/export-base?session_id=${encodeURIComponent(sessionId)}&filtered=${String(filtered)}`), updateElaboracaoMap: (sessionId, variavelMapa) => postJson('/api/elaboracao/map/update', { session_id: sessionId, variavel_mapa: variavelMapa }), getContext: (sessionId) => getJson(`/api/elaboracao/context?session_id=${encodeURIComponent(sessionId)}`), uploadVisualizacaoFile(sessionId, file) { const form = new FormData() form.append('session_id', sessionId) form.append('file', file) return postForm('/api/visualizacao/upload', form) }, exibirVisualizacao: (sessionId) => postJson('/api/visualizacao/exibir', { session_id: sessionId }), updateVisualizacaoMap: (sessionId, variavelMapa) => postJson('/api/visualizacao/map/update', { session_id: sessionId, variavel_mapa: variavelMapa }), evaluationFieldsViz: (sessionId) => postJson('/api/visualizacao/evaluation/fields', { session_id: sessionId }), evaluationCalculateViz: (sessionId, valoresX, indiceBase) => postJson('/api/visualizacao/evaluation/calculate', { session_id: sessionId, valores_x: valoresX, indice_base: indiceBase, }), evaluationClearViz: (sessionId) => postJson('/api/visualizacao/evaluation/clear', { session_id: sessionId }), evaluationDeleteViz: (sessionId, indice, indiceBase) => postJson('/api/visualizacao/evaluation/delete', { session_id: sessionId, indice, indice_base: indiceBase, }), evaluationBaseViz: (sessionId, indiceBase) => postJson('/api/visualizacao/evaluation/base', { session_id: sessionId, indice_base: indiceBase, }), exportEvaluationViz: (sessionId) => getBlob(`/api/visualizacao/evaluation/export?session_id=${encodeURIComponent(sessionId)}`), clearVisualizacao: (sessionId) => postJson('/api/visualizacao/clear', { session_id: sessionId }), }