//go:build wireinject
// +build wireinject

package app

import (
	"github.com/google/wire"

	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/config"
	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/interface/http"
	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/interface/http/blockedemail"
	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/interface/http/collection"
	commonhttp "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/interface/http/common"
	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/interface/http/dashboard"
	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/interface/http/file"
	http_inviteemail "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/interface/http/inviteemail"
	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/interface/http/me"
	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/interface/http/middleware"
	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/interface/http/tag"
	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/interface/http/user"
	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/interface/scheduler"
	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/interface/scheduler/tasks"
	blockedemailrepo "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/repo/blockedemail"
	collectionrepo "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/repo/collection"
	filemetadatarepo "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/repo/filemetadata"
	fileobjectstoragerepo "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/repo/fileobjectstorage"
	inviteemailratelimitrepo "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/repo/inviteemailratelimit"
	storagedailyusagerepo "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/repo/storagedailyusage"
	storageusageeventrepo "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/repo/storageusageevent"
	tagrepo "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/repo/tag"
	userrepo "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/repo/user"
	svc_auth "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/service/auth"
	svc_blockedemail "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/service/blockedemail"
	svc_collection "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/service/collection"
	svc_dashboard "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/service/dashboard"
	svc_file "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/service/file"
	svc_inviteemail "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/service/inviteemail"
	svc_ipanonymization "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/service/ipanonymization"
	svc_me "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/service/me"
	svc_tag "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/service/tag"
	svc_user "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/service/user"
	uc_blockedemail "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/usecase/blockedemail"
	uc_collection "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/usecase/collection"
	uc_filemetadata "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/usecase/filemetadata"
	uc_fileobjectstorage "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/usecase/fileobjectstorage"
	uc_storagedailyusage "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/usecase/storagedailyusage"
	uc_storageusageevent "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/usecase/storageusageevent"
	uc_tag "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/usecase/tag"
	uc_user "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/usecase/user"
	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/auditlog"
	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/distributedmutex"
	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/emailer/mailgun"
	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/leaderelection"
	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/logger"
	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/ratelimit"
	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/security/jwt"
	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/storage/cache/cassandracache"
	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/storage/database/cassandradb"
	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/storage/memory/redis"
	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/storage/object/s3"
)

// InitializeApplication wires up all dependencies using Google Wire
func InitializeApplication(cfg *config.Configuration) (*Application, error) {
	wire.Build(
		// Infrastructure layer (pkg/)
		logger.ProvideLogger,
		auditlog.ProvideAuditLogger,
		cassandradb.ProvideCassandraConnection,
		cassandradb.NewMigrator,
		cassandracache.ProvideCassandraCacher,
		redis.ProvideRedisUniversalClient,
		s3.ProvideS3ObjectStorageProvider,
		jwt.ProvideJWTProvider,
		mailgun.ProvideMapleFileModuleEmailer,
		distributedmutex.ProvideDistributedMutexAdapter,
		leaderelection.ProvideLeaderElection,
		ratelimit.ProvideLoginRateLimiter,
		ratelimit.ProvideAuthFailureRateLimiter,
		middleware.ProvideRateLimitMiddleware,
		middleware.ProvideSecurityHeadersMiddleware,

		// Repository layer
		blockedemailrepo.NewBlockedEmailRepository,
		filemetadatarepo.ProvideRepository,
		fileobjectstoragerepo.ProvideRepository,
		userrepo.ProvideRepository,
		collectionrepo.ProvideRepository,
		storagedailyusagerepo.ProvideRepository,
		storageusageeventrepo.ProvideRepository,
		inviteemailratelimitrepo.ProvideRepository,
		tagrepo.ProvideTagRepository,

		// Use case layer - Collection (10 providers - only used ones)
		uc_collection.ProvideGetCollectionUseCase,
		uc_collection.ProvideUpdateCollectionUseCase,
		uc_collection.ProvideHardDeleteCollectionUseCase,
		uc_collection.ProvideCheckCollectionAccessUseCase,
		uc_collection.ProvideGetCollectionSyncDataUseCase,
		uc_collection.ProvideCountUserFoldersUseCase,
		uc_collection.ProvideAnonymizeOldIPsUseCase,
		uc_collection.ProvideListCollectionsByUserUseCase,
		uc_collection.ProvideRemoveUserFromAllCollectionsUseCase,
		uc_collection.ProvideAnonymizeUserReferencesUseCase,

		// Use case layer - File Metadata (15 providers - only used ones)
		uc_filemetadata.ProvideCreateFileMetadataUseCase,
		uc_filemetadata.ProvideGetFileMetadataUseCase,
		uc_filemetadata.ProvideGetFileMetadataByCollectionUseCase,
		uc_filemetadata.ProvideUpdateFileMetadataUseCase,
		uc_filemetadata.ProvideSoftDeleteFileMetadataUseCase,
		uc_filemetadata.ProvideHardDeleteFileMetadataUseCase,
		uc_filemetadata.ProvideCountUserFilesUseCase,
		uc_filemetadata.ProvideGetFileMetadataByOwnerIDUseCase,
		uc_filemetadata.ProvideGetFileMetadataByIDsUseCase,
		uc_filemetadata.ProvideListFileMetadataSyncDataUseCase,
		uc_filemetadata.ProvideDeleteManyFileMetadataUseCase,
		uc_filemetadata.ProvideCheckFileExistsUseCase,
		uc_filemetadata.ProvideListRecentFilesUseCase,
		uc_filemetadata.ProvideAnonymizeOldIPsUseCase,
		uc_filemetadata.ProvideAnonymizeUserReferencesUseCase,

		// Use case layer - File Object Storage (6 providers - only used ones)
		uc_fileobjectstorage.ProvideGeneratePresignedUploadURLUseCase,
		uc_fileobjectstorage.ProvideGeneratePresignedDownloadURLUseCase,
		uc_fileobjectstorage.ProvideDeleteEncryptedDataUseCase,
		uc_fileobjectstorage.ProvideDeleteMultipleEncryptedDataUseCase,
		uc_fileobjectstorage.ProvideVerifyObjectExistsUseCase,
		uc_fileobjectstorage.ProvideGetObjectSizeUseCase,

		// Use case layer - User (10 providers)
		uc_user.ProvideUserCreateUseCase,
		uc_user.ProvideUserGetByIDUseCase,
		uc_user.ProvideUserGetByEmailUseCase,
		uc_user.ProvideUserGetByVerificationCodeUseCase,
		uc_user.ProvideUserUpdateUseCase,
		uc_user.ProvideUserDeleteByIDUseCase,
		uc_user.ProvideUserStorageQuotaHelperUseCase,
		uc_user.ProvideAnonymizeOldIPsUseCase,
		uc_user.ProvideAnonymizeUserIPsImmediatelyUseCase,
		uc_user.ProvideClearUserCacheUseCase,

		// Use case layer - Blocked Email (4 providers)
		uc_blockedemail.NewCreateBlockedEmailUseCase,
		uc_blockedemail.NewListBlockedEmailsUseCase,
		uc_blockedemail.NewDeleteBlockedEmailUseCase,
		uc_blockedemail.NewCheckBlockedEmailUseCase,

		// Use case layer - Storage Daily Usage (3 providers - only used ones)
		uc_storagedailyusage.ProvideGetStorageDailyUsageTrendUseCase,
		uc_storagedailyusage.ProvideUpdateStorageUsageUseCase,
		uc_storagedailyusage.ProvideDeleteByUserUseCase,

		// Use case layer - Storage Usage Event (2 providers)
		uc_storageusageevent.ProvideCreateStorageUsageEventUseCase,
		uc_storageusageevent.ProvideDeleteByUserUseCase,

		// Use case layer - Tag (11 providers)
		uc_tag.ProvideCreateTagUseCase,
		uc_tag.ProvideGetTagByIDUseCase,
		uc_tag.ProvideListTagsByUserUseCase,
		uc_tag.ProvideUpdateTagUseCase,
		uc_tag.ProvideDeleteTagUseCase,
		uc_tag.ProvideAssignTagUseCase,
		uc_tag.ProvideUnassignTagUseCase,
		uc_tag.ProvideGetTagsForEntityUseCase,
		uc_tag.ProvideListCollectionsByTagUseCase,
		uc_tag.ProvideListFilesByTagUseCase,
		// NOTE: ProvideCreateDefaultTagsUseCase removed - default tags must be created client-side due to E2EE

		// Service layer - Collection (15 providers)
		svc_collection.ProvideCreateCollectionService,
		svc_collection.ProvideGetCollectionService,
		svc_collection.ProvideListUserCollectionsService,
		svc_collection.ProvideUpdateCollectionService,
		svc_collection.ProvideSoftDeleteCollectionService,
		svc_collection.ProvideArchiveCollectionService,
		svc_collection.ProvideRestoreCollectionService,
		svc_collection.ProvideListSharedCollectionsService,
		svc_collection.ProvideFindRootCollectionsService,
		svc_collection.ProvideFindCollectionsByParentService,
		svc_collection.ProvideGetCollectionSyncDataService,
		svc_collection.ProvideMoveCollectionService,
		svc_collection.ProvideGetFilteredCollectionsService,
		svc_collection.ProvideShareCollectionService,
		svc_collection.ProvideRemoveMemberService,

		// Service layer - File (14 providers)
		svc_file.ProvideCreatePendingFileService,
		svc_file.ProvideGetPresignedUploadURLService,
		svc_file.ProvideCompleteFileUploadService,
		svc_file.ProvideGetFileService,
		svc_file.ProvideGetPresignedDownloadURLService,
		svc_file.ProvideListFilesByCollectionService,
		svc_file.ProvideListRecentFilesService,
		svc_file.ProvideUpdateFileService,
		svc_file.ProvideSoftDeleteFileService,
		svc_file.ProvideArchiveFileService,
		svc_file.ProvideRestoreFileService,
		svc_file.ProvideDeleteMultipleFilesService,
		svc_file.ProvideListFileSyncDataService,
		svc_file.ProvideListFilesByOwnerIDService,

		// Service layer - Auth (10 providers)
		svc_auth.ProvideRegisterService,
		svc_auth.ProvideVerifyEmailService,
		svc_auth.ProvideResendVerificationService,
		svc_auth.ProvideRequestOTTService,
		svc_auth.ProvideVerifyOTTService,
		svc_auth.ProvideCompleteLoginService,
		svc_auth.ProvideRefreshTokenService,
		svc_auth.ProvideRecoveryInitiateService,
		svc_auth.ProvideRecoveryVerifyService,
		svc_auth.ProvideRecoveryCompleteService,

		// Service layer - Me (5 providers)
		svc_me.ProvideGetMeService,
		svc_me.ProvideUpdateMeService,
		svc_me.ProvideDeleteMeService,
		svc_me.ProvideChangeEmailRequestService,
		svc_me.ProvideChangeEmailVerifyService,

		// Service layer - Dashboard (1 provider)
		svc_dashboard.ProvideGetDashboardService,

		// Service layer - User (2 providers)
		svc_user.ProvideUserPublicLookupService,
		svc_user.ProvideCompleteUserDeletionService,

		// Service layer - Blocked Email (3 providers)
		svc_blockedemail.ProvideCreateBlockedEmailService,
		svc_blockedemail.ProvideListBlockedEmailsService,
		svc_blockedemail.ProvideDeleteBlockedEmailService,

		// Service layer - Invite Email (1 provider)
		svc_inviteemail.ProvideSendInviteEmailService,

		// Service layer - IP Anonymization (1 provider)
		svc_ipanonymization.ProvideAnonymizeOldIPsService,

		// Service layer - Tag (2 providers)
		svc_tag.ProvideTagService,
		svc_tag.ProvideSearchByTagsService,

		// Service layer - Storage Daily Usage (none currently used)

		// Middleware
		middleware.ProvideMiddleware,

		// HTTP handlers - Common
		commonhttp.ProvideMapleFileVersionHTTPHandler,

		// HTTP handlers - Dashboard
		dashboard.ProvideGetDashboardHTTPHandler,

		// HTTP handlers - Me (5 providers)
		me.ProvideGetMeHTTPHandler,
		me.ProvidePutUpdateMeHTTPHandler,
		me.ProvideDeleteMeHTTPHandler,
		me.ProvidePostChangeEmailRequestHTTPHandler,
		me.ProvidePostChangeEmailVerifyHTTPHandler,

		// HTTP handlers - User (1 provider)
		user.ProvideUserPublicLookupHTTPHandler,

		// HTTP handlers - Blocked Email (3 providers)
		blockedemail.ProvideCreateBlockedEmailHTTPHandler,
		blockedemail.ProvideListBlockedEmailsHTTPHandler,
		blockedemail.ProvideDeleteBlockedEmailHTTPHandler,

		// HTTP handlers - Invite Email (1 provider)
		http_inviteemail.ProvideSendInviteEmailHTTPHandler,

		// HTTP handlers - Collection (15 providers)
		collection.ProvideCreateCollectionHTTPHandler,
		collection.ProvideGetCollectionHTTPHandler,
		collection.ProvideListUserCollectionsHTTPHandler,
		collection.ProvideUpdateCollectionHTTPHandler,
		collection.ProvideSoftDeleteCollectionHTTPHandler,
		collection.ProvideArchiveCollectionHTTPHandler,
		collection.ProvideRestoreCollectionHTTPHandler,
		collection.ProvideListSharedCollectionsHTTPHandler,
		collection.ProvideFindRootCollectionsHTTPHandler,
		collection.ProvideFindCollectionsByParentHTTPHandler,
		collection.ProvideCollectionSyncHTTPHandler,
		collection.ProvideMoveCollectionHTTPHandler,
		collection.ProvideGetFilteredCollectionsHTTPHandler,
		collection.ProvideShareCollectionHTTPHandler,
		collection.ProvideRemoveMemberHTTPHandler,

		// HTTP handlers - File (14 providers)
		file.ProvideCreatePendingFileHTTPHandler,
		file.ProvideGetPresignedUploadURLHTTPHandler,
		file.ProvideCompleteFileUploadHTTPHandler,
		file.ProvideGetFileHTTPHandler,
		file.ProvideGetPresignedDownloadURLHTTPHandler,
		file.ProvideReportDownloadCompletedHTTPHandler,
		file.ProvideListFilesByCollectionHTTPHandler,
		file.ProvideListRecentFilesHTTPHandler,
		file.ProvideUpdateFileHTTPHandler,
		file.ProvideSoftDeleteFileHTTPHandler,
		file.ProvideArchiveFileHTTPHandler,
		file.ProvideRestoreFileHTTPHandler,
		file.ProvideDeleteMultipleFilesHTTPHandler,
		file.ProvideFileSyncHTTPHandler,

		// HTTP handlers - Tag (12 providers)
		tag.ProvideCreateTagHTTPHandler,
		tag.ProvideListTagsHTTPHandler,
		tag.ProvideGetTagHTTPHandler,
		tag.ProvideUpdateTagHTTPHandler,
		tag.ProvideDeleteTagHTTPHandler,
		tag.ProvideAssignTagHTTPHandler,
		tag.ProvideUnassignTagHTTPHandler,
		tag.ProvideGetTagsForCollectionHTTPHandler,
		tag.ProvideGetTagsForFileHTTPHandler,
		tag.ProvideListCollectionsByTagHandler,
		tag.ProvideListFilesByTagHandler,
		tag.ProvideSearchByTagsHandler,

		// HTTP layer - Aggregate Handlers
		http.ProvideHandlers,

		// HTTP layer - Server
		http.ProvideServer,

		// Scheduler
		scheduler.ProvideScheduler,
		tasks.ProvideIPAnonymizationTask,

		// Application
		ProvideApplication,
	)

	return nil, nil
}
