import { defineStore } from 'pinia' import { ref } from 'vue' import { api } from '@/services/request' import { getTodaySummary, getTrend } from '@/services/health' interface CachedTrend { data: { date: string; value: number }[] cachedAt: number } interface TodaySummary { blood_pressure?: { systolic: number; diastolic: number; status: string; reference_range?: string } heart_rate?: { value: number; status: string; reference_range?: string } blood_sugar?: { value: number; status: string; reference_range?: string } weight?: { value: number; status: string; reference_range?: string } } interface HealthThreshold { id: string indicator: string direction: string threshold_value: number level: string is_active: boolean } export const DEFAULT_THRESHOLDS: HealthThreshold[] = [ { id: '_bp_sys_high', indicator: 'systolic_bp', direction: 'high', threshold_value: 140, level: 'warning', is_active: true }, { id: '_bp_dia_high', indicator: 'diastolic_bp', direction: 'high', threshold_value: 90, level: 'warning', is_active: true }, { id: '_hr_high', indicator: 'heart_rate', direction: 'high', threshold_value: 100, level: 'warning', is_active: true }, { id: '_hr_low', indicator: 'heart_rate', direction: 'low', threshold_value: 60, level: 'warning', is_active: true }, { id: '_bs_fasting_high', indicator: 'blood_sugar_fasting', direction: 'high', threshold_value: 6.1, level: 'warning', is_active: true }, { id: '_bs_pp_high', indicator: 'blood_sugar_postprandial', direction: 'high', threshold_value: 7.8, level: 'warning', is_active: true }, ] const CACHE_TTL = 5 * 60 * 1000 const TODAY_SUMMARY_TTL = 60_000 const THRESHOLD_CACHE_KEY = 'health_thresholds' const THRESHOLD_TTL = 24 * 60 * 60 * 1000 export const useHealthStore = defineStore('health', () => { const vitals = ref([]) const todaySummary = ref(null) const todaySummaryFetchedAt = ref(0) const trendData = ref>({}) const thresholds = ref(DEFAULT_THRESHOLDS) const loading = ref(false) async function fetchVitals() { loading.value = true try { const summary = await getTodaySummary() vitals.value = summary ? [summary] : [] } catch { /* ignore */ } loading.value = false } async function refreshToday(force = false) { if (!force && todaySummary.value && Date.now() - todaySummaryFetchedAt.value < TODAY_SUMMARY_TTL) return loading.value = true try { const patientId = uni.getStorageSync('current_patient_id') || undefined const params: Record = {} if (patientId) params.patient_id = patientId todaySummary.value = await api.get('/health/vital-signs/today', params) todaySummaryFetchedAt.value = Date.now() } catch { /* ignore */ } loading.value = false } async function getTrend(indicator: string, range: string): Promise<{ date: string; value: number }[]> { const cacheKey = `${indicator}_${range}` const cached = trendData.value[cacheKey] if (cached && Date.now() - cached.cachedAt < CACHE_TTL) return cached.data try { const resp = await api.get<{ data_points: { date: string; value: number }[] }>( '/health/vital-signs/trend', { indicator, range }, ) const points = resp.data_points || [] trendData.value = { ...trendData.value, [cacheKey]: { data: points, cachedAt: Date.now() } } return points } catch { return [] } } async function fetchThresholds() { try { const cached = uni.getStorageSync(THRESHOLD_CACHE_KEY) as { data: HealthThreshold[]; ts: number } | undefined if (cached && Date.now() - cached.ts < THRESHOLD_TTL) { thresholds.value = cached.data return } } catch { /* cache miss */ } try { const data = await api.get('/health/critical-value-thresholds/public') uni.setStorageSync(THRESHOLD_CACHE_KEY, { data, ts: Date.now() }) thresholds.value = data } catch { /* keep defaults */ } } function clearCache() { trendData.value = {} todaySummary.value = null todaySummaryFetchedAt.value = 0 } return { vitals, todaySummary, trendData, thresholds, loading, fetchVitals, refreshToday, getTrend, fetchThresholds, clearCache, } })