const ADDRESSES = require('../helper/coreAssets.json')
// Nivela Protocol Adapter for DeFiLlama
const sdk = require('@defillama/sdk');
const { sumTokens2 } = require('../helper/unwrapLPs');

const nUSD = '0x9AE01bcE99611a389645437208f199F4595df737'
const tokens = {
    // Basic tokens
    NIV: '0x56FC995646AB92a5128cEB2124721D122B3b9D90',
    // veNIV: '0x4E6864C7007F407Dc62DB68f09023D58E93433Fe',
    // nUSD: '0x9AE01bcE99611a389645437208f199F4595df737',
    USDC: '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d',
    USDT: '0x55d398326f99059fF775485246999027B3197955',
    
    // Additional vault tokens
    wBNB: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c',
    FDUSD: '0xc5f0f7b66764F6ec8C8Dff7BA683102295E16409',
    WETH: '0x2170Ed0880ac9A755fd29B2688956BD959F933F8',
    WBTC: '0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c',
};

const contracts = {
    StakednUSD: '0x6697Db6332071F7C5b64577d0db9B7219ae09594',
    VoteEscrowedNIV: '0x4E6864C7007F407Dc62DB68f09023D58E93433Fe',
    NivelaVault: '0x2f2FE42C07F9D2C12A386edeB64EFD23582AD9F6',
    LenderVoteEscrowedNIV: '0x674e2C3Add04D21e7A2d7f8a14d00969E413B446',
    LenderWBNB: '0x8e39de2390662F59fAB55D6dF031802BD4Be16d6',
    LenderWETH: '0x80cebB4579dB7C39bC43FC26a74e4086FD847FA5',
    PegStabilityModuleUSDC: '0x577a547F24A8bB4aC9643644684DC883254C282a',
    PegStabilityModuleUSDT: '0xE2D42dDB05E8Ddb8B399B4Fd2ad92F12E7470F1e',
    Floor: '0xc0c7d5EC7e543536bA6042baCdFed9bdc5B6304a',
    MarketLens: '0x79a71F1fac2376a9187A7482a2122F6e21fB97C7',
};



// Calculates TVL from NivelaVault, PSMs, and Floor
async function tvl(api) {
    const tokensAndOwners = [];

    // Add all vault tokens
    for (const [_, tokenAddress] of Object.entries(tokens)) {
        if (tokenAddress.toLowerCase() === tokens.NIV.toLowerCase()) continue;
        tokensAndOwners.push([tokenAddress, contracts.NivelaVault]);
    }

    // PSM tokens
    tokensAndOwners.push([tokens.USDC, contracts.PegStabilityModuleUSDC]);
    tokensAndOwners.push([tokens.USDT, contracts.PegStabilityModuleUSDT]);

    // Get all balances first
    const balances = await sumTokens2({ api, tokensAndOwners });
    
    return balances;
}

// Calculates staked nUSD
async function staking(api) {
    const tokensAndOwners = [
        [tokens.NIV, contracts.VoteEscrowedNIV],
    ];

    const balances = await sumTokens2({ api, tokensAndOwners });
    
    return balances;
}

// No LP tokens in the current implementation
async function pool2(api) {
    return {};
}

// Gets borrowed nUSD amount from the MarketLens contract
async function borrowed(api) {
  // Explicit ABI for the MarketLens contract function
  const abi = 'function getTotalBorrowed(address lender) external view returns (uint256)';

  // List of lenders to check
  const lenders = [
    contracts.LenderVoteEscrowedNIV,
    contracts.LenderWBNB,
    contracts.LenderWETH,
  ];

  // Get borrowed amounts from all lenders
  for (const lender of lenders) {
    const borrowedAmount = await api.call({
      abi,
      target: contracts.MarketLens,
      params: [lender],
    });
    api.add(nUSD, borrowedAmount);
  }

  return api.getBalances();
}


module.exports = {
    timetravel: true,
    misrepresentedTokens: false,
    doublecounted: false,
    methodology:
        'TVL includes various tokens in NivelaVault, stablecoins in PSMs, and nUSD in Floor. ' +
        'Staking tracks NIV in VoteEscrowedNIV and nUSD in StakednUSD. ' +
        'Borrowed shows nUSD loans from Lenders.',
    bsc: {
        tvl,
        staking,
        pool2,
        borrowed,
    },

};


