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

import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {IAtomicSettlementAdapter} from "../interfaces/IAtomicSettlementAdapter.sol";
import {UniversalCCIPBridge} from "../../UniversalCCIPBridge.sol";

contract UniversalCcipAtomicSettlementAdapter is AccessControl, IAtomicSettlementAdapter {
    using SafeERC20 for IERC20;

    bytes32 public constant ROUTER_ROLE = keccak256("ROUTER_ROLE");

    UniversalCCIPBridge public immutable universalBridge;

    struct SettlementParams {
        uint64 destinationChain;
        address destinationRecipient;
        bytes32 assetType;
        bool usePMM;
        bool useVault;
        bytes complianceProof;
        bytes vaultInstructions;
    }

    event AtomicSettlementBridged(
        bytes32 indexed obligationId,
        bytes32 indexed messageId,
        address indexed token,
        uint256 amount,
        uint64 destinationChain,
        address recipient
    );

    constructor(address universalBridge_, address admin) {
        universalBridge = UniversalCCIPBridge(payable(universalBridge_));
        _grantRole(DEFAULT_ADMIN_ROLE, admin);
    }

    function executeSettlement(
        bytes32 obligationId,
        address token,
        uint256 amount,
        address recipient,
        bytes calldata data
    ) external payable onlyRole(ROUTER_ROLE) returns (bytes32 settlementId) {
        SettlementParams memory params = abi.decode(data, (SettlementParams));
        address finalRecipient = params.destinationRecipient == address(0) ? recipient : params.destinationRecipient;
        IERC20(token).forceApprove(address(universalBridge), amount);
        settlementId = universalBridge.bridge{value: msg.value}(
            UniversalCCIPBridge.BridgeOperation({
                token: token,
                amount: amount,
                destinationChain: params.destinationChain,
                recipient: finalRecipient,
                assetType: params.assetType,
                usePMM: params.usePMM,
                useVault: params.useVault,
                complianceProof: params.complianceProof,
                vaultInstructions: params.vaultInstructions
            })
        );
        IERC20(token).forceApprove(address(universalBridge), 0);
        emit AtomicSettlementBridged(
            obligationId,
            settlementId,
            token,
            amount,
            params.destinationChain,
            finalRecipient
        );
    }
}
