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

interface ITreasury {
    error NotApproved();
    error InvalidToken();
    error NotAccepted();
    error InsufficientReserves();
    error TreasuryExceeds();
    error OnlyQueueTimelock();
    error EmptyAddress();
    error TimelockDisabled();
    error ActionNullified();
    error ActionExecuted();
    error TimelockNotComplete();
    error AlreadyInitialized();

    enum STATUS {
        RESERVEDEPOSITOR,
        RESERVESPENDER,
        RESERVETOKEN,
        RESERVEMANAGER,
        LIQUIDITYDEPOSITOR,
        LIQUIDITYTOKEN,
        LIQUIDITYMANAGER,
        RESERVEDEBTOR,
        REWARDMANAGER,
        STNK,
        FTSODEBTOR
    }

    struct Queue {
        STATUS managing;
        address toPermit;
        address calculator;
        uint256 timelockEnd;
        bool nullify;
        bool executed;
    }

    event Deposit(address indexed token, uint256 amount, uint256 value);
    event Withdrawal(address indexed token, uint256 amount, uint256 value);
    event CreateDebt(address indexed debtor, address indexed token, uint256 amount, uint256 value);
    event RepayDebt(address indexed debtor, address indexed token, uint256 amount, uint256 value);
    event Managed(address indexed token, uint256 amount);
    event ReservesAudited(uint256 indexed totalReserves);
    event Minted(address indexed caller, address indexed recipient, uint256 amount);
    event PermissionQueued(STATUS indexed status, address queued);
    event Permissioned(address addr, STATUS indexed status, bool result);

    function deposit(
        address _token,
        uint256 _amount,
        uint256 _profit
    ) external returns (uint256);

    function withdraw(address _token, uint256 _amount) external;
    function repayDebtWithReserves(address _token, uint256 _amount) external;
    function repayDebtWithFtso(uint256 _amount) external;
    function mint(address _recipient, uint256 _amount) external;
    function manage(address _token, uint256 _amount) external;
    function incurDebt(address _token, uint256 _amount) external;

    function tokenValue(address _token, uint256 _amount) external view returns (uint256 value_);
    function indexInRegistry(address _address, STATUS _status) external view returns (bool, uint256);
    function excessReserves() external view returns (uint256);
    function baseSupply() external view returns (uint256);
    function totalReserves() external view returns (uint256);

}
