//go:build wireinject
// +build wireinject

package app

import (
	"github.com/google/wire"

	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/config"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/http/middleware"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/interface/http"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/interface/http/handler/admin"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/interface/http/handler/gateway"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/interface/http/handler/healthcheck"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/interface/http/handler/plugin"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/interface/http/handler/site"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/interface/http/handler/tenant"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/interface/http/handler/user"
	siterepo "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/repo"
	tenantrepo "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/repository/tenant"
	userrepo "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/repository/user"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/scheduler"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/service"
	gatewaysvc "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/service/gateway"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/service/ipcleanup"
	pagesvc "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/service/page"
	securityeventservice "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/service/securityevent"
	sitesvc "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/service/site"
	tenantsvc "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/service/tenant"
	usersvc "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/service/user"
	gatewayuc "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/usecase/gateway"
	pageusecase "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/usecase/page"
	siteusecase "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/usecase/site"
	tenantusecase "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/usecase/tenant"
	userusecase "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/usecase/user"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/cache"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/distributedmutex"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/dns"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/leaderelection"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/logger"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/ratelimit"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/search"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/security"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/security/apikey"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/security/ipcrypt"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/security/password"
	rediscache "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/storage/cache"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/storage/database"
)

// InitializeApplication wires up all dependencies
func InitializeApplication(cfg *config.Config) (*Application, error) {
	wire.Build(
		// Infrastructure layer (pkg/)
		logger.ProvideLogger,
		database.ProvideCassandraSession,

		// Cache layer
		rediscache.ProvideRedisClient,
		cache.ProvideRedisCache,
		cache.ProvideCassandraCache,
		cache.ProvideTwoTierCache,

		// Security layer
		security.ProvideJWTProvider,
		password.NewPasswordProvider,
		password.NewPasswordValidator,
		password.NewBreachChecker,         // CWE-521: Password breach checking
		security.ProvideClientIPExtractor, // CWE-348: X-Forwarded-For validation
		apikey.ProvideGenerator,
		apikey.ProvideHasher,
		ipcrypt.ProvideIPEncryptor, // CWE-359: IP encryption for GDPR compliance

		// Meilisearch client
		search.ProvideClient,

		// DNS verifier (for domain ownership verification)
		dns.ProvideVerifier,

		// Rate limiter
		ratelimit.ProvideLoginRateLimiter, // CWE-307: Login rate limiting and account lockout

		// Distributed mutex (for race condition prevention)
		distributedmutex.ProvideDistributedMutexAdapter,

		// Leader election (for distributed scheduling)
		leaderelection.ProvideLeaderElection,

		// Repository layer (internal/repository/)
		siterepo.NewSiteRepository,
		siterepo.NewPageRepository,
		tenantrepo.ProvideRepository,
		userrepo.ProvideRepository,

		// Use case layer (internal/usecase/)
		// Tenant usecases - refactored to focused operations
		tenantusecase.ProvideValidateTenantSlugUniqueUseCase,
		tenantusecase.ProvideCreateTenantEntityUseCase,
		tenantusecase.ProvideSaveTenantToRepoUseCase,
		tenantusecase.ProvideGetTenantUseCase,
		tenantusecase.ProvideDeleteTenantUseCase, // For SAGA compensation
		// User usecases - refactored to focused operations
		userusecase.ProvideValidateUserEmailUniqueUseCase,
		userusecase.ProvideCreateUserEntityUseCase,
		userusecase.ProvideSaveUserToRepoUseCase,
		userusecase.ProvideGetUserUseCase,
		userusecase.ProvideDeleteUserUseCase, // For SAGA compensation
		// Gateway usecases - focused operations only (no orchestration)
		// Register usecases (used by RegisterService)
		gatewayuc.ProvideValidateRegistrationInputUseCase,
		gatewayuc.ProvideCheckTenantSlugAvailabilityUseCase,
		gatewayuc.ProvideCheckPasswordBreachUseCase, // CWE-521: Password breach checking
		gatewayuc.ProvideHashPasswordUseCase,
		// Login usecases (used by LoginUseCase)
		gatewayuc.ProvideGetUserByEmailUseCase,
		gatewayuc.ProvideVerifyPasswordUseCase,
		gatewayuc.ProvideLoginUseCase,
		// Site usecases - refactored to focused operations
		siteusecase.ProvideValidateDomainUseCase,
		siteusecase.ProvideGenerateAPIKeyUseCase,
		siteusecase.ProvideGenerateVerificationTokenUseCase,
		siteusecase.ProvideCreateSiteEntityUseCase,
		siteusecase.ProvideSaveSiteToRepoUseCase,
		siteusecase.ProvideGetSiteUseCase,
		siteusecase.ProvideListSitesUseCase,
		siteusecase.ProvideValidateSiteForDeletionUseCase,
		siteusecase.ProvideDeleteSiteFromRepoUseCase,
		siteusecase.ProvideUpdateSiteAPIKeyUseCase,
		siteusecase.ProvideUpdateSiteAPIKeyToRepoUseCase,
		siteusecase.ProvideAuthenticateAPIKeyUseCase,
		siteusecase.ProvideVerifySiteUseCase,
		// Page usecases - refactored to focused operations
		// Sync usecases
		pageusecase.ProvideValidateSiteUseCase,
		pageusecase.ProvideEnsureSearchIndexUseCase,
		pageusecase.ProvideCreatePageEntityUseCase,
		pageusecase.ProvideUpsertPageUseCase,
		pageusecase.ProvideIndexPageToSearchUseCase,
		pageusecase.ProvideUpdateSiteUsageUseCase,
		// Delete usecases
		pageusecase.ProvideValidateSiteForDeletionUseCase,
		pageusecase.ProvideDeletePagesFromRepoUseCase,
		pageusecase.ProvideDeletePagesFromSearchUseCase,
		// Search usecases
		pageusecase.ProvideValidateSiteForSearchUseCase,
		pageusecase.ProvideExecuteSearchQueryUseCase,
		pageusecase.ProvideIncrementSearchCountUseCase,
		// Status usecases
		pageusecase.ProvideValidateSiteForStatusUseCase,
		pageusecase.ProvideGetPageStatisticsUseCase,
		pageusecase.ProvideGetSearchIndexStatusUseCase,
		pageusecase.ProvideGetPageByIDUseCase,
		siteusecase.ProvideResetMonthlyUsageUseCase,

		// Service layer (internal/service/)
		service.ProvideSessionService,
		tenantsvc.ProvideCreateTenantService,
		tenantsvc.ProvideGetTenantService,
		usersvc.ProvideCreateUserService,
		usersvc.ProvideGetUserService,
		sitesvc.ProvideCreateSiteService,
		sitesvc.ProvideGetSiteService,
		sitesvc.ProvideListSitesService,
		sitesvc.ProvideDeleteSiteService,
		sitesvc.ProvideRotateAPIKeyService,
		sitesvc.ProvideAuthenticateAPIKeyService,
		sitesvc.ProvideVerifySiteService,
		gatewaysvc.ProvideRegisterService,
		gatewaysvc.ProvideLoginService,
		gatewaysvc.ProvideRefreshTokenService,
		pagesvc.NewSyncPagesService,
		pagesvc.NewSearchPagesService,
		pagesvc.NewDeletePagesService,
		pagesvc.NewSyncStatusService,
		ipcleanup.ProvideCleanupService,                 // CWE-359: IP cleanup for GDPR compliance
		securityeventservice.ProvideSecurityEventLogger, // CWE-778: Security event logging

		// Middleware layer
		middleware.ProvideJWTMiddleware,
		middleware.ProvideAPIKeyMiddleware,
		middleware.ProvideRateLimitMiddlewares,       // CWE-770: Registration and auth endpoints rate limiting
		middleware.ProvideSecurityHeadersMiddleware,
		middleware.ProvideRequestSizeLimitMiddleware, // CWE-770: Request size limits

		// Handler layer (internal/interface/http/handler/)
		healthcheck.ProvideHealthCheckHandler,
		gateway.ProvideRegisterHandler,
		gateway.ProvideLoginHandler,
		gateway.ProvideRefreshTokenHandler,
		gateway.ProvideHelloHandler,
		gateway.ProvideMeHandler,
		tenant.ProvideCreateHandler,
		tenant.ProvideGetHandler,
		user.ProvideCreateHandler,
		user.ProvideGetHandler,
		site.ProvideCreateHandler,
		site.ProvideGetHandler,
		site.ProvideListHandler,
		site.ProvideDeleteHandler,
		site.ProvideRotateAPIKeyHandler,
		site.ProvideVerifySiteHandler,
		plugin.ProvideStatusHandler,
		plugin.ProvidePluginVerifyHandler,
		plugin.ProvideVersionHandler,
		plugin.ProvideSyncPagesHandler,
		plugin.ProvideSearchPagesHandler,
		plugin.ProvideDeletePagesHandler,
		plugin.ProvideSyncStatusHandler,
		admin.ProvideUnlockAccountHandler, // CWE-307: Admin account unlock
		admin.ProvideAccountStatusHandler, // CWE-307: Admin account status check

		// Scheduler layer (internal/scheduler/)
		scheduler.ProvideQuotaResetScheduler,
		scheduler.ProvideIPCleanupScheduler, // CWE-359: IP cleanup for GDPR compliance

		// HTTP server (internal/interface/http/)
		http.ProvideServer,

		// Application
		ProvideApplication,
	)

	return nil, nil
}
