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

import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {IRouterClient} from "../ccip/IRouterClient.sol";

/**
 * @title CrossChainFlashRepayReceiver
 * @notice **Destination-chain** CCIP receiver: forwards received ERC-20s to a recipient encoded in `message.data`.
 * @dev Intended pairing with `CrossChainFlashBorrower` / bridge senders. `msg.sender` must be the CCIP router.
 *      `data` encoding: `abi.encode(address recipient, bytes32 obligationId)` where `obligationId` is opaque (indexing / ops).
 *      **Repaying the source-chain flash vault** requires a **separate** flow (second tx / bridge back); this contract does not pull debt on source.
 */
contract CrossChainFlashRepayReceiver {
    using SafeERC20 for IERC20;

    IRouterClient public immutable ccipRouter;

    event CrossChainDelivered(
        bytes32 indexed messageId,
        uint64 indexed sourceChainSelector,
        address indexed recipient,
        address token,
        uint256 amount,
        bytes32 obligationId
    );

    error OnlyRouter();
    error NoTokens();
    error BadData();

    constructor(address ccipRouter_) {
        require(ccipRouter_ != address(0), "CrossChainFlashRepayReceiver: zero router");
        ccipRouter = IRouterClient(ccipRouter_);
    }

    modifier onlyRouter() {
        if (msg.sender != address(ccipRouter)) revert OnlyRouter();
        _;
    }

    function ccipReceive(IRouterClient.Any2EVMMessage calldata message) external onlyRouter {
        _deliver(message);
    }

    function _deliver(IRouterClient.Any2EVMMessage calldata m) private {
        if (m.tokenAmounts.length == 0) revert NoTokens();
        IRouterClient.TokenAmount calldata ta = m.tokenAmounts[0];
        if (ta.token == address(0) || ta.amount == 0) revert NoTokens();
        (address recipient, bytes32 obligationId) = abi.decode(m.data, (address, bytes32));
        if (recipient == address(0)) revert BadData();
        IERC20(ta.token).safeTransfer(recipient, ta.amount);
        emit CrossChainDelivered(m.messageId, m.sourceChainSelector, recipient, ta.token, ta.amount, obligationId);
    }
}

