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

import {Test, console} from "forge-std/Test.sol";
import "../../../../contracts/bridge/trustless/integration/StablecoinPegManager.sol";
import "../../../../contracts/reserve/ReserveSystem.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract MockERC20 is ERC20 {
    constructor(string memory name, string memory symbol) ERC20(name, symbol) {
        _mint(msg.sender, 1000000 ether);
    }
}

contract StablecoinPegManagerTest is Test {
    StablecoinPegManager public pegManager;
    ReserveSystem public reserveSystem;
    
    MockERC20 public usdt;
    MockERC20 public usdc;
    MockERC20 public weth;

    address public deployer = address(0xDE0001);

    function setUp() public {
        vm.startPrank(deployer);

        // Deploy mock tokens
        usdt = new MockERC20("Tether USD", "USDT");
        usdc = new MockERC20("USD Coin", "USDC");
        weth = new MockERC20("Wrapped Ether", "WETH");

        // Deploy ReserveSystem
        reserveSystem = new ReserveSystem(deployer);
        // Grant PRICE_FEED_ROLE to this test contract so we can update prices
        reserveSystem.grantRole(keccak256("PRICE_FEED_ROLE"), address(this));

        // Deploy StablecoinPegManager
        pegManager = new StablecoinPegManager(address(reserveSystem));

        // Register assets
        pegManager.registerUSDStablecoin(address(usdt));
        pegManager.registerUSDStablecoin(address(usdc));
        pegManager.registerWETH(address(weth));

        vm.stopPrank();
    }

    function testRegisterUSDStablecoin() public {
        address[] memory assets = pegManager.getSupportedAssets();
        assertEq(assets.length, 3); // USDT, USDC, WETH
    }

    function testCheckUSDpeg() public {
        // Set price at $1.00 (on peg)
        reserveSystem.updatePriceFeed(address(usdt), 1e18, block.timestamp);
        
        (bool isMaintained, int256 deviationBps) = pegManager.checkUSDpeg(address(usdt));
        
        assertTrue(isMaintained);
        assertEq(deviationBps, 0);
    }

    function testCheckUSDpegDeviation() public {
        // Set price at $1.01 (1% above peg)
        reserveSystem.updatePriceFeed(address(usdt), 1.01e18, block.timestamp);
        
        (bool isMaintained, int256 deviationBps) = pegManager.checkUSDpeg(address(usdt));
        
        // Deviation should be 100 bps (1%), threshold is 50 bps (0.5%)
        assertFalse(isMaintained);
        assertEq(deviationBps, 100);
    }

    function testCheckETHpeg() public {
        // Set price at 1:1 (on peg)
        reserveSystem.updatePriceFeed(address(weth), 1e18, block.timestamp);
        
        (bool isMaintained, int256 deviationBps) = pegManager.checkETHpeg(address(weth));
        
        assertTrue(isMaintained);
        assertEq(deviationBps, 0);
    }

    function testCalculateDeviation() public {
        int256 deviation = pegManager.calculateDeviation(address(usdt), 1.01e18, 1e18);
        assertEq(deviation, 100); // 1% = 100 bps
    }

    function testGetPegStatus() public {
        reserveSystem.updatePriceFeed(address(usdt), 1e18, block.timestamp);
        
        (uint256 currentPrice, uint256 targetPrice, int256 deviationBps, bool isMaintained) = 
            pegManager.getPegStatus(address(usdt));
        
        assertEq(currentPrice, 1e18);
        assertEq(targetPrice, 1e18);
        assertEq(deviationBps, 0);
        assertTrue(isMaintained);
    }

    function testSetUSDPegThreshold() public {
        uint256 newThreshold = 100; // 1%
        
        vm.prank(deployer);
        pegManager.setUSDPegThreshold(newThreshold);
        
        assertEq(pegManager.usdPegThresholdBps(), newThreshold);
    }
}

