package com.doctate.watch.presentation

/** What the recording screen currently shows. */
sealed interface UiState {
    data object Idle : UiState
    data object RequestingPermission : UiState
    data class Recording(val elapsedSeconds: Int) : UiState
    data object Uploading : UiState
    data class Success(val caseId: String) : UiState
    data class Error(val message: String, val transient: Boolean) : UiState
}

/** Events that drive state transitions. Side effects live in the ViewModel. */
sealed interface RecordingEvent {
    data object OnRecordTap : RecordingEvent
    data object PermissionGranted : RecordingEvent
    data object PermissionDenied : RecordingEvent
    data class RecordingTick(val elapsedSeconds: Int) : RecordingEvent
    data object OnStopTap : RecordingEvent
    data object OnDiscardTap : RecordingEvent
    data object RecordingFinished : RecordingEvent
    data class UploadSucceeded(val caseId: String) : RecordingEvent
    data class UploadFailed(val message: String, val transient: Boolean) : RecordingEvent
    data object OnResetTap : RecordingEvent
}

/**
 * Pure state transition. Unknown (state, event) combinations are no-ops: e.g. a late
 * UploadSucceeded after the user already tapped reset stays Idle.
 */
internal fun reduce(state: UiState, event: RecordingEvent): UiState = when (state) {
    is UiState.Idle -> when (event) {
        RecordingEvent.OnRecordTap -> UiState.RequestingPermission
        else -> state
    }
    is UiState.RequestingPermission -> when (event) {
        RecordingEvent.PermissionGranted -> UiState.Recording(elapsedSeconds = 0)
        RecordingEvent.PermissionDenied ->
            UiState.Error(message = "Microphone permission denied", transient = false)
        else -> state
    }
    is UiState.Recording -> when (event) {
        is RecordingEvent.RecordingTick -> UiState.Recording(elapsedSeconds = event.elapsedSeconds)
        RecordingEvent.OnStopTap -> UiState.Uploading
        RecordingEvent.OnDiscardTap -> UiState.Idle
        RecordingEvent.RecordingFinished -> UiState.Uploading
        is RecordingEvent.UploadFailed -> UiState.Error(event.message, event.transient)
        else -> state
    }
    is UiState.Uploading -> when (event) {
        is RecordingEvent.UploadSucceeded -> UiState.Success(caseId = event.caseId)
        is RecordingEvent.UploadFailed -> UiState.Error(event.message, event.transient)
        else -> state
    }
    is UiState.Success, is UiState.Error -> when (event) {
        RecordingEvent.OnResetTap -> UiState.Idle
        else -> state
    }
}
