package router

import (
	"log"
	"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"

	"github.com/redis/go-redis/v9"
	"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
}

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

	idleTimeout := time.Duration(cfg.Session.IdleTimeout) * time.Minute
	rememberTimeout := time.Duration(cfg.Session.RememberTimeout) * time.Minute
	cleanupInterval := time.Duration(cfg.Session.CleanupInterval) * time.Second

	// 总是创建 MemoryStore 作为兜底
	memStore := session.NewMemoryStore(idleTimeout, rememberTimeout)
	memStore.StartCleanup(cleanupInterval)

	var sessionStore session.Store

	if cfg.Redis.Enabled && redisClient != nil {
		// Redis 模式 + 自动降级保护
		redisStore := session.NewRedisStore(redisClient, idleTimeout, rememberTimeout)
		sessionStore = session.NewFallbackStore(redisStore, memStore)
		log.Println("[Router] 会话存储: Redis（带内存降级保护）")
	} else {
		// 纯内存模式
		sessionStore = memStore
		log.Println("[Router] 会话存储: 内存")
	}

	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)
	return userRepo, sessionMgr, authService, rateLimiter, authCtrl, avatarSvc, authMdw
}
