package com.example.medilightv2android import android.content.Context import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import com.example.medilightv2android.ble.BleManager import com.example.medilightv2android.managers.NirsManager import com.example.medilightv2android.models.* import com.example.medilightv2android.services.* enum class AppScreen { ONBOARDING, CONSENT, REGISTRATION, HOME, SENSOR_SELECT, DEVICE_SCAN, NIRS_CALIBRATION, PIEZO_PERSONALIZATION, PLACEMENT_GUIDE, PIN_SETUP, PIN_ENTRY, VIVAMYO_MONITORING, PIEZO_MONITORING, MEASUREMENT_HISTORY, VOIDING_DIARY, URINE_CAMERA, REMINDER_SETTINGS } class AppState(private val context: Context) { var currentScreen by mutableStateOf(AppScreen.ONBOARDING) var user by mutableStateOf(User()) var sensorMode by mutableStateOf(SensorMode.PIEZO) var bladderLevel by mutableStateOf(BladderLevel()) var isDeviceConnected by mutableStateOf(false) var isDemoMode by mutableStateOf(false) var piezoSettings by mutableStateOf(PiezoSettings()) var catheterCount = mutableIntStateOf(0) private val storage = UserStorage.getInstance(context) private val historyStore = MeasurementHistoryStore.getInstance(context) private val notificationService = NotificationService.getInstance(context) private val bleManager = BleManager.getInstance(context) private val reminderService = ReminderService.getInstance(context) init { loadState() } fun loadState() { user = storage.user sensorMode = storage.sensorMode bladderLevel = bladderLevel.copy( currentLevel = storage.bladderLevel, catheterizationThreshold = storage.catheterizationLevel ) piezoSettings = storage.piezoSettings catheterCount.intValue = storage.catheterCount currentScreen = when { !storage.hasCompletedOnboarding -> AppScreen.ONBOARDING !storage.isRegistered -> AppScreen.REGISTRATION !storage.hasPin -> AppScreen.PIN_SETUP else -> AppScreen.PIN_ENTRY } } fun completeOnboarding() { storage.hasCompletedOnboarding = true storage.hasConsented = true currentScreen = AppScreen.REGISTRATION } fun completeConsent() { storage.hasConsented = true storage.consentTimestamp = System.currentTimeMillis() currentScreen = AppScreen.REGISTRATION } fun completeRegistration() { storage.user = user storage.isRegistered = true currentScreen = AppScreen.PIN_SETUP } fun goHome() { NirsManager.instance.stopStreaming() NirsManager.instance.reset() if (!isDemoMode) bleManager.disconnect() isDeviceConnected = false isDemoMode = false currentScreen = AppScreen.HOME } fun enterDemoMode() { isDemoMode = true isDeviceConnected = true currentScreen = if (sensorMode == SensorMode.NIRS) { AppScreen.VIVAMYO_MONITORING } else { AppScreen.PIEZO_MONITORING } } fun startFromHome() { sensorMode = SensorMode.PIEZO storage.sensorMode = SensorMode.PIEZO currentScreen = if (isDeviceConnected) AppScreen.PIEZO_MONITORING else AppScreen.DEVICE_SCAN } fun selectSensor(mode: SensorMode) { sensorMode = mode storage.sensorMode = mode currentScreen = AppScreen.DEVICE_SCAN } fun backToSensorSelect() { currentScreen = AppScreen.HOME } fun deviceConnected() { isDeviceConnected = true currentScreen = if (sensorMode == SensorMode.NIRS) { AppScreen.NIRS_CALIBRATION } else { AppScreen.PIEZO_PERSONALIZATION } } fun calibrationComplete() { currentScreen = AppScreen.VIVAMYO_MONITORING } fun personalizationComplete() { storage.piezoSettings = piezoSettings currentScreen = AppScreen.PLACEMENT_GUIDE } fun placementComplete() { bladderLevel = BladderLevel(currentLevel = 0, catheterizationThreshold = bladderLevel.catheterizationThreshold) storage.bladderLevel = 0 currentScreen = AppScreen.PIEZO_MONITORING } fun pinSet(pin: String) { storage.pin = pin storage.hasPin = true currentScreen = AppScreen.HOME } fun pinVerified() { currentScreen = AppScreen.HOME } fun incrementLevel() { val previousUrgency = bladderLevel.urgency val newLevel = bladderLevel.copy() newLevel.increment() bladderLevel = newLevel storage.bladderLevel = bladderLevel.currentLevel val record = MeasurementRecord( eventType = MeasurementEventType.MEASUREMENT, level = bladderLevel.currentLevel, estimatedVolume = estimatedVolume, urgencyLevel = bladderLevel.urgency, fillPercentage = fillPercentage ) historyStore.addRecord(record) val newUrgency = bladderLevel.urgency if (newUrgency != previousUrgency) { notificationService.sendUrgencyNotification(newUrgency, estimatedVolume) } } fun resetLevel() { val record = MeasurementRecord( eventType = MeasurementEventType.CATHETERIZATION, level = bladderLevel.currentLevel, estimatedVolume = estimatedVolume, urgencyLevel = bladderLevel.urgency, fillPercentage = fillPercentage ) historyStore.addRecord(record) val newLevel = bladderLevel.copy() newLevel.reset() bladderLevel = newLevel storage.bladderLevel = 0 notificationService.cancelAll() reminderService.reschedule() if (catheterCount.intValue > 0) { catheterCount.intValue-- storage.catheterCount = catheterCount.intValue } } fun showHistory() { currentScreen = AppScreen.MEASUREMENT_HISTORY } fun backToMonitoring() { currentScreen = if (sensorMode == SensorMode.NIRS) AppScreen.VIVAMYO_MONITORING else AppScreen.PIEZO_MONITORING } fun addCatheterCount(amount: Int = 1) { catheterCount.intValue += amount storage.catheterCount = catheterCount.intValue } fun updateCatheterizationThreshold(threshold: Int) { bladderLevel = bladderLevel.copy(catheterizationThreshold = threshold) storage.catheterizationLevel = threshold } val estimatedVolume: Int get() { if (BladderLevel.MAX_LEVEL <= 0) return 0 return (bladderLevel.currentLevel.toDouble() / BladderLevel.MAX_LEVEL * piezoSettings.maxVolume).toInt() } val fillPercentage: Double get() { if (BladderLevel.MAX_LEVEL <= 0) return 0.0 return bladderLevel.currentLevel.toDouble() / BladderLevel.MAX_LEVEL * 100.0 } }