import * as SecureStore from 'expo-secure-store'; import type { AuthResponse, ChatResponse, Patient, ApiResponse, ApiError } from '@/types'; const API_BASE_URL = 'https://eluxnetworks.net/function/well-api/api'; const CLIENT_ID = 'MA_001'; class ApiService { private async getToken(): Promise { try { return await SecureStore.getItemAsync('accessToken'); } catch { return null; } } private async getUserName(): Promise { try { return await SecureStore.getItemAsync('userName'); } catch { return null; } } private generateNonce(): string { return Math.floor(Math.random() * 1000000).toString(); } private async makeRequest(params: Record): Promise> { try { const formData = new URLSearchParams(); Object.entries(params).forEach(([key, value]) => { formData.append(key, value); }); const response = await fetch(API_BASE_URL, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: formData.toString(), }); const data = await response.json(); if (data.status === '200 OK' || data.ok === true) { return { data: data as T, ok: true }; } return { ok: false, error: { message: data.message || data.error || 'Request failed', status: response.status, }, }; } catch (error) { const apiError: ApiError = { message: error instanceof Error ? error.message : 'Network error', code: 'NETWORK_ERROR', }; return { ok: false, error: apiError }; } } // Authentication async login(username: string, password: string): Promise> { const response = await this.makeRequest({ function: 'credentials', user_name: username, ps: password, clientId: CLIENT_ID, nonce: this.generateNonce(), }); if (response.ok && response.data) { // Save credentials to SecureStore await SecureStore.setItemAsync('accessToken', response.data.access_token); await SecureStore.setItemAsync('userId', response.data.user_id.toString()); await SecureStore.setItemAsync('userName', username); await SecureStore.setItemAsync('privileges', response.data.privileges); await SecureStore.setItemAsync('maxRole', response.data.max_role.toString()); } return response; } async logout(): Promise { await SecureStore.deleteItemAsync('accessToken'); await SecureStore.deleteItemAsync('userId'); await SecureStore.deleteItemAsync('userName'); await SecureStore.deleteItemAsync('privileges'); await SecureStore.deleteItemAsync('maxRole'); } async isAuthenticated(): Promise { const token = await this.getToken(); return !!token; } // Get stored user info async getStoredUser() { try { const userId = await SecureStore.getItemAsync('userId'); const userName = await SecureStore.getItemAsync('userName'); const privileges = await SecureStore.getItemAsync('privileges'); const maxRole = await SecureStore.getItemAsync('maxRole'); if (!userId || !userName) return null; return { user_id: parseInt(userId, 10), user_name: userName, privileges: privileges || '', max_role: parseInt(maxRole || '0', 10), }; } catch { return null; } } // Patients async getPatients(): Promise> { const token = await this.getToken(); if (!token) { return { ok: false, error: { message: 'Not authenticated', code: 'UNAUTHORIZED' } }; } // Note: Using mock data since get_patients API structure is not fully documented // Replace with actual API call when available const mockPatients: Patient[] = [ { id: 1, name: 'Julia Smith', status: 'online', relationship: 'Mother', last_activity: '2 min ago', health_data: { heart_rate: 72, steps: 3450, sleep_hours: 7.5, }, }, { id: 2, name: 'Robert Johnson', status: 'offline', relationship: 'Father', last_activity: '1 hour ago', health_data: { heart_rate: 68, steps: 2100, sleep_hours: 6.8, }, }, ]; return { data: { patients: mockPatients }, ok: true }; } async getPatient(id: number): Promise> { const response = await this.getPatients(); if (!response.ok || !response.data) { return { ok: false, error: response.error }; } const patient = response.data.patients.find((p) => p.id === id); if (!patient) { return { ok: false, error: { message: 'Patient not found', code: 'NOT_FOUND' } }; } return { data: patient, ok: true }; } // AI Chat async sendMessage(question: string, deploymentId: string = '21'): Promise> { const token = await this.getToken(); const userName = await this.getUserName(); if (!token || !userName) { return { ok: false, error: { message: 'Not authenticated', code: 'UNAUTHORIZED' } }; } return this.makeRequest({ function: 'voice_ask', clientId: CLIENT_ID, user_name: userName, token: token, question: question, deployment_id: deploymentId, }); } } export const api = new ApiService();