package auth

import (
	"context"
	"errors"
)

// contextKey is the type for context keys in this package
type contextKey string

const (
	userKey contextKey = "user"
)

// UserContext represents the authenticated user in context
type UserContext struct {
	ID          uint
	Email       string
	Roles       []RoleClaim
	Permissions []string
}

// WithUser adds a user to the context
func WithUser(ctx context.Context, user *UserContext) context.Context {
	return context.WithValue(ctx, userKey, user)
}

// CurrentUser retrieves the user from context
func CurrentUser(ctx context.Context) (*UserContext, error) {
	user, ok := ctx.Value(userKey).(*UserContext)
	if !ok {
		return nil, errors.New("no user in context")
	}
	return user, nil
}

// HasPermission checks if the current user has a specific permission
func HasPermission(ctx context.Context, permissionCode string) bool {
	user, err := CurrentUser(ctx)
	if err != nil {
		return false
	}
	for _, perm := range user.Permissions {
		if perm == permissionCode {
			return true
		}
	}
	return false
}

// HasAnyPermission checks if the current user has any of the specified permissions
func HasAnyPermission(ctx context.Context, permissionCodes ...string) bool {
	user, err := CurrentUser(ctx)
	if err != nil {
		return false
	}
	permSet := make(map[string]bool)
	for _, perm := range user.Permissions {
		permSet[perm] = true
	}
	for _, code := range permissionCodes {
		if permSet[code] {
			return true
		}
	}
	return false
}

// IsAuthenticated checks if there's an authenticated user in context
func IsAuthenticated(ctx context.Context) bool {
	_, err := CurrentUser(ctx)
	return err == nil
}
