package com.example.livingai.utils

import android.content.Context
import android.hardware.Sensor
import android.hardware.SensorEvent
import android.hardware.SensorEventListener
import android.hardware.SensorManager
import android.util.Log
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow

class TiltSensorManager(
    context: Context
) : SensorEventListener {

    private val sensorManager = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager
    private val rotationVectorSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR)

    private val _tilt = MutableStateFlow(Triple(0f, 0f, 0f)) // pitch, roll, azimuth
    val tilt: StateFlow<Triple<Float, Float, Float>> = _tilt.asStateFlow()

    init {
        Log.d("TiltSensorManager", "TiltSensorManager initialized.")
        if (rotationVectorSensor == null) {
            Log.e("TiltSensorManager", "Rotation Vector Sensor not available on this device.")
        }
    }

    fun start() {
        Log.d("TiltSensorManager", "start() called.")
        rotationVectorSensor?.let {
            val registered = sensorManager.registerListener(
                this,
                it,
                SensorManager.SENSOR_DELAY_UI
            )
            Log.d("TiltSensorManager", "Listener registration attempted. Success: $registered")
        } ?: Log.e("TiltSensorManager", "Cannot start listener, sensor is null.")
    }

    fun stop() {
        Log.d("TiltSensorManager", "stop() called.")
        sensorManager.unregisterListener(this)
    }

    override fun onSensorChanged(event: SensorEvent?) {
        event ?: return
        if (event.sensor.type != Sensor.TYPE_ROTATION_VECTOR) return

        val rotationMatrix = FloatArray(9)
        val orientationAngles = FloatArray(3)

        // Convert rotation vector to rotation matrix
        SensorManager.getRotationMatrixFromVector(rotationMatrix, event.values)

        // Convert rotation matrix to orientation angles
        SensorManager.getOrientation(rotationMatrix, orientationAngles)

        // orientationAngles: [azimuth, pitch, roll] in radians
        val azimuth = Math.toDegrees(orientationAngles[0].toDouble()).toFloat()
        val pitch = Math.toDegrees(orientationAngles[1].toDouble()).toFloat()
        val roll = Math.toDegrees(orientationAngles[2].toDouble()).toFloat()

        Log.d("TiltSensor", "Pitch: $pitch, Roll: $roll, Azimuth: $azimuth")

        _tilt.value = Triple(pitch, roll, azimuth)
    }

    override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {
        Log.d("TiltSensorManager", "Accuracy changed to $accuracy for sensor ${sensor?.name}")
    }
}
