package middleware

import (
	"net/http"
	"strings"

	"metazone.cc/metalab/internal/common"
	"metazone.cc/metalab/internal/config"
	"metazone.cc/metalab/internal/model"
	"metazone.cc/metalab/internal/session"

	"github.com/gin-gonic/gin"
)

// MaintenanceMiddleware 维护模式中间件：维护期间仅站长（Owner）可访问
type MaintenanceMiddleware struct {
	cfg            *config.Config
	siteSettings   *config.SiteSettings
	sessionManager *session.Manager
}

// NewMaintenanceMiddleware 构造函数
func NewMaintenanceMiddleware(cfg *config.Config, siteSettings *config.SiteSettings, sm *session.Manager) *MaintenanceMiddleware {
	return &MaintenanceMiddleware{cfg: cfg, siteSettings: siteSettings, sessionManager: sm}
}

// Handler 返回 Gin 中间件处理函数
func (mm *MaintenanceMiddleware) Handler() gin.HandlerFunc {
	return func(c *gin.Context) {
		// 未启用维护模式 → 放行
		if !mm.siteSettings.IsMaintenanceEnabled() {
			c.Next()
			return
		}

		path := c.Request.URL.Path

		// 白名单：登录相关页面和 API 始终可访问
		if isMaintenanceWhitelist(path) {
			c.Next()
			return
		}

		// 读取 session cookie 并验证
		sid, err := c.Cookie(common.SessionCookieName)
		if err != nil || sid == "" {
			blockAccess(c, path)
			return
		}

		s, err := mm.sessionManager.Validate(sid)
		if err != nil || s == nil {
			blockAccess(c, path)
			return
		}

		if !model.HasMinRole(s.Role, model.RoleOwner) {
			blockAccess(c, path)
			return
		}

		c.Next()
	}
}

// isMaintenanceWhitelist 判断路径是否在维护白名单中
func isMaintenanceWhitelist(path string) bool {
	if path == "/auth/login" || strings.HasPrefix(path, "/api/auth/") {
		return true
	}
	if strings.HasPrefix(path, "/static/") || strings.HasPrefix(path, "/shared/") {
		return true
	}
	if path == "/favicon.ico" || path == "/favicon.svg" {
		return true
	}
	return false
}

// blockAccess 根据请求类型阻止访问
func blockAccess(c *gin.Context, path string) {
	if strings.HasPrefix(path, "/api/") || strings.HasPrefix(path, "/admin/api/") {
		c.AbortWithStatusJSON(http.StatusForbidden, gin.H{
			"success": false,
			"message": "社区正在维护中，仅站长可访问",
		})
		return
	}
	common.RedirectToLogin(c)
}
