Function Clone-UserGroups {
    <#
    .SYNOPSIS
        Clones security group memberships from one user to another.

    .DESCRIPTION
        Compares the McGuire AFB security group memberships of a source
        (primary) user and a target (clone) user. Any groups the primary user
        belongs to that the clone user does not are added to the clone user
        via DRA.

    .PARAMETER PrimaryUser
        The source user whose group memberships will be copied.

    .PARAMETER CloneUser
        The target user(s) who will receive the new group memberships. Accepts
        an array or comma-separated string.

    .PARAMETER GroupOUFilter
        DistinguishedName fragment used to limit which groups are copied.
        Defaults to config.json ActiveDirectory.DefaultLocation.

    .EXAMPLE
        Clone-UserGroups -PrimaryUser 'Doe.John' -CloneUser 'Smith.Jane'
        Copies all McGuire AFB group memberships from John Doe to Jane Smith.
    #>
    [CmdletBinding(SupportsShouldProcess=$true)]
    param(
        [Parameter(Mandatory=$true, Position=0)]
        [string]$PrimaryUser,

        [Parameter(Mandatory=$true, Position=1)]
        [string[]]$CloneUser,

        [Parameter(Position=2)]
        [string]$GroupOUFilter
    )

    Process {
        $cloneUsers = @(Split-ToolArgumentList -Value $CloneUser)
        if ($cloneUsers.Count -eq 0) {
            Write-Error "At least one CloneUser is required."
            return
        }
        if ([string]::IsNullOrWhiteSpace($GroupOUFilter)) {
            $location = if ($Global:AppConfig.ActiveDirectory.DefaultLocation) { [string]$Global:AppConfig.ActiveDirectory.DefaultLocation } else { 'McGuire AFB' }
            $GroupOUFilter = "OU=$location"
        }

        try {
            $primaryAdUser = Get-ToolADUser -Identity $PrimaryUser -Properties MemberOf -ErrorAction Stop
        }
        catch {
            Write-Error "Could not resolve primary user '$PrimaryUser' in Active Directory. Error: $($_.Exception.Message)"
            return
        }

        # Collect configured OU-specific groups for the primary user.
        $primaryGroups = @()
        foreach ($groupDN in $primaryAdUser.MemberOf) {
            $groupObj = Get-ToolADGroup $groupDN -ErrorAction SilentlyContinue
            if ($groupObj -and $groupObj.DistinguishedName -like "*$GroupOUFilter*") {
                $primaryGroups += [pscustomobject]@{
                    Name           = [string]$groupObj.Name
                    SamAccountName = if ($groupObj.SamAccountName) { [string]$groupObj.SamAccountName } else { [string]$groupObj.Name }
                }
            }
        }

        if ($primaryGroups.Count -eq 0) {
            Write-Verbose "'$PrimaryUser' has no groups matching '$GroupOUFilter'."
            return
        }

        foreach ($targetUser in $cloneUsers) {
            try {
                $cloneAdUser = Get-ToolADUser -Identity $targetUser -Properties MemberOf -ErrorAction Stop
            }
            catch {
                Write-Warning "Could not resolve clone user '$targetUser' in Active Directory. Error: $($_.Exception.Message)"
                continue
            }

            $cloneGroups = @()
            foreach ($groupDN in $cloneAdUser.MemberOf) {
                $groupObj = Get-ToolADGroup $groupDN -ErrorAction SilentlyContinue
                if ($groupObj -and $groupObj.DistinguishedName -like "*$GroupOUFilter*") {
                    $cloneGroups += if ($groupObj.SamAccountName) { [string]$groupObj.SamAccountName } else { [string]$groupObj.Name }
                }
            }

            # Determine which groups the clone user is missing
            $missingGroups = @($primaryGroups | Where-Object { $_.SamAccountName -notin $cloneGroups })

            if ($missingGroups.Count -eq 0) {
                Write-Verbose "'$targetUser' already belongs to all '$GroupOUFilter' groups that '$PrimaryUser' is a member of."
                continue
            }

            $missingGroupNames = @($missingGroups | ForEach-Object { $_.SamAccountName })
            Write-Verbose "Adding '$targetUser' to $($missingGroupNames.Count) missing group(s): $($missingGroupNames -join ', ')"

            if ($pscmdlet.ShouldProcess($targetUser, "Clone groups from $PrimaryUser")) {
                Add-MemberToGroup -UserName $targetUser -GroupName $missingGroupNames -ErrorAction Stop
                $cloneDisplayName = $cloneAdUser.Name
                Write-Output "$cloneDisplayName has been added to the following groups: $($missingGroupNames -join ', ')"
            }
        }
    }
}
