package com.example.livingai.pages.camera

import android.content.res.Resources
import android.graphics.Bitmap
import android.net.Uri
import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.livingai.domain.ml.FeedbackAnalyzer
import com.example.livingai.domain.ml.FeedbackState
import com.example.livingai.domain.ml.ObjectDetector
import com.example.livingai.utils.Constants
import com.example.livingai.utils.TiltSensorManager
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch

class VideoViewModel(
    private val objectDetector: ObjectDetector,
    private val feedbackAnalyzer: FeedbackAnalyzer,
    private val tiltSensorManager: TiltSensorManager
) : ViewModel() {

    private val _state = MutableStateFlow(VideoState())
    val state = _state.asStateFlow()

    init {
        tiltSensorManager.start()

        viewModelScope.launch {
            tiltSensorManager.tilt.collect { (pitch, _, _) ->
                _state.value = _state.value.copy(tilt = pitch)
            }
        }

        objectDetector.onResults = { results, _ ->
            if (results.isNotEmpty()) {
                Log.d(
                    "VideoViewModel",
                    "Detected objects: ${results.joinToString { "${it.text} (${it.score})" }}"
                )
            }

            val cow = results.firstOrNull { it.text.contains("cow", ignoreCase = true) }
            val feedback = feedbackAnalyzer.analyze(
                detection = cow,
                frameWidth = state.value.frameWidth,
                frameHeight = state.value.frameHeight,
                screenHeight = state.value.screenHeight,
                tiltDegrees = state.value.tilt,
                focalLengthPx = state.value.focalLength
            )
            _state.value = _state.value.copy(
                cowDetection = cow,
                feedback = feedback
            )
        }

        objectDetector.onError = { error ->
            Log.e("VideoViewModel", "Detection error: $error")
        }
    }

    override fun onCleared() {
        super.onCleared()
        tiltSensorManager.stop()
    }

    fun onEvent(event: VideoEvent) {
        when (event) {
            is VideoEvent.VideoRecorded -> {
                _state.value = _state.value.copy(recordedVideoUri = event.uri, isRecording = false)
            }
            is VideoEvent.StartRecording -> {
                _state.value = _state.value.copy(isRecording = true)
            }
            is VideoEvent.StopRecording -> {
                _state.value = _state.value.copy(isRecording = false)
            }
            is VideoEvent.ClearRecordedVideo -> {
                _state.value = _state.value.copy(recordedVideoUri = null)
            }
            is VideoEvent.FrameReceived -> {
                _state.value = _state.value.copy(
                    frameWidth = event.bitmap.width,
                    frameHeight = Constants.VIDEO_SILHOETTE_FRAME_HEIGHT.value.toInt(),
                    screenHeight = event.bitmap.height,
                    focalLength = event.focalLength
                )
                objectDetector.detect(event.bitmap, event.rotation)
            }
        }
    }
}

data class VideoState(
    val isRecording: Boolean = false,
    val recordedVideoUri: Uri? = null,
    val cowDetection: ObjectDetector.DetectionResult? = null,
    val feedback: FeedbackState = FeedbackState.Idle,
    val frameWidth: Int = 0,
    val frameHeight: Int = 0,
    val screenHeight: Int = 0,
    val tilt: Float = 0f,
    val focalLength: Float = 0f
)

sealed class VideoEvent {
    data class VideoRecorded(val uri: Uri) : VideoEvent()
    object StartRecording : VideoEvent()
    object StopRecording : VideoEvent()
    object ClearRecordedVideo : VideoEvent()
    data class FrameReceived(
        val bitmap: Bitmap, 
        val rotation: Int,
        val tilt: Float = 0f,
        val focalLength: Float = 0f
    ) : VideoEvent()
}
