package router

import (
	"time"

	"metazone.cc/metalab/internal/config"
	"metazone.cc/metalab/internal/controller"
	adminCtrl "metazone.cc/metalab/internal/controller/admin"
	"metazone.cc/metalab/internal/middleware"
	"metazone.cc/metalab/internal/repository"
	"metazone.cc/metalab/internal/service"
	"metazone.cc/metalab/internal/session"

	"gorm.io/gorm"
)

type dependencies struct {
	authCtrl        *controller.AuthController
	authMdw         *middleware.AuthMiddleware
	maintenanceMdw  *middleware.MaintenanceMiddleware
	settingsCtrl    *controller.SettingsController
	messageCtrl     *controller.MessageController
	postCtrl        *controller.PostController
	spaceCtrl       *controller.SpaceController
	studioCtrl      *controller.StudioController
	adminPostCtrl   *adminCtrl.AdminPostController
	adminCtrl       *adminCtrl.AdminController
	auditCtrl       *adminCtrl.AuditController
	siteSettingCtrl *adminCtrl.SiteSettingController
	tokenCtrl       *controller.AuthController
}

func buildDepsCore(db *gorm.DB, cfg *config.Config, siteSettings *config.SiteSettings) (
	*repository.UserRepo, *session.Manager, *service.AuthService,
	*middleware.RateLimiter, *controller.AuthController,
	*service.AvatarService, *middleware.AuthMiddleware, *adminCtrl.AdminController,
) {
	userRepo := repository.NewUserRepo(db)

	// Session 存储：内存模式（后续可切换为 RedisStore）
	sessionStore := session.NewMemoryStore(
		time.Duration(cfg.Session.IdleTimeout)*time.Minute,
		time.Duration(cfg.Session.RememberTimeout)*time.Minute,
	)
	// 启动后台过清理 goroutine
	sessionStore.StartCleanup(time.Duration(cfg.Session.CleanupInterval) * time.Second)

	sessionMgr := session.NewManager(sessionStore, userRepo, cfg)
	authService := service.NewAuthService(userRepo, sessionMgr, cfg, siteSettings)
	rateLimiter := middleware.NewRateLimiter()
	authCtrl := controller.NewAuthController(authService, sessionMgr, rateLimiter, cfg)
	avatarSvc := service.NewAvatarService(userRepo)
	authMdw := middleware.NewAuthMiddleware(cfg, sessionMgr)
	adminController := adminCtrl.NewAdminController(service.NewAdminService(userRepo, sessionMgr))
	return userRepo, sessionMgr, authService, rateLimiter, authCtrl, avatarSvc, authMdw, adminController
}
