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

/**
 * @title ILedger
 * @notice Interface for the Core Ledger contract
 * @dev Single source of truth for collateral and debt balances
 */
interface ILedger {
    /**
     * @notice Modify collateral balance for a vault
     * @param vault Vault address
     * @param asset Collateral asset address
     * @param delta Amount to add (positive) or subtract (negative)
     */
    function modifyCollateral(address vault, address asset, int256 delta) external;

    /**
     * @notice Modify debt balance for a vault
     * @param vault Vault address
     * @param currency Debt currency address (eMoney token)
     * @param delta Amount to add (positive) or subtract (negative)
     */
    function modifyDebt(address vault, address currency, int256 delta) external;

    /**
     * @notice Get vault health (collateralization ratio in XAU)
     * @param vault Vault address
     * @return healthRatio Collateralization ratio in basis points (10000 = 100%)
     * @return collateralValue Total collateral value in XAU (18 decimals)
     * @return debtValue Total debt value in XAU (18 decimals)
     */
    function getVaultHealth(address vault) external view returns (
        uint256 healthRatio,
        uint256 collateralValue,
        uint256 debtValue
    );

    /**
     * @notice Check if a vault can borrow a specific amount
     * @param vault Vault address
     * @param currency Debt currency address
     * @param amount Amount to borrow (in currency units)
     * @return canBorrow True if borrow is allowed
     * @return reasonCode Reason code if borrow is not allowed
     */
    function canBorrow(address vault, address currency, uint256 amount) external view returns (
        bool canBorrow,
        bytes32 reasonCode
    );

    /**
     * @notice Get collateral balance for a vault
     * @param vault Vault address
     * @param asset Collateral asset address
     * @return balance Collateral balance
     */
    function collateral(address vault, address asset) external view returns (uint256);

    /**
     * @notice Get debt balance for a vault
     * @param vault Vault address
     * @param currency Debt currency address
     * @return balance Debt balance
     */
    function debt(address vault, address currency) external view returns (uint256);

    /**
     * @notice Get debt ceiling for an asset
     * @param asset Asset address
     * @return ceiling Debt ceiling
     */
    function debtCeiling(address asset) external view returns (uint256);

    /**
     * @notice Get liquidation ratio for an asset
     * @param asset Asset address
     * @return ratio Liquidation ratio in basis points
     */
    function liquidationRatio(address asset) external view returns (uint256);

    /**
     * @notice Get credit multiplier for an asset
     * @param asset Asset address
     * @return multiplier Credit multiplier in basis points (50000 = 5x)
     */
    function creditMultiplier(address asset) external view returns (uint256);

    /**
     * @notice Get rate accumulator for an asset
     * @param asset Asset address
     * @return accumulator Rate accumulator
     */
    function rateAccumulator(address asset) external view returns (uint256);

    /**
     * @notice Set risk parameters for an asset
     * @param asset Asset address
     * @param debtCeiling_ Debt ceiling
     * @param liquidationRatio_ Liquidation ratio in basis points
     * @param creditMultiplier_ Credit multiplier in basis points
     */
    function setRiskParameters(
        address asset,
        uint256 debtCeiling_,
        uint256 liquidationRatio_,
        uint256 creditMultiplier_
    ) external;

    /**
     * @notice Grant VAULT_ROLE to an address (for factory use)
     * @param account Address to grant role to
     */
    function grantVaultRole(address account) external;

    /**
     * @notice Register a newly created vault (callable by VAULT_FACTORY_ROLE)
     * @param vault Vault contract address
     */
    function registerVault(address vault) external;

    event CollateralModified(address indexed vault, address indexed asset, int256 delta);
    event DebtModified(address indexed vault, address indexed currency, int256 delta);
    event RiskParametersSet(address indexed asset, uint256 debtCeiling, uint256 liquidationRatio, uint256 creditMultiplier);
}
