package com.placeholder.sherpai2.workers

import android.content.Context
import androidx.hilt.work.HiltWorker
import androidx.work.*
import com.placeholder.sherpai2.domain.clustering.FaceClusteringService
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

/**
 * FaceClusteringWorker - Background face clustering with persistence
 *
 * BENEFITS:
 * - Survives app restarts
 * - Runs even when app is backgrounded
 * - Progress updates via WorkManager Data
 * - Results saved to shared preferences
 *
 * USAGE:
 * val workRequest = OneTimeWorkRequestBuilder<FaceClusteringWorker>()
 *     .setConstraints(...)
 *     .build()
 * WorkManager.getInstance(context).enqueue(workRequest)
 */
@HiltWorker
class FaceClusteringWorker @AssistedInject constructor(
    @Assisted private val context: Context,
    @Assisted workerParams: WorkerParameters,
    private val clusteringService: FaceClusteringService
) : CoroutineWorker(context, workerParams) {

    companion object {
        const val WORK_NAME = "face_clustering_discovery"
        const val KEY_PROGRESS_CURRENT = "progress_current"
        const val KEY_PROGRESS_TOTAL = "progress_total"
        const val KEY_PROGRESS_MESSAGE = "progress_message"
        const val KEY_CLUSTER_COUNT = "cluster_count"
        const val KEY_FACE_COUNT = "face_count"
        const val KEY_RESULT_JSON = "result_json"
    }

    override suspend fun doWork(): Result = withContext(Dispatchers.Default) {
        try {
            // Check if we should stop (work cancelled)
            if (isStopped) {
                return@withContext Result.failure()
            }

            withContext(Dispatchers.Main) {
                setProgress(
                    workDataOf(
                        KEY_PROGRESS_CURRENT to 0,
                        KEY_PROGRESS_TOTAL to 100,
                        KEY_PROGRESS_MESSAGE to "Starting discovery..."
                    )
                )
            }

            // Run clustering
            val result = clusteringService.discoverPeople(
                onProgress = { current, total, message ->
                    if (!isStopped) {
                        kotlinx.coroutines.runBlocking {
                            withContext(Dispatchers.Main) {
                                setProgress(
                                    workDataOf(
                                        KEY_PROGRESS_CURRENT to current,
                                        KEY_PROGRESS_TOTAL to total,
                                        KEY_PROGRESS_MESSAGE to message
                                    )
                                )
                            }
                        }
                    }
                }
            )

            // Save result to SharedPreferences for ViewModel to read
            val prefs = context.getSharedPreferences("face_clustering", Context.MODE_PRIVATE)
            prefs.edit().apply {
                putInt(KEY_CLUSTER_COUNT, result.clusters.size)
                putInt(KEY_FACE_COUNT, result.totalFacesAnalyzed)
                putLong("timestamp", System.currentTimeMillis())
                // Don't serialize full result - too complex without proper setup
                // Phase 2 will handle proper result persistence
                apply()
            }

            // Success!
            Result.success(
                workDataOf(
                    KEY_CLUSTER_COUNT to result.clusters.size,
                    KEY_FACE_COUNT to result.totalFacesAnalyzed
                )
            )

        } catch (e: Exception) {
            // Save error state
            val prefs = context.getSharedPreferences("face_clustering", Context.MODE_PRIVATE)
            prefs.edit().apply {
                putString("error", e.message ?: "Unknown error")
                putLong("timestamp", System.currentTimeMillis())
                apply()
            }

            Result.failure(
                workDataOf("error" to (e.message ?: "Unknown error"))
            )
        }
    }
}