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

/**
 * @title IBalancerVault
 * @notice Interface for Balancer V2 Vault
 * @dev Balancer provides weighted pools and better stablecoin swaps
 */
interface IBalancerVault {
    struct SingleSwap {
        bytes32 poolId;
        SwapKind kind;
        address assetIn;
        address assetOut;
        uint256 amount;
        bytes userData;
    }

    struct FundManagement {
        address sender;
        bool fromInternalBalance;
        address payable recipient;
        bool toInternalBalance;
    }

    enum SwapKind {
        GIVEN_IN,  // Amount in is known
        GIVEN_OUT  // Amount out is known
    }

    /**
     * @notice Execute a single swap
     * @param singleSwap Swap parameters
     * @param funds Fund management parameters
     * @param limit Maximum amount to swap (slippage protection)
     * @param deadline Deadline for swap
     * @return amountCalculated Amount calculated for swap
     */
    function swap(
        SingleSwap memory singleSwap,
        FundManagement memory funds,
        uint256 limit,
        uint256 deadline
    ) external payable returns (uint256 amountCalculated);

    /**
     * @notice Get pool information
     * @param poolId Pool identifier
     * @return poolAddress Pool address
     * @return specialization Pool specialization type
     */
    function getPool(bytes32 poolId) external view returns (address poolAddress, uint8 specialization);

    /**
     * @notice Query batch swap for quotes
     * @param kind Swap kind
     * @param swaps Array of swaps to query
     * @param assets Array of assets involved
     * @return assetDeltas Asset deltas for each asset
     */
    function queryBatchSwap(
        SwapKind kind,
        SingleSwap[] memory swaps,
        address[] memory assets
    ) external view returns (int256[] memory assetDeltas);

    /**
     * @notice Get pool tokens and balances
     * @param poolId Pool identifier
     * @return tokens Token addresses in the pool
     * @return balances Token balances in the pool
     * @return lastChangeBlock Last block number that changed balances
     */
    function getPoolTokens(bytes32 poolId)
        external
        view
        returns (
            address[] memory tokens,
            uint256[] memory balances,
            uint256 lastChangeBlock
        );
}

