contract TokenismAdminWhitelist is Context {
    using Roles for Roles.Role;
    Roles.Role private _managerWhitelisteds;

    //  Add multiple admins option
     mapping(address => string) public admins;
     address superAdmin;
     address feeAddress;

     //  Setting FeeStatus and fee Percent by Tokenism
    //  uint8 feeStatus;
    //  uint8 feePercent;
    bool public accreditationCheck = true;

    struct whitelistInfoManager {
        address wallet;
        string role;
        bool valid;
    }

    mapping(address => whitelistInfoManager) whitelistManagers;

     constructor() public {
        // admin = _msgSender();
        
        admins[_msgSender()] = "superAdmin";
        superAdmin = msg.sender;
       
    }
    function addSuperAdmin(address _superAdmin) public {

         require(msg.sender == superAdmin, "Only super admin can add admin");
         admins[_superAdmin] = "superAdmin";
         admins[superAdmin] = "dev";
         superAdmin = _superAdmin;
        
    }

    modifier onlyAdmin() {
       require(
          StringUtils.equal(admins[_msgSender()], "superAdmin") ||
          StringUtils.equal(admins[_msgSender()], "dev") ||
          StringUtils.equal(admins[_msgSender()], "fee") ||
          StringUtils.equal(admins[_msgSender()], "admin"),
                "Only admin is allowed"
        );
         _;
    }

    modifier onlyManager() {
    require(
            isWhitelistedManager(_msgSender()) || 
             StringUtils.equal(admins[_msgSender()], "superAdmin") ||
             StringUtils.equal(admins[_msgSender()], "dev") ||
             StringUtils.equal(admins[_msgSender()], "fee") ||
             StringUtils.equal(admins[_msgSender()], "admin"),
            "TokenismAdminWhitelist: caller does not have the Manager role"
        );
        _;
    }
    // Update Accredential Status
    function updateAccreditationCheck(bool status) public onlyManager {
        accreditationCheck = status;
    }

    // Roles
    function addWhitelistedManager(address _wallet, string memory _role)
        public
        onlyAdmin
    {
        require(
            StringUtils.equal(_role, "finance") ||
            StringUtils.equal(_role, "signer") ||
                StringUtils.equal(_role, "assets"),
            "TokenismAdminWhitelist: caller does not have the Manager role"
        );

        whitelistInfoManager storage newManager = whitelistManagers[_wallet];

        _managerWhitelisteds.add(_wallet);
        newManager.wallet = _wallet;
        newManager.role = _role;
        newManager.valid = true;
    }

    function getManagerRole(address _wallet)
        public
        view
        returns (string memory)
    {
        whitelistInfoManager storage m = whitelistManagers[_wallet];
        return m.role;
    }

    function updateRoleManager(address _wallet, string memory _role)
        public
        onlyAdmin
    {
         require(
            StringUtils.equal(_role, "finance") ||
            StringUtils.equal(_role, "signer") ||
                StringUtils.equal(_role, "assets"),
            "TokenismAdminWhitelist: Invalid  Manager role"
        );
        whitelistInfoManager storage m = whitelistManagers[_wallet];
        m.role = _role;
    }

    function isWhitelistedManager(address _wallet) public view returns (bool) {
        whitelistInfoManager memory m = whitelistManagers[_wallet];

        if (  StringUtils.equal(admins[_wallet], "superAdmin") ||
              StringUtils.equal(admins[_wallet], "dev") ||
              StringUtils.equal(admins[_wallet], "fee") ||
             StringUtils.equal(admins[_wallet], "admin")) return true;
        else if (!m.valid) return false;
        else return true;
    }

    // Only Super Admin
    function removeWhitelistedManager(address _wallet) public onlyAdmin {
        _managerWhitelisteds.remove(_wallet);
        whitelistInfoManager storage m = whitelistManagers[_wallet];
        m.valid = false;
    }

    function transferOwnership(address  _newAdmin)
        public
        returns (bool)
    {
        // admin = _newAdmin;
        require(_msgSender() == superAdmin, "Only super admin can add admin");
         admins[_newAdmin] = "superAdmin";
         admins[superAdmin] = "";
         superAdmin = _newAdmin;

        return true;
    }
    function addAdmin(address  _newAdmin, string memory _role)
    public
    onlyAdmin
    returns (bool)
    {
        
    require(_msgSender() == superAdmin || Address.isContract(_newAdmin) , "Only super admin can add admin");
    require(
              StringUtils.equal(_role, "dev") ||
              StringUtils.equal(_role, "fee") ||
              StringUtils.equal(_role, "admin"),
             "undefind admin role"
             );
        admins[_newAdmin] = _role;
        return true;
    }

   // Function Add Fee Address 
   function addFeeAddress(address _feeAddress) public {
       require(_msgSender() == superAdmin, "Only super admin can add Fee Address");
      feeAddress = _feeAddress;
   }
   function getFeeAddress()public view returns(address){
       return feeAddress;
   } 

    // // Fee On off functionality
    // function setFeeStatus(uint8 option) public returns(bool){ // Fee option must be 0, 1
    //     require(msg.sender == superAdmin, "Only SuperAdmin on off fee");
    //     require(option == 1 || option == 0, "Wrong option call only 1 for on and 0 for off");
    //     require(feePercent > 0, "addPlatformFee! You must have set platform fee to on fee");
    //     feeStatus = option;
    //     return true;
    // }
    // // Get Fee Status
    //     return feeStatus;
    // }
    // // Add Fee Percent or change Fee Percentage on Tokenism Platform
    // function addPlatformFee(uint8 _fee)public returns(bool){
    //     require(msg.sender == superAdmin, "Only SuperAmin change Platform Fee");
    //     require(_fee > 0 && _fee < 100, "Wrong Percentage!  Fee must be greater 0 and less than 100");
    //     feePercent = _fee;
    //     return true;

    // }
    //  return feePercent;
    // }
    function isAdmin(address _calle)public view returns(bool) {
        if(StringUtils.equal(admins[_calle] , "superAdmin") ||
             StringUtils.equal(admins[_calle] , "dev") ||
             StringUtils.equal(admins[_calle] , "fee") ||
             StringUtils.equal(admins[_calle] , "admin")){
                 return true;
             }
             return false;
        //  return admins[_calle];   
    }
    function isSuperAdmin(address _calle) public view returns(bool){
        if(StringUtils.equal(admins[_calle] , "superAdmin")){
            return true;
        }
        return false;
    }
   function isManager(address _calle)public returns(bool) {
        whitelistInfoManager memory m = whitelistManagers[_calle];
        return m.valid;
   }
}
function addFeeAddress(address _feeAddress) public {
    require(_msgSender() == superAdmin, "Only super admin can add Fee Address");
   feeAddress = _feeAddress;
}

// Function Add Fee Address 