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

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

/**
 * @title AereTreasury
 * @notice DAO treasury for AERE Network. Holds protocol-owned AERE.
 * @dev Spends are queued by the owner (governance contract post-handover) with a
 *      timelock; anyone can execute after the delay. Provides transparency and
 *      gives the community a window to react to malicious proposals.
 */
contract AereTreasury is Ownable, ReentrancyGuard {
    uint256 public constant TIMELOCK = 2 days;

    struct Spend {
        address to;
        uint256 amount;
        uint64  eta;
        bool    executed;
        bool    cancelled;
        string  reason;
    }

    Spend[] public spends;

    event Funded(address indexed from, uint256 amount);
    event SpendQueued(uint256 indexed id, address indexed to, uint256 amount, uint64 eta, string reason);
    event SpendExecuted(uint256 indexed id);
    event SpendCancelled(uint256 indexed id);

    receive() external payable { emit Funded(msg.sender, msg.value); }

    function queueSpend(address to, uint256 amount, string calldata reason) external onlyOwner returns (uint256 id) {
        require(to != address(0) && amount > 0, "params");
        require(amount <= address(this).balance, "insufficient");
        uint64 eta = uint64(block.timestamp + TIMELOCK);
        spends.push(Spend({to: to, amount: amount, eta: eta, executed: false, cancelled: false, reason: reason}));
        id = spends.length - 1;
        emit SpendQueued(id, to, amount, eta, reason);
    }

    function executeSpend(uint256 id) external nonReentrant {
        Spend storage s = spends[id];
        require(!s.executed && !s.cancelled, "done");
        require(block.timestamp >= s.eta, "timelock");
        require(address(this).balance >= s.amount, "balance");
        s.executed = true;
        (bool ok, ) = s.to.call{value: s.amount}("");
        require(ok, "transfer");
        emit SpendExecuted(id);
    }

    function cancelSpend(uint256 id) external onlyOwner {
        Spend storage s = spends[id];
        require(!s.executed && !s.cancelled, "done");
        s.cancelled = true;
        emit SpendCancelled(id);
    }

    function spendCount() external view returns (uint256) { return spends.length; }
}
