Help with calculating rewards for addresses during transfer

I'm having trouble with working out how to calculate the reward and send the amount to the stakeholders. I can deploy to the initial wallet but it fails when I try to send any to another address. I used some of the code from this guide:
https://hackernoon.com/implementing-staking-in-solidity-1687302a82cf

Here's my code that I'm having trouble with:

contract CHAR is Context, IERC20, Ownable {
    using SafeMath for uint256;
    using Address for address;

    mapping (address => uint256) private _rOwned;
    mapping (address => uint256) private _tOwned;
    mapping (address => mapping (address => uint256)) private _allowances;

    mapping (address => bool) private _isExcluded;
    address[] private _excluded;
    
  address[] internal _stakeholders;
    address[] internal  stakeholders;
    mapping(address => uint256) internal stakes;
    mapping(address => uint256) internal rewards;
   
    uint256 private constant MAX = ~uint256(0);
    uint256 private constant _tTotal = 100 * 10**10 * 10**9;
    //uint256 private constant _tTotal = 100 * 10**9;
    uint256 private _rTotal = (MAX - (MAX % _tTotal));
    uint256 private _tFeeTotal;

    string private _name;
    string private _symbol;
    uint8 private _decimals = 9;
    address private charityWallet;

    constructor (string memory tokName, 
                string memory tokSymbol,
                address _charityWallet,
                address[] memory _initialWallets,
                uint[] memory _initialAmounts) {
        _rOwned[_msgSender()] = _rTotal;
        // Distribute to initial wallets
        for (uint i = 0; i < _initialWallets.length; i++) {
            // Determine how much to initially mint to each wallet and exclude them from the fee
           // _isExcluded[_initialWallets[i]] = true;
            _transfer(_msgSender(), _initialWallets[i], _initialAmounts[i] * 10**10 * 10**9);
        }
        stakeholders = _stakeholders;
        charityWallet = _charityWallet;
        _name = tokName;
        _symbol = tokSymbol;
        emit Transfer(address(0), _msgSender(), _tTotal);
    }

    function name() public view returns (string memory) {
        return _name;
    }

    function symbol() public view returns (string memory) {
        return _symbol;
    }

    function decimals() public view returns (uint8) {
        return _decimals;
    }

    function totalSupply() public pure override returns (uint256) {
        return _tTotal;
    }

    function balanceOf(address account) public view override returns (uint256) {
        if (_isExcluded[account]) return _tOwned[account];
        return tokenFromReflection(_rOwned[account]);
        
        
    }

    function transfer(address recipient, uint256 amount, address stakeholder, address _stakeholder) public override returns (bool) {
        uint charityFee = (amount * 3) / 100;
        uint amount1 = amount - charityFee;
        uint stakeFee = (amount * 3) / 100;
        uint amount2 = amount1 - stakeFee;
        
        //uint amount3 = (amount * 50) / 3;
        //uint amount4 = amount3 / 2;
        
        _transfer(_msgSender(), charityWallet, charityFee);
        amount -= charityFee;
        addStakeholder(recipient);
       // _stakeholder = stakeholders;
        // for (uint256 s = 0; s < stakeholders.length; s += 1){
        //address stakeholder = stakeholders;
        //calculateReward(stakeholder, stakeFee);
         //}
        
        uint256 _stakes = stakes[_stakeholder];
        //stakeholder_percent = _stakes * _totalStakes / stakeholders.length;
        uint256 stakeholder_percent1 = _stakes * totalStakes();
        uint256 stakeholder_percent2 = stakeholder_percent1 / stakeholders.length;
        uint stakeReward = stakeFee / stakeholder_percent2;
         
        //uint sendreward = calculateReward(stakeholder, stakeFee);
        address stakeholders = stakeholder;
         
        _transfer(_msgSender(), stakeholders, stakeReward);
        _transfer(_msgSender(), recipient, amount2);
        return true;
    }

I tried using the calculateRewards function first but couldn't figure it out so I tried doing the calculation in the transfer function:

function totalStakes() public view returns(uint256)
   {
       uint256 _totalStakes = 0;
       for (uint256 s = 0; s < stakeholders.length; s += 1){
           _totalStakes = _totalStakes.add(stakes[stakeholders[s]]);
       }
       return _totalStakes;
   }
    
    function calculateReward(address _stakeholder, uint256 stakeFee) public view returns(uint256)
   {
        uint256 _stakes = stakes[_stakeholder];
        //stakeholder_percent = _stakes * _totalStakes / stakeholders.length;
        uint256 stakeholder_percent1 = _stakes * totalStakes();
        uint256 stakeholder_percent2 = stakeholder_percent1 / stakeholders.length;
        uint stakeReward = stakeFee / stakeholder_percent2;
        
        return stakeReward;
   }

This post is missing a clear question so it’s difficult to answer.

Sorry. I was asking how I could calculate the percentage of tokens that an address holds from the total amount. And then send them the percentage of the tax.

Given that CHAR is IERC20, you have a balanceOf function, so to get the % that a certain address holds relative to the total supply, you could do balanceOf(msg.sender) / totalSupply().

Then, if you already have something like uint taxAmount = msg.value * taxInBasisPoints / 1000, you could then calculate the amount to send as taxAmount * balanceOf(msg.sender) / totalSupply().

Caution: You have to make sure that taxAmount * balanceOf(msg.sender) > totalSupply(), or else it will round to 0, as we have no decimals in the EVM.