package com.placeholder.sherpai2.di

import android.content.Context
import androidx.work.WorkManager
import com.placeholder.sherpai2.data.local.dao.*
import com.placeholder.sherpai2.data.repository.FaceRecognitionRepository
import com.placeholder.sherpai2.data.repository.TaggingRepositoryImpl
import com.placeholder.sherpai2.domain.clustering.ClusterQualityAnalyzer
import com.placeholder.sherpai2.domain.clustering.ClusterRefinementService
import com.placeholder.sherpai2.domain.repository.ImageRepository
import com.placeholder.sherpai2.domain.repository.ImageRepositoryImpl
import com.placeholder.sherpai2.domain.repository.TaggingRepository
import com.placeholder.sherpai2.domain.validation.ValidationScanService
import dagger.Binds
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton

/**
 * RepositoryModule - Provides repository implementations
 *
 * UPDATED TO INCLUDE:
 * - FaceRecognitionRepository for face recognition operations
 * - ValidationScanService for post-training validation
 * - ClusterRefinementService for user feedback loop (NEW)
 * - ClusterQualityAnalyzer for cluster validation
 * - WorkManager for background tasks
 */
@Module
@InstallIn(SingletonComponent::class)
abstract class RepositoryModule {

    // ===== EXISTING REPOSITORY BINDINGS =====

    @Binds
    @Singleton
    abstract fun bindImageRepository(
        impl: ImageRepositoryImpl
    ): ImageRepository

    @Binds
    @Singleton
    abstract fun bindTaggingRepository(
        impl: TaggingRepositoryImpl
    ): TaggingRepository

    // ===== COMPANION OBJECT FOR PROVIDES =====

    companion object {

        /**
         * Provide FaceRecognitionRepository
         */
        @Provides
        @Singleton
        fun provideFaceRecognitionRepository(
            @ApplicationContext context: Context,
            personDao: PersonDao,
            imageDao: ImageDao,
            faceModelDao: FaceModelDao,
            photoFaceTagDao: PhotoFaceTagDao,
            personAgeTagDao: PersonAgeTagDao
        ): FaceRecognitionRepository {
            return FaceRecognitionRepository(
                context = context,
                personDao = personDao,
                imageDao = imageDao,
                faceModelDao = faceModelDao,
                photoFaceTagDao = photoFaceTagDao,
                personAgeTagDao = personAgeTagDao
            )
        }

        /**
         * Provide ValidationScanService
         */
        @Provides
        @Singleton
        fun provideValidationScanService(
            @ApplicationContext context: Context,
            imageDao: ImageDao,
            faceModelDao: FaceModelDao
        ): ValidationScanService {
            return ValidationScanService(
                context = context,
                imageDao = imageDao,
                faceModelDao = faceModelDao
            )
        }

        /**
         * Provide ClusterRefinementService (NEW)
         * Handles user feedback and cluster refinement workflow
         */
        @Provides
        @Singleton
        fun provideClusterRefinementService(
            faceCacheDao: FaceCacheDao,
            userFeedbackDao: UserFeedbackDao,
            qualityAnalyzer: ClusterQualityAnalyzer
        ): ClusterRefinementService {
            return ClusterRefinementService(
                faceCacheDao = faceCacheDao,
                userFeedbackDao = userFeedbackDao,
                qualityAnalyzer = qualityAnalyzer
            )
        }

        /**
         * Provide ClusterQualityAnalyzer
         * Validates cluster quality before training
         */
        @Provides
        @Singleton
        fun provideClusterQualityAnalyzer(): ClusterQualityAnalyzer {
            return ClusterQualityAnalyzer()
        }

        /**
         * Provide WorkManager for background tasks
         */
        @Provides
        @Singleton
        fun provideWorkManager(
            @ApplicationContext context: Context
        ): WorkManager {
            return WorkManager.getInstance(context)
        }
    }
}