package com.placeholder.sherpai2.ui.imagedetail.viewmodel

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.placeholder.sherpai2.data.local.dao.FaceModelDao
import com.placeholder.sherpai2.data.local.dao.ImageDao
import com.placeholder.sherpai2.data.local.dao.PersonDao
import com.placeholder.sherpai2.data.local.dao.PhotoFaceTagDao
import com.placeholder.sherpai2.data.local.entity.TagEntity
import com.placeholder.sherpai2.domain.repository.TaggingRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import javax.inject.Inject

/**
 * Represents a person tagged in this photo via face recognition
 */
data class FaceTagInfo(
    val personId: String,
    val personName: String,
    val confidence: Float,
    val faceModelId: String,
    val tagId: String
)

/**
 * ImageDetailViewModel
 *
 * Owns:
 *  - Image context
 *  - Tag write operations
 *  - Face tag display (people recognized in photo)
 */
@HiltViewModel
@OptIn(ExperimentalCoroutinesApi::class)
class ImageDetailViewModel @Inject constructor(
    private val tagRepository: TaggingRepository,
    private val imageDao: ImageDao,
    private val photoFaceTagDao: PhotoFaceTagDao,
    private val faceModelDao: FaceModelDao,
    private val personDao: PersonDao
) : ViewModel() {

    private val imageUri = MutableStateFlow<String?>(null)

    val tags: StateFlow<List<TagEntity>> =
        imageUri
            .filterNotNull()
            .flatMapLatest { uri ->
                tagRepository.getTagsForImage(uri)
            }
            .stateIn(
                scope = viewModelScope,
                started = SharingStarted.WhileSubscribed(5_000),
                initialValue = emptyList()
            )

    // Face tags (people recognized in this photo)
    private val _faceTags = MutableStateFlow<List<FaceTagInfo>>(emptyList())
    val faceTags: StateFlow<List<FaceTagInfo>> = _faceTags.asStateFlow()

    fun loadImage(uri: String) {
        imageUri.value = uri
        loadFaceTags(uri)
    }

    private fun loadFaceTags(uri: String) {
        viewModelScope.launch {
            try {
                // Get imageId from URI
                val image = imageDao.getImageByUri(uri) ?: return@launch

                // Get face tags for this image
                val faceTags = photoFaceTagDao.getTagsForImage(image.imageId)

                // Resolve to person names
                val faceTagInfos = faceTags.mapNotNull { tag ->
                    val faceModel = faceModelDao.getFaceModelById(tag.faceModelId) ?: return@mapNotNull null
                    val person = personDao.getPersonById(faceModel.personId) ?: return@mapNotNull null

                    FaceTagInfo(
                        personId = person.id,
                        personName = person.name,
                        confidence = tag.confidence,
                        faceModelId = tag.faceModelId,
                        tagId = tag.id
                    )
                }

                _faceTags.value = faceTagInfos.sortedByDescending { it.confidence }
            } catch (e: Exception) {
                _faceTags.value = emptyList()
            }
        }
    }

    fun addTag(value: String) {
        val uri = imageUri.value ?: return
        viewModelScope.launch {
            tagRepository.addTagToImage(uri, value, source = "MANUAL", confidence = 1.0f)
        }
    }

    fun removeTag(tag: TagEntity) {
        val uri = imageUri.value ?: return
        viewModelScope.launch {
            tagRepository.removeTagFromImage(uri, tag.value)
        }
    }

    /**
     * Remove a face tag (person recognition)
     */
    fun removeFaceTag(faceTagInfo: FaceTagInfo) {
        viewModelScope.launch {
            photoFaceTagDao.deleteTagById(faceTagInfo.tagId)
            // Reload face tags
            imageUri.value?.let { loadFaceTags(it) }
        }
    }
}
