import type { Item, CreateItemBody, UpdateItemBody, StatsResponse, ItemFile } from './types'; const BASE = '/api'; async function request(path: string, init?: RequestInit): Promise { const res = await fetch(`${BASE}${path}`, { headers: { 'Content-Type': 'application/json' }, ...init, }); if (!res.ok) { const body = await res.json().catch(() => ({})); throw new Error(body.error || `Request failed: ${res.status}`); } if (res.status === 204) return undefined as T; return res.json(); } export const api = { // Items listItems(params?: Record): Promise { const qs = params ? '?' + new URLSearchParams(params).toString() : ''; return request(`/items${qs}`); }, getItem(id: string): Promise { return request(`/items/${id}`); }, createItem(body: CreateItemBody): Promise { return request('/items', { method: 'POST', body: JSON.stringify(body) }); }, updateItem(id: string, body: UpdateItemBody): Promise { return request(`/items/${id}`, { method: 'PUT', body: JSON.stringify(body) }); }, deleteItem(id: string): Promise { return request(`/items/${id}`, { method: 'DELETE' }); }, restoreItem(id: string): Promise { return request(`/items/${id}/restore`, { method: 'POST' }); }, permanentDeleteItem(id: string): Promise { return request(`/items/${id}/permanent`, { method: 'DELETE' }); }, duplicateItem(id: string): Promise { return request(`/items/${id}/duplicate`, { method: 'POST' }); }, bulkUpdateItems(ids: string[], updates: { category?: string; location?: string; status?: string; flagged?: number }): Promise<{ updated: number }> { return request('/items/bulk', { method: 'PATCH', body: JSON.stringify({ ids, updates }) }); }, // Suggestions getCategories(): Promise { return request('/suggestions/categories'); }, getLocations(): Promise { return request('/suggestions/locations'); }, // Files async uploadFiles(itemId: string, files: File[], type: 'photo' | 'receipt'): Promise { const form = new FormData(); form.append('type', type); for (const f of files) form.append('files', f); const res = await fetch(`${BASE}/items/${itemId}/files`, { method: 'POST', body: form }); if (!res.ok) throw new Error('Upload failed'); return res.json(); }, deleteFile(fileId: string): Promise { return request(`/files/${fileId}`, { method: 'DELETE' }); }, setFeaturedPhoto(itemId: string, fileId: string): Promise { return request(`/items/${itemId}/files/${fileId}/featured`, { method: 'PUT' }); }, // Stats getStats(): Promise { return request('/stats'); }, }; // Image variant URL helpers function variantUrl(storedName: string, suffix: string): string { const dot = storedName.lastIndexOf('.'); return `/api/uploads/${storedName.slice(0, dot)}${suffix}${storedName.slice(dot)}`; } export function thumbUrl(storedName: string): string { return variantUrl(storedName, '_thumb'); } export function largeUrl(storedName: string): string { return variantUrl(storedName, '_large'); } export function uploadUrl(storedName: string): string { return `/api/uploads/${storedName}`; }