package collection

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_file "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/domain/file"
	dom_tag "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/domain/tag"
	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_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"
	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/emailer/mailgun"
	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/ratelimit"
)

// Wire providers for collection services

func ProvideCreateCollectionService(
	cfg *config.Configuration,
	logger *zap.Logger,
	userGetByIDUseCase uc_user.UserGetByIDUseCase,
	repo dom_collection.CollectionRepository,
	tagRepo dom_tag.Repository,
) CreateCollectionService {
	return NewCreateCollectionService(cfg, logger, userGetByIDUseCase, repo, tagRepo)
}

func ProvideGetCollectionService(
	cfg *config.Configuration,
	logger *zap.Logger,
	repo dom_collection.CollectionRepository,
	userGetByIDUseCase uc_user.UserGetByIDUseCase,
	authFailureRateLimiter ratelimit.AuthFailureRateLimiter,
) GetCollectionService {
	return NewGetCollectionService(cfg, logger, repo, userGetByIDUseCase, authFailureRateLimiter)
}

func ProvideUpdateCollectionService(
	cfg *config.Configuration,
	logger *zap.Logger,
	repo dom_collection.CollectionRepository,
	authFailureRateLimiter ratelimit.AuthFailureRateLimiter,
) UpdateCollectionService {
	return NewUpdateCollectionService(cfg, logger, repo, authFailureRateLimiter)
}

func ProvideSoftDeleteCollectionService(
	cfg *config.Configuration,
	logger *zap.Logger,
	repo dom_collection.CollectionRepository,
	fileRepo dom_file.FileMetadataRepository,
	getCollectionUseCase uc_collection.GetCollectionUseCase,
	updateCollectionUseCase uc_collection.UpdateCollectionUseCase,
	hardDeleteCollectionUseCase uc_collection.HardDeleteCollectionUseCase,
	deleteMultipleDataUseCase uc_fileobjectstorage.DeleteMultipleEncryptedDataUseCase,
	storageQuotaHelperUseCase uc_user.UserStorageQuotaHelperUseCase,
	createStorageUsageEventUseCase uc_storageusageevent.CreateStorageUsageEventUseCase,
	updateStorageUsageUseCase uc_storagedailyusage.UpdateStorageUsageUseCase,
) SoftDeleteCollectionService {
	return NewSoftDeleteCollectionService(
		cfg,
		logger,
		repo,
		fileRepo,
		getCollectionUseCase,
		updateCollectionUseCase,
		hardDeleteCollectionUseCase,
		deleteMultipleDataUseCase,
		storageQuotaHelperUseCase,
		createStorageUsageEventUseCase,
		updateStorageUsageUseCase,
	)
}

func ProvideArchiveCollectionService(
	cfg *config.Configuration,
	logger *zap.Logger,
	repo dom_collection.CollectionRepository,
) ArchiveCollectionService {
	return NewArchiveCollectionService(cfg, logger, repo)
}

func ProvideRestoreCollectionService(
	cfg *config.Configuration,
	logger *zap.Logger,
	repo dom_collection.CollectionRepository,
) RestoreCollectionService {
	return NewRestoreCollectionService(cfg, logger, repo)
}

func ProvideListUserCollectionsService(
	cfg *config.Configuration,
	logger *zap.Logger,
	repo dom_collection.CollectionRepository,
	fileRepo dom_file.FileMetadataRepository,
) ListUserCollectionsService {
	return NewListUserCollectionsService(cfg, logger, repo, fileRepo)
}

func ProvideListSharedCollectionsService(
	cfg *config.Configuration,
	logger *zap.Logger,
	repo dom_collection.CollectionRepository,
	fileRepo dom_file.FileMetadataRepository,
) ListSharedCollectionsService {
	return NewListSharedCollectionsService(cfg, logger, repo, fileRepo)
}

func ProvideFindRootCollectionsService(
	cfg *config.Configuration,
	logger *zap.Logger,
	repo dom_collection.CollectionRepository,
) FindRootCollectionsService {
	return NewFindRootCollectionsService(cfg, logger, repo)
}

func ProvideFindCollectionsByParentService(
	cfg *config.Configuration,
	logger *zap.Logger,
	repo dom_collection.CollectionRepository,
) FindCollectionsByParentService {
	return NewFindCollectionsByParentService(cfg, logger, repo)
}

func ProvideGetCollectionSyncDataService(
	cfg *config.Configuration,
	logger *zap.Logger,
	getCollectionSyncDataUseCase uc_collection.GetCollectionSyncDataUseCase,
) GetCollectionSyncDataService {
	return NewGetCollectionSyncDataService(cfg, logger, getCollectionSyncDataUseCase)
}

func ProvideMoveCollectionService(
	cfg *config.Configuration,
	logger *zap.Logger,
	repo dom_collection.CollectionRepository,
) MoveCollectionService {
	return NewMoveCollectionService(cfg, logger, repo)
}

func ProvideGetFilteredCollectionsService(
	cfg *config.Configuration,
	logger *zap.Logger,
	repo dom_collection.CollectionRepository,
) GetFilteredCollectionsService {
	return NewGetFilteredCollectionsService(cfg, logger, repo)
}

func ProvideShareCollectionService(
	cfg *config.Configuration,
	logger *zap.Logger,
	repo dom_collection.CollectionRepository,
	checkBlockedEmailUC uc_blockedemail.CheckBlockedEmailUseCase,
	userGetByIDUC uc_user.UserGetByIDUseCase,
	emailer mailgun.Emailer,
) ShareCollectionService {
	return NewShareCollectionService(cfg, logger, repo, checkBlockedEmailUC, userGetByIDUC, emailer)
}

func ProvideRemoveMemberService(
	cfg *config.Configuration,
	logger *zap.Logger,
	repo dom_collection.CollectionRepository,
) RemoveMemberService {
	return NewRemoveMemberService(cfg, logger, repo)
}
