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

import {GhostAccessControlled} from "./GhostAccessControlled.sol";
import {IGhostAuthority} from "../interfaces/IGhostAuthority.sol";
import {FullMath} from "../libraries/FullMath.sol";
import {IERC20} from "@openzeppelin-contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin-contracts/token/ERC20/utils/SafeERC20.sol";

abstract contract FrontEndRewarder is GhostAccessControlled {
    using SafeERC20 for IERC20;

    uint256 public daoReward;
    uint256 public refReward;

    mapping(address => uint256) public rewards;
    mapping(address => bool) public whitelisted;

    IERC20 internal immutable _ftso; // forge-lint: disable-line(screaming-snake-case-immutable)

    constructor(address _authorityAddress, address _ftsoAddress)
        GhostAccessControlled(IGhostAuthority(_authorityAddress))
    {
        _ftso = IERC20(_ftsoAddress);
    }

    function getReward() external {
        uint256 reward = rewards[msg.sender];
        rewards[msg.sender] = 0;
        _ftso.safeTransfer(msg.sender, reward);
    }

    function _giveRewards(
        uint256 payout,
        address referral
    ) internal returns (uint256) {
        uint256 toDao = FullMath.mulDiv(payout, daoReward, 1e4);
        uint256 toRef = FullMath.mulDiv(payout, refReward, 1e4);

        if (whitelisted[referral]) {
            rewards[referral] += toRef;
            rewards[authority.guardian()] += toDao;
        } else {
            rewards[authority.guardian()] += toDao + toRef;
        }

        return toDao + toRef;
    }

    function setRewards(
        uint256 toFrontEnd,
        uint256 toDao
    ) external onlyGovernor {
        refReward = toFrontEnd;
        daoReward = toDao;
    }

    function whitelist(address operator) external onlyPolicy {
        whitelisted[operator] = !whitelisted[operator];
    }
}
