package com.placeholder.sherpai2.data.local.entity

import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.Index
import androidx.room.PrimaryKey
import java.util.UUID

/**
 * UserFeedbackEntity - Stores user corrections during cluster validation
 *
 * PURPOSE:
 * - Capture which faces user marked as correct/incorrect
 * - Ground truth data for improving clustering
 * - Enable cluster refinement before training
 * - Track confidence in automated detections
 *
 * USAGE FLOW:
 * 1. Clustering creates initial clusters
 * 2. User reviews ValidationPreview
 * 3. User swipes faces: ✅ Correct / ❌ Incorrect
 * 4. Feedback stored here
 * 5. If too many incorrect → Re-cluster without those faces
 * 6. If approved → Train model with confirmed faces only
 *
 * INDEXES:
 * - imageId: Fast lookup of feedback for specific images
 * - clusterId: Get all feedback for a cluster
 * - feedbackType: Filter by correction type
 * - personId: Track feedback after person created
 */
@Entity(
    tableName = "user_feedback",
    foreignKeys = [
        ForeignKey(
            entity = ImageEntity::class,
            parentColumns = ["imageId"],
            childColumns = ["imageId"],
            onDelete = ForeignKey.CASCADE
        ),
        ForeignKey(
            entity = PersonEntity::class,
            parentColumns = ["id"],
            childColumns = ["personId"],
            onDelete = ForeignKey.CASCADE
        )
    ],
    indices = [
        Index(value = ["imageId"]),
        Index(value = ["clusterId"]),
        Index(value = ["personId"]),
        Index(value = ["feedbackType"])
    ]
)
data class UserFeedbackEntity(
    @PrimaryKey
    val id: String = UUID.randomUUID().toString(),

    /**
     * Image containing the face
     */
    val imageId: String,

    /**
     * Face index within the image (0-based)
     * Multiple faces per image possible
     */
    val faceIndex: Int,

    /**
     * Cluster ID from clustering (before person created)
     * Null if feedback given after person exists
     */
    val clusterId: Int?,

    /**
     * Person ID if feedback is about an existing person
     * Null during initial cluster validation
     */
    val personId: String?,

    /**
     * Type of feedback user provided
     */
    val feedbackType: String, // FeedbackType enum stored as string

    /**
     * Confidence score that led to this face being shown
     * Helps identify if low confidence = more errors
     */
    val originalConfidence: Float,

    /**
     * Optional user note
     */
    val userNote: String? = null,

    /**
     * When feedback was provided
     */
    val timestamp: Long = System.currentTimeMillis()
) {
    companion object {
        fun create(
            imageId: String,
            faceIndex: Int,
            clusterId: Int? = null,
            personId: String? = null,
            feedbackType: FeedbackType,
            originalConfidence: Float,
            userNote: String? = null
        ): UserFeedbackEntity {
            return UserFeedbackEntity(
                imageId = imageId,
                faceIndex = faceIndex,
                clusterId = clusterId,
                personId = personId,
                feedbackType = feedbackType.name,
                originalConfidence = originalConfidence,
                userNote = userNote
            )
        }
    }

    fun getFeedbackType(): FeedbackType {
        return try {
            FeedbackType.valueOf(feedbackType)
        } catch (e: Exception) {
            FeedbackType.UNCERTAIN
        }
    }
}

/**
 * FeedbackType - Types of user corrections
 */
enum class FeedbackType {
    /**
     * User confirmed this face IS the person
     * Boosts confidence, use for training
     */
    CONFIRMED_MATCH,

    /**
     * User said this face is NOT the person
     * Remove from cluster, exclude from training
     */
    REJECTED_MATCH,

    /**
     * User marked as outlier during cluster review
     * Face doesn't belong in this cluster
     */
    MARKED_OUTLIER,

    /**
     * User is uncertain
     * Skip this face for training, revisit later
     */
    UNCERTAIN
}