package middleware

import (
	"github.com/gofiber/fiber/v2"
	"github.com/google/uuid"
	"gorm.io/gorm"
	customMiddleware "netidhub-saas-be/app/middleware"
)

// AddClientFilter adds client_id filter to GORM query
// Enhanced to support multi-client access and super admin
func AddClientFilter(db *gorm.DB, c *fiber.Ctx) *gorm.DB {
	if c == nil {
		return db
	}

	// Check if super admin
	if customMiddleware.IsSuperAdmin(c) {
		return db // No filtering for super admin
	}

	// Get accessible client IDs
	accessibleClientIDs := customMiddleware.GetAccessibleClientIDs(c)
	
	if accessibleClientIDs == nil {
		// Super admin or no restriction
		return db
	}

	if len(accessibleClientIDs) == 0 {
		// User has no client access - return empty result
		return db.Where("1 = 0")
	}

	if len(accessibleClientIDs) == 1 {
		// Single client access (backward compatible)
		return db.Where("client_id = ?", accessibleClientIDs[0])
	}

	// Multiple client access
	return db.Where("client_id IN ?", accessibleClientIDs)
}

// SetClientID sets client_id in the given struct if it has a ClientId field
// Uses the current working client ID from context
func SetClientID(c *fiber.Ctx, model interface{}) {
	if c == nil {
		return
	}
	
	// Try to get current client ID first (multi-client support)
	currentClientID := customMiddleware.GetCurrentClientID(c)
	if currentClientID != nil {
		if setter, ok := model.(interface{ SetClientID(*uuid.UUID) }); ok {
			setter.SetClientID(currentClientID)
		}
		return
	}
	
	// Fallback to old GetClientID (backward compatibility)
	clientID := customMiddleware.GetClientID(c)
	if clientID != nil {
		if setter, ok := model.(interface{ SetClientID(*uuid.UUID) }); ok {
			setter.SetClientID(clientID)
		}
	}
}

// ValidateClientAccess validates if the current user has access to a resource
// Enhanced to check against all accessible clients for multi-client users
func ValidateClientAccess(db *gorm.DB, c *fiber.Ctx, tableName string, resourceID interface{}) error {
	if c == nil {
		return nil // Skip validation for background jobs
	}

	// Super admin has access to everything
	if customMiddleware.IsSuperAdmin(c) {
		return nil
	}

	accessibleClientIDs := customMiddleware.GetAccessibleClientIDs(c)
	if accessibleClientIDs == nil {
		// Super admin case (should not reach here, but for safety)
		return nil
	}

	if len(accessibleClientIDs) == 0 {
		return fiber.NewError(fiber.StatusForbidden, "No client access configured")
	}

	var count int64
	var err error

	if len(accessibleClientIDs) == 1 {
		// Single client (backward compatible)
		err = db.Table(tableName).
			Where("id = ? AND client_id = ?", resourceID, accessibleClientIDs[0]).
			Count(&count).Error
	} else {
		// Multiple clients
		err = db.Table(tableName).
			Where("id = ? AND client_id IN ?", resourceID, accessibleClientIDs).
			Count(&count).Error
	}

	if err != nil {
		return err
	}

	if count == 0 {
		return fiber.NewError(fiber.StatusForbidden, "Access denied to this resource")
	}

	return nil
}

// FilterByCurrentClient filters query by the current working client only
// Different from AddClientFilter - this only filters by the ACTIVE client
func FilterByCurrentClient(db *gorm.DB, c *fiber.Ctx) *gorm.DB {
	if c == nil {
		return db
	}

	// Super admin with no specific client selected
	if customMiddleware.IsSuperAdmin(c) {
		currentClientID := customMiddleware.GetCurrentClientID(c)
		if currentClientID == nil {
			return db // No filter
		}
		return db.Where("client_id = ?", currentClientID)
	}

	// Regular user - filter by current client
	currentClientID := customMiddleware.GetCurrentClientID(c)
	if currentClientID != nil {
		return db.Where("client_id = ?", currentClientID)
	}

	return db
}
