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

import {Test, console} from "forge-std/Test.sol";
import {Aggregator} from "../../contracts/oracle/Aggregator.sol";
import {OracleWithCCIP} from "../../contracts/oracle/OracleWithCCIP.sol";
import {CCIPSender} from "../../contracts/ccip/CCIPSender.sol";

contract OracleFlowTest is Test {
    Aggregator public aggregator;
    OracleWithCCIP public oracleWithCCIP;
    CCIPSender public ccipSender;
    address public transmitter;
    
    function setUp() public {
        transmitter = address(this);
        
        aggregator = new Aggregator("ETH/USD", address(this), 60, 50);
        aggregator.addTransmitter(transmitter);
        
        // Deploy CCIP components (simplified for testing)
        address mockRouter = address(0x123);
        address mockFeeToken = address(0x456);
        ccipSender = new CCIPSender(mockRouter, address(aggregator), mockFeeToken);
        
        oracleWithCCIP = new OracleWithCCIP(
            "ETH/USD",
            address(this),
            60,
            50,
            address(ccipSender)
        );
        oracleWithCCIP.addTransmitter(transmitter);
    }
    
    function testFullOracleUpdateFlow() public {
        uint256 price = 25000000000; // $250.00
        
        // Update oracle
        oracleWithCCIP.updateAnswer(price);
        
        // Verify update
        (uint256 roundId, int256 answer, , , ) = oracleWithCCIP.latestRoundData();
        assertEq(uint256(answer), price, "Price should match");
        assertEq(roundId, 1, "Round ID should be 1");
    }
    
    function testOracleUpdateWithHeartbeat() public {
        uint256 price1 = 25000000000;
        uint256 price2 = 25100000000;
        
        // First update
        oracleWithCCIP.updateAnswer(price1);
        
        // Fast forward past heartbeat
        vm.warp(block.timestamp + 61);
        
        // Second update should create new round
        oracleWithCCIP.updateAnswer(price2);
        
        (uint256 roundId, int256 answer, , , ) = oracleWithCCIP.latestRoundData();
        assertEq(uint256(answer), price2, "Price should be updated");
        assertEq(roundId, 2, "Round ID should increment");
    }
    
    function testOracleUpdateWithDeviation() public {
        uint256 price1 = 25000000000; // $250.00
        uint256 price2 = 25125000000; // $251.25 (0.5% deviation)
        
        // First update
        oracleWithCCIP.updateAnswer(price1);
        
        // Second update with deviation
        oracleWithCCIP.updateAnswer(price2);
        
        (uint256 roundId, int256 answer, , , ) = oracleWithCCIP.latestRoundData();
        assertEq(uint256(answer), price2, "Price should be updated");
        assertGt(roundId, 1, "Round ID should increment on deviation");
    }
}

