package com.placeholder.sherpai2.data.repository

import com.placeholder.sherpai2.data.local.dao.ImageTagDao
import com.placeholder.sherpai2.data.local.dao.TagDao
import com.placeholder.sherpai2.data.local.entity.ImageTagEntity
import com.placeholder.sherpai2.data.local.entity.TagEntity
import com.placeholder.sherpai2.domain.repository.TaggingRepository
import kotlinx.coroutines.flow.Flow
import javax.inject.Inject
import javax.inject.Singleton

/**
 *
 *
 * Critical design decisions here
 *
 * Tag normalization happens once
 *
 * Visibility rules live here
 *
 * ML and manual tagging share the same path
 */

@Singleton
class TaggingRepositoryImpl @Inject constructor(
    private val tagDao: TagDao,
    private val imageTagDao: ImageTagDao
) : TaggingRepository {

    override suspend fun addTagToImage(
        imageId: String,
        tagValue: String,
        source: String,
        confidence: Float
    ) {
        // Step 1: normalize tag
        val normalized = tagValue.trim().lowercase()

        // Step 2: ensure tag exists
        val tag = tagDao.getByValue(normalized)
            ?: TagEntity(
                tagId = "tag_$normalized",
                type = "GENERIC",
                value = normalized,
                createdAt = System.currentTimeMillis()
            ).also { tagDao.insert(it) }

        // Step 3: attach tag to image
        imageTagDao.upsert(
            ImageTagEntity(
                imageId = imageId,
                tagId = tag.tagId,
                source = source,
                confidence = confidence,
                visibility = "PUBLIC",
                createdAt = System.currentTimeMillis()
            )
        )
    }

    override suspend fun hideTagForImage(
        imageId: String,
        tagValue: String
    ) {
        val tag = tagDao.getByValue(tagValue) ?: return

        imageTagDao.upsert(
            ImageTagEntity(
                imageId = imageId,
                tagId = tag.tagId,
                source = "MANUAL",
                confidence = 1.0f,
                visibility = "HIDDEN",
                createdAt = System.currentTimeMillis()
            )
        )
    }

    override fun getTagsForImage(imageId: String): Flow<List<TagEntity>> {
        // Join imageTagDao -> tagDao to get all PUBLIC tags for this image
        return imageTagDao.getTagsForImage(imageId)
    }

    override suspend fun removeTagFromImage(imageId: String, tagId: String) {
        // Mark the tag as hidden instead of deleting, keeping the visibility logic
        imageTagDao.upsert(
            ImageTagEntity(
                imageId = imageId,
                tagId = tagId,
                source = "MANUAL",
                confidence = 1.0f,
                visibility = "HIDDEN",
                createdAt = System.currentTimeMillis()
            )
        )
    }
}
