// codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/interface/http/middleware/utils.go
package middleware

import (
	"regexp"

	"go.uber.org/zap"
)

type protectedRoute struct {
	pattern string
	regex   *regexp.Regexp
}

var (
	exactPaths    = make(map[string]bool)
	patternRoutes []protectedRoute
)

func init() {
	// Exact matches
	exactPaths = map[string]bool{
		"/api/v1/me":                        true,
		"/api/v1/me/delete":                 true,
		"/api/v1/me/blocked-emails":         true,
		"/api/v1/me/email/change-request":   true, // Email change step 1: request
		"/api/v1/me/email/change-verify":    true, // Email change step 2: verify
		"/api/v1/dashboard":                 true,
		"/api/v1/collections":          true,
		"/api/v1/collections/filtered": true,
		"/api/v1/collections/root":     true,
		"/api/v1/collections/shared":   true,
		"/api/v1/collections/sync":     true, // Sync collections endpoint
		"/api/v1/files":                true,
		"/api/v1/files/pending":        true, // Three-step workflow file-create endpoint: Start
		"/api/v1/files/recent":         true,
		"/api/v1/files/sync":           true, // Sync files endpoint
		"/api/v1/files/delete-multiple": true, // Delete multiple files endpoint
		"/api/v1/invites/send-email":   true, // Send invitation email to non-registered user
		"/api/v1/tags":                 true, // List and create tags
		"/api/v1/tags/search":          true, // Search by tags
		"/iam/api/v1/users/lookup":     true, // User public key lookup (requires auth)
	}

	// Pattern matches
	patterns := []string{
		// Blocked Email patterns
		"^/api/v1/me/blocked-emails/[^/]+$", // Delete specific blocked email

		// Collection patterns (plural routes)
		"^/api/v1/collections/[a-zA-Z0-9-]+$",           // Individual collection operations
		"^/api/v1/collections/[a-zA-Z0-9-]+/move$",                       // Move collection
		"^/api/v1/collections/[a-zA-Z0-9-]+/share$",                      // Share collection
		"^/api/v1/collections/[a-zA-Z0-9-]+/members$",                    // Collection members
		"^/api/v1/collections/[a-zA-Z0-9-]+/members/[a-zA-Z0-9-]+$",      // Remove specific member
		"^/api/v1/collections/[a-zA-Z0-9-]+/archive$",                    // Archive collection
		"^/api/v1/collections/[a-zA-Z0-9-]+/restore$",                    // Restore collection
		"^/api/v1/collections-by-parent/[a-zA-Z0-9-]+$", // Collections by parent

		// Collection patterns (singular routes for files)
		"^/api/v1/collection/[a-zA-Z0-9-]+/files$",      // Collection files (singular)

		// File patterns (singular routes)
		"^/api/v1/file/[a-zA-Z0-9-]+$",               // Individual file operations
		"^/api/v1/file/[a-zA-Z0-9-]+/data$",          // File data
		"^/api/v1/file/[a-zA-Z0-9-]+/upload-url$",    // File upload URL
		"^/api/v1/file/[a-zA-Z0-9-]+/download-url$",  // File download URL
		"^/api/v1/file/[a-zA-Z0-9-]+/complete$",      // Complete file upload
		"^/api/v1/file/[a-zA-Z0-9-]+/archive$",       // Archive file
		"^/api/v1/file/[a-zA-Z0-9-]+/restore$",       // Restore file

		// Tag patterns
		"^/api/v1/tags/[a-zA-Z0-9-]+$",                                       // Individual tag operations (GET, PUT, DELETE)
		"^/api/v1/tags/[a-zA-Z0-9-]+/assign$",                                // Assign tag to entity
		"^/api/v1/tags/[a-zA-Z0-9-]+/entities/[a-zA-Z0-9-]+$",                // Unassign tag from entity
		"^/api/v1/tags/for/collection/[a-zA-Z0-9-]+$",                        // Get tags for collection
		"^/api/v1/tags/for/file/[a-zA-Z0-9-]+$",                              // Get tags for file
		"^/api/v1/tags/collections$",                                         // List collections by tag
		"^/api/v1/tags/files$",                                               // List files by tag
	}

	// Precompile patterns
	patternRoutes = make([]protectedRoute, len(patterns))
	for i, pattern := range patterns {
		patternRoutes[i] = protectedRoute{
			pattern: pattern,
			regex:   regexp.MustCompile(pattern),
		}
	}
}

func isProtectedPath(logger *zap.Logger, path string) bool {
	// Check exact matches first (O(1) lookup)
	if exactPaths[path] {
		logger.Debug("✅ found via map - url is protected",
			zap.String("path", path))
		return true
	}

	// Check patterns
	for _, route := range patternRoutes {
		if route.regex.MatchString(path) {
			logger.Debug("✅ found via regex - url is protected",
				zap.String("path", path))
			return true
		}
	}

	logger.Debug("❌ not found",
		zap.String("path", path))

	return false
}
