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

import "forge-std/Test.sol";
import "../../contracts/rwa/RWAToken.sol";
import "../../contracts/rwa/LiIndexFlashVault.sol";
import {IERC3156FlashBorrower} from "@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

contract MockFlashBorrower is IERC3156FlashBorrower {
    bytes32 private constant _RETURN = keccak256("ERC3156FlashBorrower.onFlashLoan");

    function onFlashLoan(
        address,
        address token,
        uint256 amount,
        uint256 fee,
        bytes calldata
    ) external returns (bytes32) {
        IERC20(token).approve(msg.sender, amount + fee);
        return _RETURN;
    }
}

contract LiIndexFlashVaultTest is Test {
    LiIndexFlashVault vault;
    RWAToken liToken;
    MockFlashBorrower borrower;
    address admin = address(0xA11CE);

    function setUp() public {
        vm.startPrank(admin);
        liToken = new RWAToken(
            "LiXAU Test",
            "LiXAU",
            6,
            "LiXAU",
            "Commodity",
            "Gold",
            "Index",
            "XAU",
            "M00",
            admin,
            admin,
            admin,
            1_000_000,
            0,
            keccak256("methodology-test")
        );
        vault = new LiIndexFlashVault(
            admin,
            8000,
            5000,
            5,
            250,
            86400,
            2400_00000000
        );
        vault.setSupportedToken(address(liToken), true);
        borrower = new MockFlashBorrower();
        liToken.mint(admin, 1_000_000e6);
        liToken.approve(address(vault), type(uint256).max);
        vault.deposit(address(liToken), 500_000e6);
        vm.stopPrank();
    }

    function test_MaxFlashLoanWithinLtv() public view {
        uint256 max = vault.maxFlashLoan(address(liToken));
        assertEq(max, 250_000e6);
    }

    function test_FlashLoanRepays() public {
        vm.prank(admin);
        vault.flashLoan(IERC3156FlashBorrower(address(borrower)), address(liToken), 100_000e6, "");
        assertEq(vault.outstandingFlash(address(liToken)), 0);
    }

    function test_BlocksWhenUtilizationExceeded() public {
        vm.startPrank(admin);
        vault.flashLoan(IERC3156FlashBorrower(address(borrower)), address(liToken), 400_000e6, "");
        vm.stopPrank();
        assertEq(vault.maxFlashLoan(address(liToken)), 0);
    }
}
