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

import androidx.room.Entity
import androidx.room.Index
import androidx.room.PrimaryKey

/**
 * Represents a single image on the device.
 *
 * This entity is intentionally immutable (mostly):
 * - imageUri identifies where the image lives
 * - sha256 prevents duplicates
 * - capturedAt is the EXIF timestamp
 *
 * FACE DETECTION CACHE (mutable for performance):
 * - hasFaces: Boolean flag to skip images without faces
 * - faceCount: Number of faces detected (0 if no faces)
 * - facesLastDetected: Timestamp of last face detection
 * - faceDetectionVersion: Version number for cache invalidation
 *
 * These fields are populated during:
 * 1. Initial model training (already detecting faces)
 * 2. Utility scans (burst detection, quality analysis)
 * 3. Any face detection operation
 * 4. Background maintenance scans
 */
@Entity(
    tableName = "images",
    indices = [
        Index(value = ["imageUri"], unique = true),
        Index(value = ["sha256"], unique = true),
        Index(value = ["capturedAt"]),
        Index(value = ["hasFaces"]),  // NEW: For fast filtering
        Index(value = ["faceCount"])  // NEW: For range queries (singles, couples, groups)
    ]
)
data class ImageEntity(

    @PrimaryKey
    val imageId: String,

    val imageUri: String,

    /**
     * Cryptographic hash of image bytes.
     * Used for deduplication and re-indexing.
     */
    val sha256: String,

    /**
     * EXIF timestamp (UTC millis).
     */
    val capturedAt: Long,

    /**
     * When this image was indexed into the app.
     */
    val ingestedAt: Long,

    val width: Int,
    val height: Int,

    /**
     * CAMERA | SCREENSHOT | IMPORTED
     */
    val source: String,

    // ============================================================================
    // FACE DETECTION CACHE - Populated asynchronously
    // ============================================================================

    /**
     * Whether this image contains any faces.
     * - true: At least one face detected
     * - false: No faces detected
     * - null: Not yet scanned (default for newly ingested images)
     *
     * Use this to skip images without faces during person scanning.
     */
    val hasFaces: Boolean? = null,

    /**
     * Number of faces detected in this image.
     * - 0: No faces
     * - 1: Solo person (useful for filtering)
     * - 2: Couple (useful for filtering)
     * - 3+: Group photo (useful for filtering)
     * - null: Not yet scanned
     *
     * Use this for:
     * - Finding solo photos of a person
     * - Identifying couple photos
     * - Filtering out group photos if needed
     */
    val faceCount: Int? = null,

    /**
     * Timestamp when faces were last detected in this image.
     * Used for cache invalidation logic.
     *
     * Invalidate cache if:
     * - Image modified date > facesLastDetected
     * - faceDetectionVersion < current version
     */
    val facesLastDetected: Long? = null,

    /**
     * Face detection algorithm version.
     * Increment this when improving face detection to invalidate old cache.
     *
     * Current version: 1
     * - If detection algorithm improves, increment to 2
     * - Query will re-scan images with version < 2
     */
    val faceDetectionVersion: Int? = null
) {
    companion object {
        /**
         * Current face detection algorithm version.
         * Increment when making significant improvements to face detection.
         */
        const val CURRENT_FACE_DETECTION_VERSION = 1

        /**
         * Check if face detection cache is valid.
         * Invalid if:
         * - Never scanned (hasFaces == null)
         * - Old detection version
         * - Image modified after detection (would need file system check)
         */
        fun isFaceDetectionCacheValid(image: ImageEntity): Boolean {
            return image.hasFaces != null &&
                    image.faceDetectionVersion == CURRENT_FACE_DETECTION_VERSION
        }
    }

    /**
     * Check if this image needs face detection scanning.
     */
    fun needsFaceDetection(): Boolean {
        return hasFaces == null ||
                faceDetectionVersion == null ||
                faceDetectionVersion < CURRENT_FACE_DETECTION_VERSION
    }

    /**
     * Check if this image definitely has faces (cached).
     */
    fun hasCachedFaces(): Boolean {
        return hasFaces == true && !needsFaceDetection()
    }

    /**
     * Check if this image definitely has no faces (cached).
     */
    fun hasCachedNoFaces(): Boolean {
        return hasFaces == false && !needsFaceDetection()
    }

    /**
     * Get a copy with updated face detection cache.
     */
    fun withFaceDetectionCache(
        hasFaces: Boolean,
        faceCount: Int,
        timestamp: Long = System.currentTimeMillis()
    ): ImageEntity {
        return copy(
            hasFaces = hasFaces,
            faceCount = faceCount,
            facesLastDetected = timestamp,
            faceDetectionVersion = CURRENT_FACE_DETECTION_VERSION
        )
    }
}