// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

/**
 * @title MockStakingForVotes
 * @notice TEST-ONLY mock implementing the read surface of AereStakingV2 and
 *         AereLockedStaking that AereStakedGovVotes consumes. Never deployed to
 *         mainnet; used solely by test/gov-stack-selftest.local.js.
 */
contract MockStakingForVotes {
    struct V {
        bool active;
        bool exists;
        uint256 selfStake;
        uint256 totalDelegated;
        uint256 commissionBps;
        uint256 commissionAccrued;
    }
    mapping(address => V) private _validators;
    address[] private _list;
    mapping(address => mapping(address => uint256)) private _delegation;

    struct L {
        uint256 amount;
        uint64 startedAt;
        uint64 unlockAt;
        uint8 tier;
        bool withdrawn;
    }
    mapping(address => L[]) private _locks;

    function setValidator(address v, uint256 selfStake) external {
        if (!_validators[v].exists) {
            _validators[v].exists = true;
            _list.push(v);
        }
        _validators[v].active = true;
        _validators[v].selfStake = selfStake;
    }

    function setDelegation(address v, address d, uint256 amount) external {
        _delegation[v][d] = amount;
    }

    function addLock(address user, uint256 amount, bool withdrawn) external {
        _locks[user].push(L({ amount: amount, startedAt: 0, unlockAt: 0, tier: 0, withdrawn: withdrawn }));
    }

    // ---- AereStakingV2 read surface ----
    function validatorCount() external view returns (uint256) {
        return _list.length;
    }

    function validatorList(uint256 i) external view returns (address) {
        return _list[i];
    }

    function delegations(address v, address d)
        external
        view
        returns (uint256 amount, uint256 stakedAt, uint256 lastClaimTime, uint256 rewardAccrued)
    {
        return (_delegation[v][d], 0, 0, 0);
    }

    function validators(address a)
        external
        view
        returns (bool active, bool exists, uint256 selfStake, uint256 totalDelegated, uint256 commissionBps, uint256 commissionAccrued)
    {
        V memory v = _validators[a];
        return (v.active, v.exists, v.selfStake, v.totalDelegated, v.commissionBps, v.commissionAccrued);
    }

    // ---- AereLockedStaking read surface ----
    function lockCount(address user) external view returns (uint256) {
        return _locks[user].length;
    }

    function getLock(address user, uint256 id)
        external
        view
        returns (uint256 amount, uint64 startedAt, uint64 unlockAt, uint8 tier, bool withdrawn)
    {
        L memory l = _locks[user][id];
        return (l.amount, l.startedAt, l.unlockAt, l.tier, l.withdrawn);
    }
}
