package com.example.medilightv2android import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.BackHandler import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.compose.animation.Crossfade import androidx.compose.animation.core.tween import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import app.rive.runtime.kotlin.core.Rive import com.example.medilightv2android.services.KeychainService import com.example.medilightv2android.services.NotificationService import com.example.medilightv2android.ui.theme.Medilightv2androidTheme import com.example.medilightv2android.ui.views.calibration.CalibrationView import com.example.medilightv2android.ui.views.connection.DeviceScanView import com.example.medilightv2android.ui.views.history.MeasurementHistoryView import com.example.medilightv2android.ui.views.home.HomeView import com.example.medilightv2android.ui.views.monitoring.PlacementGuideView import com.example.medilightv2android.ui.views.monitoring.PiezoMonitoringView import com.example.medilightv2android.ui.views.monitoring.VivamyoMonitoringView import com.example.medilightv2android.ui.views.monitoring.UrineCameraScreen import com.example.medilightv2android.ui.views.monitoring.VoidingDiaryView import com.example.medilightv2android.ui.views.onboarding.OnboardingView import com.example.medilightv2android.ui.views.personalization.PiezoPersonalizationView import com.example.medilightv2android.ui.views.pin.PinMode import com.example.medilightv2android.ui.views.pin.PinView import com.example.medilightv2android.ui.views.registration.RegistrationView import com.example.medilightv2android.ui.views.consent.ConsentView import com.example.medilightv2android.ui.views.reminder.ReminderSettingsView import com.example.medilightv2android.ui.views.sensorselect.SensorSelectView import com.example.medilightv2android.ui.views.clinical.ClinicalHomeView import com.example.medilightv2android.ui.views.clinical.ClinicalLiveView class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Initialize services Rive.init(this) KeychainService.init(this) NotificationService.getInstance(this) enableEdgeToEdge() window.addFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) setContent { Medilightv2androidTheme { Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding -> MedilightApp(modifier = Modifier.padding(innerPadding)) } } } } } @Composable fun MedilightApp(modifier: Modifier = Modifier) { val context = LocalContext.current val appState = remember { AppState(context) } // HOME에서 뒤로가기 → 앱 종료 확인 var showExitDialog by remember { mutableStateOf(false) } BackHandler(enabled = appState.currentScreen == AppScreen.HOME) { showExitDialog = true } if (showExitDialog) { androidx.compose.material3.AlertDialog( onDismissRequest = { showExitDialog = false }, title = { androidx.compose.material3.Text("Exit App") }, text = { androidx.compose.material3.Text("Are you sure you want to exit?") }, confirmButton = { androidx.compose.material3.TextButton(onClick = { (context as? android.app.Activity)?.finish() }) { androidx.compose.material3.Text("Exit", color = Color.Red) } }, dismissButton = { androidx.compose.material3.TextButton(onClick = { showExitDialog = false }) { androidx.compose.material3.Text("Cancel") } } ) } // 다른 화면에서 뒤로가기 = 바로 전 화면 BackHandler(enabled = appState.currentScreen != AppScreen.HOME && appState.currentScreen != AppScreen.PIN_ENTRY) { when (appState.currentScreen) { // 메인 플로우: Home → DeviceScan → Personalization → Placement → Monitoring // DeviceScan Back: 임상 흐름이면 ClinicalHome으로, 아니면 HOME AppScreen.DEVICE_SCAN -> appState.currentScreen = if (com.example.medilightv2android.services.ClinicalSessionStore.inClinicalFlow) AppScreen.CLINICAL_HOME else AppScreen.HOME AppScreen.PIEZO_PERSONALIZATION -> appState.currentScreen = AppScreen.DEVICE_SCAN // 임상 모드 측정 중이면 endMeasurement → ClinicalHome 복귀 AppScreen.PLACEMENT_GUIDE -> if (com.example.medilightv2android.services.ClinicalSessionStore.currentSession != null) { com.example.medilightv2android.services.ClinicalSessionStore.endMeasurement(context) appState.currentScreen = AppScreen.CLINICAL_HOME } else appState.backFromPlacementGuide() AppScreen.PIEZO_MONITORING -> if (com.example.medilightv2android.services.ClinicalSessionStore.currentSession != null) { com.example.medilightv2android.services.ClinicalSessionStore.endMeasurement(context) appState.currentScreen = AppScreen.CLINICAL_HOME } else appState.currentScreen = AppScreen.PLACEMENT_GUIDE AppScreen.CLINICAL_HOME -> { com.example.medilightv2android.services.ClinicalSessionStore.inClinicalFlow = false appState.currentScreen = AppScreen.HOME } AppScreen.CLINICAL_LIVE -> { // 측정 폴더 finalize 후 ClinicalHome 복귀 com.example.medilightv2android.services.ClinicalSessionStore.endMeasurement(context) appState.currentScreen = AppScreen.CLINICAL_HOME } // 모니터링 하위 화면 → 모니터링 AppScreen.MEASUREMENT_HISTORY -> appState.currentScreen = AppScreen.PIEZO_MONITORING AppScreen.VOIDING_DIARY -> appState.currentScreen = AppScreen.PIEZO_MONITORING AppScreen.REMINDER_SETTINGS -> appState.currentScreen = AppScreen.PIEZO_MONITORING AppScreen.URINE_CAMERA -> appState.currentScreen = AppScreen.PIEZO_MONITORING // 기타 AppScreen.SENSOR_SELECT -> appState.currentScreen = AppScreen.HOME AppScreen.VIVAMYO_MONITORING -> appState.currentScreen = AppScreen.HOME AppScreen.NIRS_CALIBRATION -> appState.currentScreen = AppScreen.DEVICE_SCAN // 온보딩/등록 (뒤로가기 막지 않되 Home으로) else -> appState.currentScreen = AppScreen.HOME } } Crossfade( targetState = appState.currentScreen, animationSpec = tween(300), modifier = modifier, label = "screen" ) { screen -> when (screen) { AppScreen.ONBOARDING -> OnboardingView(appState) AppScreen.CONSENT -> ConsentView(appState) AppScreen.REGISTRATION -> RegistrationView(appState) AppScreen.HOME -> HomeView(appState) AppScreen.SENSOR_SELECT -> SensorSelectView(appState) AppScreen.DEVICE_SCAN -> DeviceScanView(appState) AppScreen.NIRS_CALIBRATION -> CalibrationView(appState) AppScreen.PIEZO_PERSONALIZATION -> PiezoPersonalizationView(appState) AppScreen.PLACEMENT_GUIDE -> PlacementGuideView(appState) AppScreen.PIN_SETUP -> PinView(appState, PinMode.SETUP, context) AppScreen.PIN_ENTRY -> PinView(appState, PinMode.ENTER, context) AppScreen.VIVAMYO_MONITORING -> VivamyoMonitoringView(appState) AppScreen.PIEZO_MONITORING -> PiezoMonitoringView(appState) AppScreen.MEASUREMENT_HISTORY -> MeasurementHistoryView(appState) AppScreen.VOIDING_DIARY -> VoidingDiaryView(onBack = { appState.currentScreen = AppScreen.HOME }) AppScreen.URINE_CAMERA -> UrineCameraScreen( onDone = { volume -> if (volume != null && volume > 0) appState.resetLevel() appState.currentScreen = AppScreen.PIEZO_MONITORING }, onCancel = { appState.currentScreen = AppScreen.PIEZO_MONITORING } ) AppScreen.REMINDER_SETTINGS -> ReminderSettingsView( onBack = { appState.backToMonitoring() } ) AppScreen.CLINICAL_HOME -> ClinicalHomeView(appState) AppScreen.CLINICAL_LIVE -> ClinicalLiveView(appState) } } }