import { getToken } from '../context/AuthContext' let _profileId = null export function setProfileId(id) { _profileId = id } const BASE = '/api' function hdrs(extra={}) { const h = {...extra} if (_profileId) h['X-Profile-Id'] = _profileId const token = getToken() if (token) h['X-Auth-Token'] = token return h } async function req(path, opts={}) { const res = await fetch(BASE+path, {...opts, headers:hdrs(opts.headers||{})}) if (!res.ok) { const err=await res.text(); throw new Error(err) } return res.json() } const json=(d)=>({method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(d)}) const jput=(d)=>({method:'PUT', headers:{'Content-Type':'application/json'},body:JSON.stringify(d)}) export const api = { // Profiles getActiveProfile: () => req('/profile'), listProfiles: () => req('/profiles'), createProfile: (d) => req('/profiles', json(d)), updateProfile: (id,d) => req(`/profiles/${id}`, jput(d)), deleteProfile: (id) => req(`/profiles/${id}`, {method:'DELETE'}), getProfile: () => req('/profile'), updateActiveProfile:(d)=> req('/profile', jput(d)), // Weight listWeight: (l=365) => req(`/weight?limit=${l}`), upsertWeight: (date,weight,note='') => req('/weight',json({date,weight,note})), updateWeight: (id,date,weight,note='') => req(`/weight/${id}`,jput({date,weight,note})), deleteWeight: (id) => req(`/weight/${id}`,{method:'DELETE'}), weightStats: () => req('/weight/stats'), // Circumferences listCirc: (l=100) => req(`/circumferences?limit=${l}`), upsertCirc: (d) => req('/circumferences',json(d)), updateCirc: (id,d) => req(`/circumferences/${id}`,jput(d)), deleteCirc: (id) => req(`/circumferences/${id}`,{method:'DELETE'}), // Caliper listCaliper: (l=100) => req(`/caliper?limit=${l}`), upsertCaliper: (d) => req('/caliper',json(d)), updateCaliper: (id,d) => req(`/caliper/${id}`,jput(d)), deleteCaliper: (id) => req(`/caliper/${id}`,{method:'DELETE'}), // Activity listActivity: (l=200)=> req(`/activity?limit=${l}`), createActivity: (d) => req('/activity',json(d)), updateActivity: (id,d) => req(`/activity/${id}`,jput(d)), deleteActivity: (id) => req(`/activity/${id}`,{method:'DELETE'}), activityStats: () => req('/activity/stats'), importActivityCsv: async(file)=>{ const fd=new FormData();fd.append('file',file) const r=await fetch(`${BASE}/activity/import-csv`,{method:'POST',body:fd,headers:hdrs()}) const d=await r.json();if(!r.ok)throw new Error(d.detail||JSON.stringify(d));return d }, // Photos uploadPhoto: (file,date='')=>{ const fd=new FormData();fd.append('file',file);fd.append('date',date) return fetch(`${BASE}/photos`,{method:'POST',body:fd,headers:hdrs()}).then(r=>r.json()) }, listPhotos: () => req('/photos'), photoUrl: (pid) => { const token = getToken() return `${BASE}/photos/${pid}${token ? `?token=${token}` : ''}` }, // Nutrition importCsv: async(file)=>{ const fd=new FormData();fd.append('file',file) const r=await fetch(`${BASE}/nutrition/import-csv`,{method:'POST',body:fd,headers:hdrs()}) const d=await r.json();if(!r.ok)throw new Error(d.detail||JSON.stringify(d));return d }, listNutrition: (l=365) => req(`/nutrition?limit=${l}`), nutritionCorrelations: () => req('/nutrition/correlations'), nutritionWeekly: (w=16) => req(`/nutrition/weekly?weeks=${w}`), // Stats & AI getStats: () => req('/stats'), insightTrend: () => req('/insights/trend',{method:'POST'}), listPrompts: () => req('/prompts'), runInsight: (slug) => req(`/insights/run/${slug}`,{method:'POST'}), insightPipeline: () => req('/insights/pipeline',{method:'POST'}), listInsights: () => req('/insights'), latestInsights: () => req('/insights/latest'), exportZip: async () => { const res = await fetch(`${BASE}/export/zip`, {headers: hdrs()}) if (!res.ok) throw new Error('Export failed') const blob = await res.blob() const url = window.URL.createObjectURL(blob) const a = document.createElement('a') a.href = url a.download = `mitai-export-${new Date().toISOString().split('T')[0]}.zip` document.body.appendChild(a) a.click() document.body.removeChild(a) window.URL.revokeObjectURL(url) }, exportJson: async () => { const res = await fetch(`${BASE}/export/json`, {headers: hdrs()}) if (!res.ok) throw new Error('Export failed') const blob = await res.blob() const url = window.URL.createObjectURL(blob) const a = document.createElement('a') a.href = url a.download = `mitai-export-${new Date().toISOString().split('T')[0]}.json` document.body.appendChild(a) a.click() document.body.removeChild(a) window.URL.revokeObjectURL(url) }, exportCsv: async () => { const res = await fetch(`${BASE}/export/csv`, {headers: hdrs()}) if (!res.ok) throw new Error('Export failed') const blob = await res.blob() const url = window.URL.createObjectURL(blob) const a = document.createElement('a') a.href = url a.download = `mitai-export-${new Date().toISOString().split('T')[0]}.csv` document.body.appendChild(a) a.click() document.body.removeChild(a) window.URL.revokeObjectURL(url) }, // Admin adminListProfiles: () => req('/admin/profiles'), adminCreateProfile: (d) => req('/admin/profiles',json(d)), adminDeleteProfile: (id) => req(`/admin/profiles/${id}`,{method:'DELETE'}), adminSetPermissions: (id,d) => req(`/admin/profiles/${id}/permissions`,jput(d)), changePin: (pin) => req('/auth/pin',json({pin})), // v9c Subscription System // User-facing getMySubscription: () => req('/subscription/me'), getMyUsage: () => req('/subscription/usage'), getMyLimits: () => req('/subscription/limits'), redeemCoupon: (code) => req('/coupons/redeem',json({code})), // Admin: Features listFeatures: () => req('/features'), createFeature: (d) => req('/features',json(d)), updateFeature: (id,d) => req(`/features/${id}`,jput(d)), deleteFeature: (id) => req(`/features/${id}`,{method:'DELETE'}), // Admin: Tiers listTiers: () => req('/tiers'), createTier: (d) => req('/tiers',json(d)), updateTier: (id,d) => req(`/tiers/${id}`,jput(d)), deleteTier: (id) => req(`/tiers/${id}`,{method:'DELETE'}), // Admin: Tier Limits (Matrix) getTierLimitsMatrix: () => req('/tier-limits'), updateTierLimit: (d) => req('/tier-limits',jput(d)), updateTierLimitsBatch:(updates) => req('/tier-limits/batch',jput({updates})), // Admin: User Restrictions listUserRestrictions: (pid) => req(`/user-restrictions${pid?'?profile_id='+pid:''}`), createUserRestriction:(d) => req('/user-restrictions',json(d)), updateUserRestriction:(id,d) => req(`/user-restrictions/${id}`,jput(d)), deleteUserRestriction:(id) => req(`/user-restrictions/${id}`,{method:'DELETE'}), // Admin: Coupons listCoupons: () => req('/coupons'), createCoupon: (d) => req('/coupons',json(d)), updateCoupon: (id,d) => req(`/coupons/${id}`,jput(d)), deleteCoupon: (id) => req(`/coupons/${id}`,{method:'DELETE'}), getCouponRedemptions: (id) => req(`/coupons/${id}/redemptions`), // Admin: Access Grants listAccessGrants: (pid,active)=> req(`/access-grants${pid?'?profile_id='+pid:''}${active?'&active_only=true':''}`), createAccessGrant: (d) => req('/access-grants',json(d)), updateAccessGrant: (id,d) => req(`/access-grants/${id}`,jput(d)), revokeAccessGrant: (id) => req(`/access-grants/${id}`,{method:'DELETE'}), }