package com.onthelevel.core.sensors

/**
 * Surface-only presentation state. Tilt magnitude remains authoritative from 0–180°;
 * Pitch and roll become ill-conditioned near vertical and are deliberately suppressed.
 */
enum class SurfacePresentation {
    FACE_UP,
    NEAR_VERTICAL,
    SCREEN_DOWN,
}

/**
 * Hysteretic presentation classifier driven by the same deadbanded stable magnitude
 * the UI displays. This prevents Pitch/Roll panels and placement copy from flapping
 * around the 80° and 90° boundaries due to sensor noise.
 */
class SurfacePresentationDetector {
    private var presentation = SurfacePresentation.FACE_UP

    fun update(displayedTiltDegrees: Double): SurfacePresentation {
        presentation = when (presentation) {
            SurfacePresentation.FACE_UP -> {
                if (displayedTiltDegrees > SCREEN_DOWN_ENTER_DEGREES) {
                    SurfacePresentation.SCREEN_DOWN
                } else if (displayedTiltDegrees >= AXIS_SUPPRESSION_ENTER_DEGREES) {
                    SurfacePresentation.NEAR_VERTICAL
                } else {
                    SurfacePresentation.FACE_UP
                }
            }
            SurfacePresentation.NEAR_VERTICAL -> when {
                displayedTiltDegrees > SCREEN_DOWN_ENTER_DEGREES -> SurfacePresentation.SCREEN_DOWN
                displayedTiltDegrees < AXIS_SUPPRESSION_EXIT_DEGREES -> SurfacePresentation.FACE_UP
                else -> SurfacePresentation.NEAR_VERTICAL
            }
            SurfacePresentation.SCREEN_DOWN -> {
                if (displayedTiltDegrees <= SCREEN_DOWN_EXIT_DEGREES) {
                    SurfacePresentation.NEAR_VERTICAL
                } else {
                    SurfacePresentation.SCREEN_DOWN
                }
            }
        }
        return presentation
    }

    fun reset() {
        presentation = SurfacePresentation.FACE_UP
    }

    companion object {
        const val AXIS_SUPPRESSION_ENTER_DEGREES = 80.0
        const val AXIS_SUPPRESSION_EXIT_DEGREES = 79.0
        const val SCREEN_DOWN_ENTER_DEGREES = 90.0
        const val SCREEN_DOWN_EXIT_DEGREES = 89.0
    }
}
