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

import "@openzeppelin/contracts/access/AccessControl.sol";

/**
 * @title BridgeVaultExtension
 * @notice Extension to vault for tracking bridge operations
 * @dev Can be attached to existing vault contracts
 */
contract BridgeVaultExtension is AccessControl {
    bytes32 public constant BRIDGE_OPERATOR_ROLE = keccak256("BRIDGE_OPERATOR_ROLE");

    enum BridgeStatus {
        Initiated,
        Confirmed,
        Completed,
        Failed
    }

    struct BridgeRecord {
        bytes32 messageId;
        address token;
        uint256 amount;
        uint64 destinationChain;
        address recipient;
        uint256 timestamp;
        BridgeStatus status;
    }

    // Storage
    mapping(bytes32 => BridgeRecord) public bridgeRecords;
    bytes32[] public bridgeHistory;
    mapping(address => bytes32[]) public userBridgeHistory;

    event BridgeRecorded(
        bytes32 indexed messageId,
        address indexed token,
        uint256 amount,
        uint64 destinationChain
    );
    
    event BridgeStatusUpdated(
        bytes32 indexed messageId,
        BridgeStatus status
    );

    constructor(address admin) {
        _grantRole(DEFAULT_ADMIN_ROLE, admin);
        _grantRole(BRIDGE_OPERATOR_ROLE, admin);
    }

    /**
     * @notice Record bridge operation
     */
    function recordBridgeOperation(
        bytes32 messageId,
        address token,
        uint256 amount,
        uint64 destinationChain,
        address recipient
    ) external onlyRole(BRIDGE_OPERATOR_ROLE) {
        require(messageId != bytes32(0), "Invalid message ID");
        require(bridgeRecords[messageId].timestamp == 0, "Already recorded");
        
        bridgeRecords[messageId] = BridgeRecord({
            messageId: messageId,
            token: token,
            amount: amount,
            destinationChain: destinationChain,
            recipient: recipient,
            timestamp: block.timestamp,
            status: BridgeStatus.Initiated
        });
        
        bridgeHistory.push(messageId);
        userBridgeHistory[recipient].push(messageId);
        
        emit BridgeRecorded(messageId, token, amount, destinationChain);
    }

    /**
     * @notice Update bridge status
     */
    function updateBridgeStatus(
        bytes32 messageId,
        BridgeStatus status
    ) external onlyRole(BRIDGE_OPERATOR_ROLE) {
        require(bridgeRecords[messageId].timestamp > 0, "Not found");
        
        bridgeRecords[messageId].status = status;
        
        emit BridgeStatusUpdated(messageId, status);
    }

    // View functions
    
    function getBridgeRecord(bytes32 messageId) external view returns (BridgeRecord memory) {
        return bridgeRecords[messageId];
    }

    function getBridgeHistory(address user) external view returns (BridgeRecord[] memory) {
        bytes32[] memory userHistory = userBridgeHistory[user];
        BridgeRecord[] memory records = new BridgeRecord[](userHistory.length);
        
        for (uint256 i = 0; i < userHistory.length; i++) {
            records[i] = bridgeRecords[userHistory[i]];
        }
        
        return records;
    }

    function getAllBridgeHistory() external view returns (BridgeRecord[] memory) {
        BridgeRecord[] memory records = new BridgeRecord[](bridgeHistory.length);
        
        for (uint256 i = 0; i < bridgeHistory.length; i++) {
            records[i] = bridgeRecords[bridgeHistory[i]];
        }
        
        return records;
    }

    function getBridgeCount() external view returns (uint256) {
        return bridgeHistory.length;
    }

    function getUserBridgeCount(address user) external view returns (uint256) {
        return userBridgeHistory[user].length;
    }
}
