package permissions

import (
	"context"

	"github.com/nexuscrm/shared/pkg/models"
)

// ListSystemPermissions returns the full platform permission catalog from
// _System_Permission rows. Adding a permission is a pack or row edit,
// not a backend release.
func (s *PermissionService) ListSystemPermissions(ctx context.Context) ([]models.SystemPermission, error) {
	return s.repo.ListSystemPermissions(ctx)
}

// --- Custom Permission CRUD ---

func (s *PermissionService) ListCustomPermissions(ctx context.Context) ([]models.SystemCustomPermission, error) {
	return s.repo.ListCustomPermissions(ctx)
}

func (s *PermissionService) GetCustomPermission(ctx context.Context, id string) (*models.SystemCustomPermission, error) {
	return s.repo.GetCustomPermission(ctx, id)
}

func (s *PermissionService) CreateCustomPermission(ctx context.Context, perm *models.SystemCustomPermission) error {
	return s.repo.CreateCustomPermission(ctx, perm)
}

func (s *PermissionService) UpdateCustomPermission(ctx context.Context, perm *models.SystemCustomPermission) error {
	return s.repo.UpdateCustomPermission(ctx, perm)
}

func (s *PermissionService) DeleteCustomPermission(ctx context.Context, id string) error {
	return s.repo.DeleteCustomPermission(ctx, id)
}

// HasPermission is the unified permission check: a user has the permission
// if it's granted either as a platform permission (Go-enum catalog, CRUD-
// level) or as a custom permission (admin-authored row in
// _System_CustomPermission). ModifyAllData is a data capability, not a
// wildcard for arbitrary system or custom permissions.
// Policy-level permissions ship as custom-permission rows declared inline on
// the action's JSON — no Go enum entry needed.
func (s *PermissionService) HasPermission(ctx context.Context, user *models.UserSession, apiName string) bool {
	if s == nil || user == nil {
		return false
	}
	if s.CheckSystemPermission(ctx, user, apiName) {
		return true
	}
	if effective, ok := s.cachedCustomPermissions(ctx, user.ID, user.ProfileID); ok {
		return effective[apiName]
	}
	effective, err := s.GetEffectiveCustomPermissions(ctx, user.ID, user.ProfileID)
	if err != nil {
		return false
	}
	return effective[apiName]
}
