I need a review and some fix to this smart contract

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PausableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20VotesUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20FlashMintUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";

contract BlackNaga is
    Initializable,
    ERC20BurnableUpgradeable,
    ERC20PausableUpgradeable,
    OwnableUpgradeable,
    ERC20PermitUpgradeable,
    ERC20VotesUpgradeable,
    ERC20FlashMintUpgradeable
{
    // Mapping to store nonces for permit function
    mapping(address => uint256) public nonces;

    // Addresses for tokenomics and limits
    address public constant BURN_ADDRESS = 0x000000000000000000000000000000000000dEaD;
    address public marketingDevAddress;
    address public reflectionAddress;
    address public teamDevelopmentAddress;
    address public charityAddress;

    // Tokenomics parameters
    uint256 public burnPercent;
    uint256 public marketingDevFeePercent;
    uint256 public reflectionFeePercent;
    uint256 public charityFeePercent;
    uint256 public teamDevelopmentFeePercent;

    // Limits and balances
    uint256 public maxTransactionAmount;
    uint256 public maxBurnAmount;
    uint256 public maxWalletBalance;

    // Events
    event MaxTransactionAmountChanged(uint256 newMaxTransactionAmount);
    event MaxWalletBalanceChanged(uint256 newMaxWalletBalance);

    /**
     * @dev Constructor function to disable initializers and setup the BlackNaga token.
     */
    constructor() {
        _disableInitializers();
    }

    /**
     * @dev Initializes the contract with initial parameters and sets the token name and symbol.
     * @param initialOwner The initial owner of the contract.
     */
    function initialize(address initialOwner) external initializer {
        __ERC20Burnable_init();
        __ERC20Pausable_init();
        __Ownable_init(initialOwner);
        __ERC20Permit_init("BlackNaga");
        __ERC20Votes_init();
        __ERC20FlashMint_init();

        string memory name = "BlackNaga";
        string memory symbol = "BLNA";
        uint256 initialSupply = 400_000_000_000_000_000_000_000; // 400 sextillion tokens with 18 decimals
        uint256 tokensToBurn = initialSupply / 2; // Burn 50% of the initial supply

        _mint(initialOwner, initialSupply); // Mint initial supply to the deployer
        _burn(initialOwner, tokensToBurn); // Burn tokens immediately

        // Set initial values for tokenomics
        burnPercent = 5;
        marketingDevFeePercent = 2;
        reflectionFeePercent = 2;
        charityFeePercent = 1;
        teamDevelopmentFeePercent = 2;

        // Set initial limits and balances
        maxTransactionAmount = initialSupply / 100; // 1% of total supply
        maxBurnAmount = 200_000_000_000_000_000_000_000; // 200 sextillion tokens
        maxWalletBalance = initialSupply; // 100% of total supply

        // Initialize fee addresses
        marketingDevAddress = 0xfeB4660C633beE5ecE0955e3330B4619923B6d7C;
        reflectionAddress = 0x81B6777039559c7396938ED17Ba39e71cE740cE7;
        teamDevelopmentAddress = 0x10a0FF128b37176277EC259E2CC469cD3cd10276;
        charityAddress = 0xD1b3A8E763d6c36d57BF9696a8595402BD54120E;

        // Ensure addresses are set correctly
        require(marketingDevAddress != address(0), "Invalid marketingDevAddress");
        require(reflectionAddress != address(0), "Invalid reflectionAddress");
        require(teamDevelopmentAddress != address(0), "Invalid teamDevelopmentAddress");
        require(charityAddress != address(0), "Invalid charityAddress");

        transferOwnership(initialOwner);
    }

    /**
     * @dev Sets the maximum transaction amount allowed.
     * @param amount The new maximum transaction amount.
     */
    function setMaxTransactionAmount(uint256 amount) external onlyOwner {
        require(amount > 0, "Max transaction amount must be greater than zero");
        maxTransactionAmount = amount;
        emit MaxTransactionAmountChanged(amount);
    }

    /**
     * @dev Sets the maximum wallet balance allowed.
     * @param balance The new maximum wallet balance.
     */
    function setMaxWalletBalance(uint256 balance) external onlyOwner {
        require(balance > 0, "Max wallet balance must be greater than zero");
        maxWalletBalance = balance;
        emit MaxWalletBalanceChanged(balance);
    }

    /**
     * @dev Transfers ownership of the contract.
     * @param newOwner The address of the new owner.
     */
    function transferOwnership(address newOwner) public override onlyOwner {
        require(newOwner != address(0), "New owner is the zero address");
        emit OwnershipTransferred(owner(), newOwner);
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers tokens from sender to recipient with specific logic for fees and burning.
     * @param sender The address sending the tokens.
     * @param recipient The address receiving the tokens.
     * @param amount The amount of tokens to transfer.
     */
    function _customTransfer(
        address sender,
        address recipient,
        uint256 amount
    ) internal {
        require(sender != address(0), "Transfer from the zero address");
        require(recipient != address(0), "Transfer to the zero address");
        require(amount > 0, "Transfer amount must be greater than zero");
        require(
            amount <= maxTransactionAmount,
            "Transfer amount exceeds the max transaction limit"
        );
        require(
            recipient.code.length == 0,
            "Transfer to a contract address is not allowed"
        );

        uint256 senderBalance = balanceOf(sender);
        require(senderBalance >= amount, "Transfer amount exceeds balance");

        if (sender != owner() && recipient != owner()) {
            require(
                balanceOf(recipient) + amount <= maxWalletBalance,
                "Transfer amount exceeds the max wallet balance"
            );
        }

        uint256 burnAmount = (amount * burnPercent) / 100;
        uint256 marketingDevFee = (amount * marketingDevFeePercent) / 100;
        uint256 reflectionFee = (amount * reflectionFeePercent) / 100;
        uint256 charityFee = (amount * charityFeePercent) / 100;
        uint256 teamDevelopmentFee = (amount * teamDevelopmentFeePercent) / 100;

        uint256 transferAmount = amount -
            (burnAmount +
                marketingDevFee +
                reflectionFee +
                charityFee +
                teamDevelopmentFee);

        unchecked {
            _transfer(sender, recipient, transferAmount);
            _transfer(sender, BURN_ADDRESS, burnAmount);
            _transfer(sender, marketingDevAddress, marketingDevFee);
            _transfer(sender, reflectionAddress, reflectionFee);
            _transfer(sender, charityAddress, charityFee);
            _transfer(sender, teamDevelopmentAddress, teamDevelopmentFee);
        }
    }

    // Additional functions and events as needed...
}