package access

import (
	"errors"
	"sort"
	"strings"

	"github.com/tidbcloud/AgentTeam/internal/core/domain"
)

type PrincipalType string

const (
	PrincipalTypeUser    PrincipalType = "user"
	PrincipalTypeAgent   PrincipalType = "agent"
	PrincipalTypeMachine PrincipalType = "machine"
	PrincipalTypeService PrincipalType = "service"
)

type DecisionSource string

const (
	DecisionSourceSystemAdmin       DecisionSource = "system_admin"
	DecisionSourceWorkspaceRole     DecisionSource = "workspace_role"
	DecisionSourceChannelMembership DecisionSource = "channel_membership"
	DecisionSourceDMParticipant     DecisionSource = "dm_participant"
	DecisionSourceThreadInherit     DecisionSource = "thread_inherit"
	DecisionSourceAgentSelf         DecisionSource = "agent_self"
	DecisionSourceMachineSelf       DecisionSource = "machine_self"
	DecisionSourceServiceGrant      DecisionSource = "service_grant"
	DecisionSourceOrgGrant          DecisionSource = "org_grant"
)

type DenyCode string

const (
	DenyCodeUnauthenticated       DenyCode = "unauthenticated"
	DenyCodeNotInWorkspace        DenyCode = "not_in_workspace"
	DenyCodeWorkspaceAccessDenied DenyCode = "workspace_access_denied"
	DenyCodeNotChannelMember      DenyCode = "not_channel_member"
	DenyCodeNotDMParticipant      DenyCode = "not_dm_participant"
	DenyCodeThreadAccessDenied    DenyCode = "thread_access_denied"
	DenyCodeActAsForbidden        DenyCode = "act_as_forbidden"
	DenyCodeScopeMissing          DenyCode = "scope_missing"
)

type AuthorizationRequest struct {
	ActorPrincipalID   string
	ActorPrincipalType PrincipalType
	WorkspaceID        string
	ActorMemberID      string
	ResourceKind       ResourceKind
	ResourceID         string
	Action             Action
	ActAsPrincipalID   string
	ActAsMemberID      string
	InstallationID     string
	RequestedScopes    []string
	RequestID          string
}

type AuthorizationDecision struct {
	Allowed             bool
	DecisionSource      DecisionSource
	ResolvedPrincipalID string
	ResolvedMemberID    string
	Scopes              []string
	DenyCode            DenyCode
}

type AgentSelf struct {
	AgentID     string
	WorkspaceID string
	MemberID    string
}

type MachineSelf struct {
	MachineID   string
	WorkspaceID string
}

type SystemAdminPrincipal struct {
	UserID string
}

type ServiceInstallationGrant struct {
	PrincipalID    string
	WorkspaceID    string
	InstallationID string
	MemberID       string
	Scopes         []string
}

func NewHumanAuthorizationRequest(userID string, workspaceID string, memberID string, resourceID string, action HumanAction) AuthorizationRequest {
	trimmedUserID := strings.TrimSpace(userID)
	trimmedMemberID := strings.TrimSpace(memberID)
	return AuthorizationRequest{
		ActorPrincipalID:   trimmedUserID,
		ActorPrincipalType: PrincipalTypeUser,
		WorkspaceID:        strings.TrimSpace(workspaceID),
		ActorMemberID:      trimmedMemberID,
		ResourceKind:       action.Resource,
		ResourceID:         strings.TrimSpace(resourceID),
		Action:             action.Action,
		ActAsPrincipalID:   trimmedUserID,
		ActAsMemberID:      trimmedMemberID,
	}
}

func NewAgentSelfAuthorizationRequest(agentID string, workspaceID string, memberID string) AuthorizationRequest {
	trimmedAgentID := strings.TrimSpace(agentID)
	trimmedMemberID := strings.TrimSpace(memberID)
	return AuthorizationRequest{
		ActorPrincipalID:   trimmedAgentID,
		ActorPrincipalType: PrincipalTypeAgent,
		WorkspaceID:        strings.TrimSpace(workspaceID),
		ActorMemberID:      trimmedMemberID,
		ResourceKind:       ResourceAgent,
		ResourceID:         trimmedAgentID,
		Action:             ActionActAsMember,
		ActAsPrincipalID:   trimmedAgentID,
		ActAsMemberID:      trimmedMemberID,
	}
}

func NewMachineSelfAuthorizationRequest(machineID string, workspaceID string) AuthorizationRequest {
	trimmedMachineID := strings.TrimSpace(machineID)
	return AuthorizationRequest{
		ActorPrincipalID:   trimmedMachineID,
		ActorPrincipalType: PrincipalTypeMachine,
		WorkspaceID:        strings.TrimSpace(workspaceID),
		ResourceKind:       ResourceMachine,
		ResourceID:         trimmedMachineID,
		Action:             ActionConnect,
		ActAsPrincipalID:   trimmedMachineID,
	}
}

func NewSystemAdminWorkspaceAccessRequest(userID string, workspaceID string) AuthorizationRequest {
	trimmedUserID := strings.TrimSpace(userID)
	trimmedWorkspaceID := strings.TrimSpace(workspaceID)
	return AuthorizationRequest{
		ActorPrincipalID:   trimmedUserID,
		ActorPrincipalType: PrincipalTypeUser,
		WorkspaceID:        trimmedWorkspaceID,
		ResourceKind:       ResourceWorkspace,
		ResourceID:         trimmedWorkspaceID,
		Action:             ActionAccess,
		ActAsPrincipalID:   trimmedUserID,
	}
}

func NewServiceInstallationInvokeRequest(servicePrincipalID string, workspaceID string, installationID string, memberID string, requestedScopes []string) AuthorizationRequest {
	trimmedServicePrincipalID := strings.TrimSpace(servicePrincipalID)
	trimmedMemberID := strings.TrimSpace(memberID)
	trimmedInstallationID := strings.TrimSpace(installationID)
	return AuthorizationRequest{
		ActorPrincipalID:   trimmedServicePrincipalID,
		ActorPrincipalType: PrincipalTypeService,
		WorkspaceID:        strings.TrimSpace(workspaceID),
		ActorMemberID:      trimmedMemberID,
		ResourceKind:       ResourceServiceInstallation,
		ResourceID:         trimmedInstallationID,
		Action:             ActionInvoke,
		ActAsPrincipalID:   trimmedServicePrincipalID,
		ActAsMemberID:      trimmedMemberID,
		InstallationID:     trimmedInstallationID,
		RequestedScopes:    normalizeScopes(requestedScopes),
	}
}

func DecideHumanWorkspaceRoleAuthorization(membership HumanWorkspaceMember, request AuthorizationRequest) (AuthorizationDecision, error) {
	if err := validateHumanAuthorizationRequest(request); err != nil {
		return AuthorizationDecision{}, err
	}
	if err := validateActAsRequest(request, membership.Member.ID); err != nil {
		return deniedAuthorizationDecision(request, membership.Member.ID, DecisionSourceWorkspaceRole, DenyCodeActAsForbidden), err
	}

	action := HumanAction{Resource: request.ResourceKind, Action: request.Action}
	if err := AuthorizeWorkspaceRole(domain.WorkspaceRole(membership.WorkspaceRole), action); err != nil {
		if errors.Is(err, ErrForbidden) {
			return deniedAuthorizationDecision(request, membership.Member.ID, DecisionSourceWorkspaceRole, DenyCodeWorkspaceAccessDenied), err
		}
		return AuthorizationDecision{}, err
	}

	return allowedAuthorizationDecision(request, membership.Member.ID, DecisionSourceWorkspaceRole), nil
}

func DecideHumanChannelAuthorization(channelAccess HumanChannelAccess, request AuthorizationRequest) (AuthorizationDecision, error) {
	if err := validateHumanAuthorizationRequest(request); err != nil {
		return AuthorizationDecision{}, err
	}
	if err := validateActAsRequest(request, channelAccess.WorkspaceMember.Member.ID); err != nil {
		return deniedAuthorizationDecision(request, channelAccess.WorkspaceMember.Member.ID, DecisionSourceWorkspaceRole, DenyCodeActAsForbidden), err
	}

	action := HumanAction{Resource: request.ResourceKind, Action: request.Action}
	if err := AuthorizeHumanChannelAction(channelAccess, action); err != nil {
		if errors.Is(err, ErrForbidden) {
			return deniedAuthorizationDecision(request, channelAccess.WorkspaceMember.Member.ID, DecisionSourceChannelMembership, DenyCodeNotChannelMember), err
		}
		return AuthorizationDecision{}, err
	}

	return allowedAuthorizationDecision(request, channelAccess.WorkspaceMember.Member.ID, DecisionSourceChannelMembership), nil
}

func DecideHumanDMAuthorization(dmAccess HumanDMAccess, request AuthorizationRequest) (AuthorizationDecision, error) {
	if err := validateHumanAuthorizationRequest(request); err != nil {
		return AuthorizationDecision{}, err
	}
	if err := validateActAsRequest(request, dmAccess.WorkspaceMember.Member.ID); err != nil {
		return deniedAuthorizationDecision(request, dmAccess.WorkspaceMember.Member.ID, DecisionSourceWorkspaceRole, DenyCodeActAsForbidden), err
	}

	action := HumanAction{Resource: request.ResourceKind, Action: request.Action}
	if err := AuthorizeHumanDMAction(dmAccess, action); err != nil {
		if errors.Is(err, ErrForbidden) {
			return deniedAuthorizationDecision(request, dmAccess.WorkspaceMember.Member.ID, DecisionSourceDMParticipant, DenyCodeNotDMParticipant), err
		}
		return AuthorizationDecision{}, err
	}

	return allowedAuthorizationDecision(request, dmAccess.WorkspaceMember.Member.ID, DecisionSourceDMParticipant), nil
}

func DecideHumanThreadAuthorization(threadAccess HumanThreadAccess, request AuthorizationRequest) (AuthorizationDecision, error) {
	if err := validateHumanAuthorizationRequest(request); err != nil {
		return AuthorizationDecision{}, err
	}
	if err := validateActAsRequest(request, threadAccess.WorkspaceMember.Member.ID); err != nil {
		return deniedAuthorizationDecision(request, threadAccess.WorkspaceMember.Member.ID, DecisionSourceWorkspaceRole, DenyCodeActAsForbidden), err
	}

	action := HumanAction{Resource: request.ResourceKind, Action: request.Action}
	if err := AuthorizeHumanThreadAction(threadAccess, action); err != nil {
		if errors.Is(err, ErrForbidden) {
			return deniedAuthorizationDecision(request, threadAccess.WorkspaceMember.Member.ID, DecisionSourceThreadInherit, DenyCodeThreadAccessDenied), err
		}
		return AuthorizationDecision{}, err
	}

	return allowedAuthorizationDecision(request, threadAccess.WorkspaceMember.Member.ID, DecisionSourceThreadInherit), nil
}

func DecideHumanMachineAuthorization(machineAccess HumanMachineAccess, request AuthorizationRequest) (AuthorizationDecision, error) {
	if err := validateHumanAuthorizationRequest(request); err != nil {
		return AuthorizationDecision{}, err
	}
	if err := validateActAsRequest(request, machineAccess.WorkspaceMember.Member.ID); err != nil {
		return deniedAuthorizationDecision(request, machineAccess.WorkspaceMember.Member.ID, DecisionSourceWorkspaceRole, DenyCodeActAsForbidden), err
	}

	action := HumanAction{Resource: request.ResourceKind, Action: request.Action}
	if err := AuthorizeWorkspaceRole(domain.WorkspaceRole(machineAccess.WorkspaceMember.WorkspaceRole), action); err != nil {
		if errors.Is(err, ErrForbidden) {
			return deniedAuthorizationDecision(request, machineAccess.WorkspaceMember.Member.ID, DecisionSourceWorkspaceRole, DenyCodeWorkspaceAccessDenied), err
		}
		return AuthorizationDecision{}, err
	}

	return allowedAuthorizationDecision(request, machineAccess.WorkspaceMember.Member.ID, DecisionSourceWorkspaceRole), nil
}

func DecideHumanAgentAuthorization(agentAccess HumanAgentAccess, request AuthorizationRequest) (AuthorizationDecision, error) {
	if err := validateHumanAuthorizationRequest(request); err != nil {
		return AuthorizationDecision{}, err
	}
	if err := validateActAsRequest(request, agentAccess.WorkspaceMember.Member.ID); err != nil {
		return deniedAuthorizationDecision(request, agentAccess.WorkspaceMember.Member.ID, DecisionSourceWorkspaceRole, DenyCodeActAsForbidden), err
	}

	action := HumanAction{Resource: request.ResourceKind, Action: request.Action}
	if err := AuthorizeWorkspaceRole(domain.WorkspaceRole(agentAccess.WorkspaceMember.WorkspaceRole), action); err != nil {
		if errors.Is(err, ErrForbidden) {
			return deniedAuthorizationDecision(request, agentAccess.WorkspaceMember.Member.ID, DecisionSourceWorkspaceRole, DenyCodeWorkspaceAccessDenied), err
		}
		return AuthorizationDecision{}, err
	}

	return allowedAuthorizationDecision(request, agentAccess.WorkspaceMember.Member.ID, DecisionSourceWorkspaceRole), nil
}

func DecideAgentSelfAuthorization(agent AgentSelf, request AuthorizationRequest) (AuthorizationDecision, error) {
	if err := validateAgentSelfAuthorizationRequest(request); err != nil {
		return AuthorizationDecision{}, err
	}

	trimmedAgentID := strings.TrimSpace(agent.AgentID)
	trimmedWorkspaceID := strings.TrimSpace(agent.WorkspaceID)
	trimmedMemberID := strings.TrimSpace(agent.MemberID)

	if strings.TrimSpace(request.ActorPrincipalID) != trimmedAgentID ||
		strings.TrimSpace(request.WorkspaceID) != trimmedWorkspaceID ||
		strings.TrimSpace(request.ResourceID) != trimmedAgentID ||
		strings.TrimSpace(request.ActorMemberID) != trimmedMemberID ||
		strings.TrimSpace(request.ActAsPrincipalID) != trimmedAgentID ||
		strings.TrimSpace(request.ActAsMemberID) != trimmedMemberID {
		return deniedAuthorizationDecision(request, trimmedMemberID, DecisionSourceAgentSelf, DenyCodeActAsForbidden), ErrForbidden
	}

	return allowedAuthorizationDecision(request, trimmedMemberID, DecisionSourceAgentSelf), nil
}

func DecideMachineSelfAuthorization(machine MachineSelf, request AuthorizationRequest) (AuthorizationDecision, error) {
	if err := validateMachineSelfAuthorizationRequest(request); err != nil {
		return AuthorizationDecision{}, err
	}

	trimmedMachineID := strings.TrimSpace(machine.MachineID)
	trimmedWorkspaceID := strings.TrimSpace(machine.WorkspaceID)

	if strings.TrimSpace(request.ActorPrincipalID) != trimmedMachineID ||
		strings.TrimSpace(request.WorkspaceID) != trimmedWorkspaceID ||
		strings.TrimSpace(request.ResourceID) != trimmedMachineID ||
		strings.TrimSpace(request.ActAsPrincipalID) != trimmedMachineID {
		return deniedAuthorizationDecision(request, "", DecisionSourceMachineSelf, DenyCodeScopeMissing), ErrForbidden
	}

	return allowedAuthorizationDecision(request, "", DecisionSourceMachineSelf), nil
}

func DecideSystemAdminWorkspaceAccess(admin SystemAdminPrincipal, request AuthorizationRequest) (AuthorizationDecision, error) {
	if err := validateSystemAdminWorkspaceAccessRequest(request); err != nil {
		return AuthorizationDecision{}, err
	}

	if err := validateActAsRequest(request, ""); err != nil {
		return deniedAuthorizationDecision(request, "", DecisionSourceSystemAdmin, DenyCodeActAsForbidden), err
	}

	trimmedUserID := strings.TrimSpace(admin.UserID)
	if strings.TrimSpace(request.ActorPrincipalID) != trimmedUserID {
		return deniedAuthorizationDecision(request, "", DecisionSourceSystemAdmin, DenyCodeActAsForbidden), ErrForbidden
	}

	return allowedAuthorizationDecision(request, "", DecisionSourceSystemAdmin), nil
}

func DecideServiceInstallationAuthorization(grant ServiceInstallationGrant, request AuthorizationRequest) (AuthorizationDecision, error) {
	if err := validateServiceInstallationAuthorizationRequest(request); err != nil {
		return AuthorizationDecision{}, err
	}

	resolvedMemberID := resolveServiceInstallationMemberID(grant, request)
	if err := validateActAsRequest(request, strings.TrimSpace(grant.MemberID)); err != nil {
		return deniedAuthorizationDecision(request, resolvedMemberID, DecisionSourceServiceGrant, DenyCodeActAsForbidden), err
	}

	trimmedPrincipalID := strings.TrimSpace(grant.PrincipalID)
	trimmedWorkspaceID := strings.TrimSpace(grant.WorkspaceID)
	trimmedInstallationID := strings.TrimSpace(grant.InstallationID)
	if strings.TrimSpace(request.ActorPrincipalID) != trimmedPrincipalID ||
		strings.TrimSpace(request.WorkspaceID) != trimmedWorkspaceID ||
		strings.TrimSpace(request.ResourceID) != trimmedInstallationID ||
		strings.TrimSpace(request.InstallationID) != trimmedInstallationID {
		return deniedAuthorizationDecision(request, resolvedMemberID, DecisionSourceServiceGrant, DenyCodeScopeMissing), ErrForbidden
	}

	requestedScopes := normalizeScopes(request.RequestedScopes)
	grantedScopes := normalizeScopes(grant.Scopes)
	if !grantedScopesCoverRequested(grantedScopes, requestedScopes) {
		return deniedAuthorizationDecision(request, resolvedMemberID, DecisionSourceServiceGrant, DenyCodeScopeMissing), ErrForbidden
	}

	decision := allowedAuthorizationDecision(request, resolvedMemberID, DecisionSourceServiceGrant)
	decision.Scopes = requestedScopes
	return decision, nil
}

func validateHumanAuthorizationRequest(request AuthorizationRequest) error {
	if strings.TrimSpace(request.ActorPrincipalID) == "" {
		return invalidAuthorizationRequestFor(request.ResourceKind, request.Action)
	}
	if request.ActorPrincipalType != PrincipalTypeUser {
		return invalidAuthorizationRequestFor(request.ResourceKind, request.Action)
	}
	if strings.TrimSpace(request.WorkspaceID) == "" || strings.TrimSpace(request.ResourceID) == "" {
		return invalidAuthorizationRequestFor(request.ResourceKind, request.Action)
	}
	return nil
}

func validateAgentSelfAuthorizationRequest(request AuthorizationRequest) error {
	if strings.TrimSpace(request.ActorPrincipalID) == "" {
		return invalidAuthorizationRequestFor(request.ResourceKind, request.Action)
	}
	if request.ActorPrincipalType != PrincipalTypeAgent {
		return invalidAuthorizationRequestFor(request.ResourceKind, request.Action)
	}
	if strings.TrimSpace(request.WorkspaceID) == "" || strings.TrimSpace(request.ResourceID) == "" {
		return invalidAuthorizationRequestFor(request.ResourceKind, request.Action)
	}
	if request.ResourceKind != ResourceAgent || request.Action != ActionActAsMember {
		return invalidAuthorizationRequestFor(request.ResourceKind, request.Action)
	}
	return nil
}

func validateMachineSelfAuthorizationRequest(request AuthorizationRequest) error {
	if strings.TrimSpace(request.ActorPrincipalID) == "" {
		return invalidAuthorizationRequestFor(request.ResourceKind, request.Action)
	}
	if request.ActorPrincipalType != PrincipalTypeMachine {
		return invalidAuthorizationRequestFor(request.ResourceKind, request.Action)
	}
	if strings.TrimSpace(request.WorkspaceID) == "" || strings.TrimSpace(request.ResourceID) == "" {
		return invalidAuthorizationRequestFor(request.ResourceKind, request.Action)
	}
	if request.ResourceKind != ResourceMachine || request.Action != ActionConnect {
		return invalidAuthorizationRequestFor(request.ResourceKind, request.Action)
	}
	return nil
}

func validateSystemAdminWorkspaceAccessRequest(request AuthorizationRequest) error {
	if strings.TrimSpace(request.ActorPrincipalID) == "" {
		return invalidAuthorizationRequestFor(request.ResourceKind, request.Action)
	}
	if request.ActorPrincipalType != PrincipalTypeUser {
		return invalidAuthorizationRequestFor(request.ResourceKind, request.Action)
	}
	if strings.TrimSpace(request.WorkspaceID) == "" || strings.TrimSpace(request.ResourceID) == "" {
		return invalidAuthorizationRequestFor(request.ResourceKind, request.Action)
	}
	if request.ResourceKind != ResourceWorkspace || request.Action != ActionAccess {
		return invalidAuthorizationRequestFor(request.ResourceKind, request.Action)
	}
	if strings.TrimSpace(request.ResourceID) != strings.TrimSpace(request.WorkspaceID) {
		return invalidAuthorizationRequestFor(request.ResourceKind, request.Action)
	}
	return nil
}

func validateServiceInstallationAuthorizationRequest(request AuthorizationRequest) error {
	if strings.TrimSpace(request.ActorPrincipalID) == "" {
		return invalidAuthorizationRequestFor(request.ResourceKind, request.Action)
	}
	if request.ActorPrincipalType != PrincipalTypeService {
		return invalidAuthorizationRequestFor(request.ResourceKind, request.Action)
	}
	if strings.TrimSpace(request.WorkspaceID) == "" ||
		strings.TrimSpace(request.ResourceID) == "" ||
		strings.TrimSpace(request.InstallationID) == "" {
		return invalidAuthorizationRequestFor(request.ResourceKind, request.Action)
	}
	if request.ResourceKind != ResourceServiceInstallation || request.Action != ActionInvoke {
		return invalidAuthorizationRequestFor(request.ResourceKind, request.Action)
	}
	if strings.TrimSpace(request.ResourceID) != strings.TrimSpace(request.InstallationID) {
		return invalidAuthorizationRequestFor(request.ResourceKind, request.Action)
	}
	if len(normalizeScopes(request.RequestedScopes)) == 0 {
		return invalidAuthorizationRequestFor(request.ResourceKind, request.Action)
	}
	return nil
}

func validateActAsRequest(request AuthorizationRequest, expectedMemberID string) error {
	if trimmedActorMemberID := strings.TrimSpace(request.ActorMemberID); trimmedActorMemberID != "" && trimmedActorMemberID != expectedMemberID {
		return ErrForbidden
	}
	if trimmedActAsPrincipalID := strings.TrimSpace(request.ActAsPrincipalID); trimmedActAsPrincipalID != "" && trimmedActAsPrincipalID != strings.TrimSpace(request.ActorPrincipalID) {
		return ErrForbidden
	}
	if trimmedActAsMemberID := strings.TrimSpace(request.ActAsMemberID); trimmedActAsMemberID != "" && trimmedActAsMemberID != expectedMemberID {
		return ErrForbidden
	}
	return nil
}

func allowedAuthorizationDecision(request AuthorizationRequest, resolvedMemberID string, source DecisionSource) AuthorizationDecision {
	return AuthorizationDecision{
		Allowed:             true,
		DecisionSource:      source,
		ResolvedPrincipalID: strings.TrimSpace(request.ActorPrincipalID),
		ResolvedMemberID:    strings.TrimSpace(resolvedMemberID),
	}
}

func deniedAuthorizationDecision(request AuthorizationRequest, resolvedMemberID string, source DecisionSource, code DenyCode) AuthorizationDecision {
	decision := allowedAuthorizationDecision(request, resolvedMemberID, source)
	decision.Allowed = false
	decision.DenyCode = code
	return decision
}

func grantedScopesCoverRequested(grantedScopes []string, requestedScopes []string) bool {
	if len(requestedScopes) == 0 {
		return false
	}
	granted := make(map[string]struct{}, len(grantedScopes))
	for _, scope := range grantedScopes {
		granted[scope] = struct{}{}
	}
	for _, scope := range requestedScopes {
		if _, ok := granted[scope]; !ok {
			return false
		}
	}
	return true
}

func normalizeScopes(scopes []string) []string {
	if len(scopes) == 0 {
		return nil
	}

	normalized := make([]string, 0, len(scopes))
	seen := make(map[string]struct{}, len(scopes))
	for _, scope := range scopes {
		trimmedScope := strings.TrimSpace(scope)
		if trimmedScope == "" {
			continue
		}
		if _, ok := seen[trimmedScope]; ok {
			continue
		}
		seen[trimmedScope] = struct{}{}
		normalized = append(normalized, trimmedScope)
	}
	sort.Strings(normalized)
	if len(normalized) == 0 {
		return nil
	}
	return normalized
}

func resolveServiceInstallationMemberID(grant ServiceInstallationGrant, request AuthorizationRequest) string {
	if trimmedMemberID := strings.TrimSpace(grant.MemberID); trimmedMemberID != "" {
		return trimmedMemberID
	}
	if trimmedMemberID := strings.TrimSpace(request.ActAsMemberID); trimmedMemberID != "" {
		return trimmedMemberID
	}
	return strings.TrimSpace(request.ActorMemberID)
}
