contract AwardSystem is Ownable {
    PointToken public pointToken;

    mapping(address => bool) public awarders;
    mapping(uint => address) public achievements;

    event AwarderAdded(address indexed addr);
    event AwarderRemoved(address indexed addr);
    event Award(address indexed from, address indexed to, uint indexed atype, uint amount, uint date);
    
    constructor(address _pointTokenAddress) {
        pointToken = PointToken(_pointTokenAddress);
    }

    // Add a new AWARDER
    function addAwarder(address _addr) public onlyOwner {
        require(!awarders[_addr], "Address is already an awarder");
        awarders[_addr] = true;
        emit AwarderAdded(_addr);
    }

    // Remove an existing AWARDER
    function deleteAwarder(address _addr) public onlyOwner {
        require(awarders[_addr], "Address is not an awarder");
        awarders[_addr] = false;
        emit AwarderRemoved(_addr);
    }

    // AWARDER adds an ACHIEVEMENT
    function addAward(uint _index) public returns (bool) {
        require(awarders[msg.sender], "Only awarders can add achievements");
        require(achievements[_index] == address(0), "Achievement already claimed");
        
        achievements[_index] = msg.sender;
        return true;
    }

    // AWARDER awards an ACHIEVEMENT and optionally POINTs
    function awardAchievement(address _user, uint _aType, uint _amount) public {
        require(awarders[msg.sender], "Only awarders can award achievements");
        require(achievements[_aType] == msg.sender, "Awarder does not own this achievement");

        if (_amount > 0) {
            require(pointToken.balanceOf(msg.sender) >= _amount, "Insufficient POINTs");
            pointToken.transfer(_user, _amount);
        }

        emit Award(msg.sender, _user, _aType, _amount, block.timestamp);
    }
}