package file

import (
	"go.uber.org/zap"

	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/config"
	dom_collection "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/domain/collection"
	dom_tag "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/domain/tag"
	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_user "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/usecase/user"
)

// Wire providers for file services

func ProvideGetFileService(
	cfg *config.Configuration,
	logger *zap.Logger,
	collectionRepo dom_collection.CollectionRepository,
	getMetadataUseCase uc_filemetadata.GetFileMetadataUseCase,
) GetFileService {
	return NewGetFileService(cfg, logger, collectionRepo, getMetadataUseCase)
}

func ProvideUpdateFileService(
	cfg *config.Configuration,
	logger *zap.Logger,
	collectionRepo dom_collection.CollectionRepository,
	getMetadataUseCase uc_filemetadata.GetFileMetadataUseCase,
	updateMetadataUseCase uc_filemetadata.UpdateFileMetadataUseCase,
) UpdateFileService {
	return NewUpdateFileService(cfg, logger, collectionRepo, getMetadataUseCase, updateMetadataUseCase)
}

func ProvideSoftDeleteFileService(
	cfg *config.Configuration,
	logger *zap.Logger,
	collectionRepo dom_collection.CollectionRepository,
	getMetadataUseCase uc_filemetadata.GetFileMetadataUseCase,
	updateFileMetadataUseCase uc_filemetadata.UpdateFileMetadataUseCase,
	softDeleteMetadataUseCase uc_filemetadata.SoftDeleteFileMetadataUseCase,
	hardDeleteMetadataUseCase uc_filemetadata.HardDeleteFileMetadataUseCase,
	deleteDataUseCase uc_fileobjectstorage.DeleteEncryptedDataUseCase,
	listFilesByOwnerIDService ListFilesByOwnerIDService,
	storageQuotaHelperUseCase uc_user.UserStorageQuotaHelperUseCase,
	createStorageUsageEventUseCase uc_storageusageevent.CreateStorageUsageEventUseCase,
	updateStorageUsageUseCase uc_storagedailyusage.UpdateStorageUsageUseCase,
) SoftDeleteFileService {
	return NewSoftDeleteFileService(cfg, logger, collectionRepo, getMetadataUseCase, updateFileMetadataUseCase, softDeleteMetadataUseCase, hardDeleteMetadataUseCase, deleteDataUseCase, listFilesByOwnerIDService, storageQuotaHelperUseCase, createStorageUsageEventUseCase, updateStorageUsageUseCase)
}

func ProvideDeleteMultipleFilesService(
	cfg *config.Configuration,
	logger *zap.Logger,
	collectionRepo dom_collection.CollectionRepository,
	getMetadataByIDsUseCase uc_filemetadata.GetFileMetadataByIDsUseCase,
	deleteMetadataManyUseCase uc_filemetadata.DeleteManyFileMetadataUseCase,
	deleteMultipleDataUseCase uc_fileobjectstorage.DeleteMultipleEncryptedDataUseCase,
	createStorageUsageEventUseCase uc_storageusageevent.CreateStorageUsageEventUseCase,
	updateStorageUsageUseCase uc_storagedailyusage.UpdateStorageUsageUseCase,
) DeleteMultipleFilesService {
	return NewDeleteMultipleFilesService(cfg, logger, collectionRepo, getMetadataByIDsUseCase, deleteMetadataManyUseCase, deleteMultipleDataUseCase, createStorageUsageEventUseCase, updateStorageUsageUseCase)
}

func ProvideListFilesByCollectionService(
	cfg *config.Configuration,
	logger *zap.Logger,
	collectionRepo dom_collection.CollectionRepository,
	getFilesByCollectionUseCase uc_filemetadata.GetFileMetadataByCollectionUseCase,
) ListFilesByCollectionService {
	return NewListFilesByCollectionService(cfg, logger, collectionRepo, getFilesByCollectionUseCase)
}

func ProvideListFilesByCreatedByUserIDService(
	cfg *config.Configuration,
	logger *zap.Logger,
	getFilesByCreatedByUserIDUseCase uc_filemetadata.GetFileMetadataByCreatedByUserIDUseCase,
) ListFilesByCreatedByUserIDService {
	return NewListFilesByCreatedByUserIDService(cfg, logger, getFilesByCreatedByUserIDUseCase)
}

func ProvideListFilesByOwnerIDService(
	cfg *config.Configuration,
	logger *zap.Logger,
	getFilesByOwnerIDUseCase uc_filemetadata.GetFileMetadataByOwnerIDUseCase,
) ListFilesByOwnerIDService {
	return NewListFilesByOwnerIDService(cfg, logger, getFilesByOwnerIDUseCase)
}

func ProvideListRecentFilesService(
	cfg *config.Configuration,
	logger *zap.Logger,
	listRecentFilesUseCase uc_filemetadata.ListRecentFilesUseCase,
) ListRecentFilesService {
	return NewListRecentFilesService(cfg, logger, listRecentFilesUseCase)
}

func ProvideListFileSyncDataService(
	cfg *config.Configuration,
	logger *zap.Logger,
	listSyncDataUseCase uc_filemetadata.ListFileMetadataSyncDataUseCase,
	collectionRepo dom_collection.CollectionRepository,
) ListFileSyncDataService {
	return NewListFileSyncDataService(cfg, logger, listSyncDataUseCase, collectionRepo)
}

func ProvideCreatePendingFileService(
	cfg *config.Configuration,
	logger *zap.Logger,
	getCollectionUseCase uc_collection.GetCollectionUseCase,
	checkCollectionAccessUseCase uc_collection.CheckCollectionAccessUseCase,
	checkFileExistsUseCase uc_filemetadata.CheckFileExistsUseCase,
	createMetadataUseCase uc_filemetadata.CreateFileMetadataUseCase,
	generatePresignedUploadURLUseCase uc_fileobjectstorage.GeneratePresignedUploadURLUseCase,
	storageQuotaHelperUseCase uc_user.UserStorageQuotaHelperUseCase,
	tagRepo dom_tag.Repository,
) CreatePendingFileService {
	return NewCreatePendingFileService(cfg, logger, getCollectionUseCase, checkCollectionAccessUseCase, checkFileExistsUseCase, createMetadataUseCase, generatePresignedUploadURLUseCase, storageQuotaHelperUseCase, tagRepo)
}

func ProvideCompleteFileUploadService(
	cfg *config.Configuration,
	logger *zap.Logger,
	collectionRepo dom_collection.CollectionRepository,
	getMetadataUseCase uc_filemetadata.GetFileMetadataUseCase,
	updateMetadataUseCase uc_filemetadata.UpdateFileMetadataUseCase,
	verifyObjectExistsUseCase uc_fileobjectstorage.VerifyObjectExistsUseCase,
	getObjectSizeUseCase uc_fileobjectstorage.GetObjectSizeUseCase,
	deleteDataUseCase uc_fileobjectstorage.DeleteEncryptedDataUseCase,
	storageQuotaHelperUseCase uc_user.UserStorageQuotaHelperUseCase,
	createStorageUsageEventUseCase uc_storageusageevent.CreateStorageUsageEventUseCase,
	updateStorageUsageUseCase uc_storagedailyusage.UpdateStorageUsageUseCase,
) CompleteFileUploadService {
	return NewCompleteFileUploadService(cfg, logger, collectionRepo, getMetadataUseCase, updateMetadataUseCase, verifyObjectExistsUseCase, getObjectSizeUseCase, deleteDataUseCase, storageQuotaHelperUseCase, createStorageUsageEventUseCase, updateStorageUsageUseCase)
}

func ProvideGetPresignedUploadURLService(
	cfg *config.Configuration,
	logger *zap.Logger,
	collectionRepo dom_collection.CollectionRepository,
	getMetadataUseCase uc_filemetadata.GetFileMetadataUseCase,
	generatePresignedUploadURLUseCase uc_fileobjectstorage.GeneratePresignedUploadURLUseCase,
) GetPresignedUploadURLService {
	return NewGetPresignedUploadURLService(cfg, logger, collectionRepo, getMetadataUseCase, generatePresignedUploadURLUseCase)
}

func ProvideGetPresignedDownloadURLService(
	cfg *config.Configuration,
	logger *zap.Logger,
	collectionRepo dom_collection.CollectionRepository,
	getMetadataUseCase uc_filemetadata.GetFileMetadataUseCase,
	generatePresignedDownloadURLUseCase uc_fileobjectstorage.GeneratePresignedDownloadURLUseCase,
) GetPresignedDownloadURLService {
	return NewGetPresignedDownloadURLService(cfg, logger, collectionRepo, getMetadataUseCase, generatePresignedDownloadURLUseCase)
}

func ProvideArchiveFileService(
	cfg *config.Configuration,
	logger *zap.Logger,
	collectionRepo dom_collection.CollectionRepository,
	getMetadataUseCase uc_filemetadata.GetFileMetadataUseCase,
	updateMetadataUseCase uc_filemetadata.UpdateFileMetadataUseCase,
) ArchiveFileService {
	return NewArchiveFileService(cfg, logger, collectionRepo, getMetadataUseCase, updateMetadataUseCase)
}

func ProvideRestoreFileService(
	cfg *config.Configuration,
	logger *zap.Logger,
	collectionRepo dom_collection.CollectionRepository,
	getMetadataUseCase uc_filemetadata.GetFileMetadataUseCase,
	updateMetadataUseCase uc_filemetadata.UpdateFileMetadataUseCase,
) RestoreFileService {
	return NewRestoreFileService(cfg, logger, collectionRepo, getMetadataUseCase, updateMetadataUseCase)
}
