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

import "@openzeppelin/contracts/access/AccessControl.sol";
import "../interop/BridgeRegistry.sol";
import "../../iso4217w/TokenFactory.sol";
import "../../iso4217w/registry/TokenRegistry.sol";

/**
 * @title WTokenBridgeIntegration
 * @notice Automatically registers ISO-4217 W tokens with BridgeRegistry
 * @dev Extends TokenFactory to auto-register W tokens on creation
 */
contract WTokenBridgeIntegration is AccessControl {
    bytes32 public constant INTEGRATOR_ROLE = keccak256("INTEGRATOR_ROLE");

    TokenFactory public tokenFactory;
    BridgeRegistry public bridgeRegistry;
    ITokenRegistry public wTokenRegistry;

    // Default bridge configuration for W tokens (more conservative due to compliance)
    uint256 public defaultMinBridgeAmount = 100e2; // 100 USD minimum
    uint256 public defaultMaxBridgeAmount = 10_000_000e2; // 10M USD maximum
    uint8 public defaultRiskLevel = 20; // Low risk (fiat-backed)
    uint256 public defaultBridgeFeeBps = 5; // 0.05% default fee (lower due to compliance)

    // Destination chain IDs (includes XRPL and Fabric in addition to EVM)
    uint256[] public defaultEvmDestinations;
    uint256[] public defaultNonEvmDestinations; // 0 for XRPL, 1 for Fabric (example)

    event WTokenRegistered(
        address indexed token,
        string indexed currencyCode,
        uint256[] destinationChainIds
    );

    constructor(
        address admin,
        address tokenFactory_,
        address bridgeRegistry_,
        address wTokenRegistry_
    ) {
        _grantRole(DEFAULT_ADMIN_ROLE, admin);
        _grantRole(INTEGRATOR_ROLE, admin);

        require(tokenFactory_ != address(0), "WTokenBridgeIntegration: zero token factory");
        require(bridgeRegistry_ != address(0), "WTokenBridgeIntegration: zero bridge registry");
        require(wTokenRegistry_ != address(0), "WTokenBridgeIntegration: zero W token registry");

        tokenFactory = TokenFactory(tokenFactory_);
        bridgeRegistry = BridgeRegistry(bridgeRegistry_);
        wTokenRegistry = ITokenRegistry(wTokenRegistry_);

        // Set default EVM destinations
        defaultEvmDestinations.push(137); // Polygon
        defaultEvmDestinations.push(10);  // Optimism
        defaultEvmDestinations.push(8453); // Base
        defaultEvmDestinations.push(42161); // Arbitrum
        defaultEvmDestinations.push(43114); // Avalanche
        defaultEvmDestinations.push(56);   // BNB Chain
        defaultEvmDestinations.push(10143); // Monad
        defaultEvmDestinations.push(42793); // Etherlink (Tezos EVM L2)

        // Set default non-EVM destinations
        defaultNonEvmDestinations.push(0); // XRPL (0 = non-EVM identifier)
        defaultNonEvmDestinations.push(1); // Fabric (1 = non-EVM identifier)
    }

    /**
     * @notice Register a W token with bridge registry
     * @param currencyCode ISO-4217 currency code (e.g., "USD")
     * @param destinationChainIds Array of allowed destination chain IDs
     * @param minAmount Minimum bridge amount (in token decimals)
     * @param maxAmount Maximum bridge amount (in token decimals)
     * @param riskLevel Risk level (0-255)
     * @param bridgeFeeBps Bridge fee in basis points
     */
    function registerWToken(
        string memory currencyCode,
        uint256[] memory destinationChainIds,
        uint256 minAmount,
        uint256 maxAmount,
        uint8 riskLevel,
        uint256 bridgeFeeBps
    ) public onlyRole(INTEGRATOR_ROLE) {
        address token = wTokenRegistry.getTokenAddress(currencyCode);
        require(token != address(0), "WTokenBridgeIntegration: token not found");

        require(destinationChainIds.length > 0, "WTokenBridgeIntegration: no destinations");
        require(minAmount > 0, "WTokenBridgeIntegration: zero min amount");
        require(maxAmount >= minAmount, "WTokenBridgeIntegration: max < min");
        require(bridgeFeeBps <= 10000, "WTokenBridgeIntegration: fee > 100%");

        bridgeRegistry.registerToken(
            token,
            minAmount,
            maxAmount,
            destinationChainIds,
            riskLevel,
            bridgeFeeBps
        );

        emit WTokenRegistered(token, currencyCode, destinationChainIds);
    }

    /**
     * @notice Register a W token with default configuration
     * @param currencyCode ISO-4217 currency code
     */
    function registerWTokenDefault(string memory currencyCode) public onlyRole(INTEGRATOR_ROLE) {
        // Combine EVM and non-EVM destinations
        uint256[] memory allDestinations = new uint256[](
            defaultEvmDestinations.length + defaultNonEvmDestinations.length
        );
        
        uint256 i = 0;
        for (uint256 j = 0; j < defaultEvmDestinations.length; j++) {
            allDestinations[i++] = defaultEvmDestinations[j];
        }
        for (uint256 j = 0; j < defaultNonEvmDestinations.length; j++) {
            allDestinations[i++] = defaultNonEvmDestinations[j];
        }

        registerWToken(
            currencyCode,
            allDestinations,
            defaultMinBridgeAmount,
            defaultMaxBridgeAmount,
            defaultRiskLevel,
            defaultBridgeFeeBps
        );
    }

    /**
     * @notice Register multiple W tokens with default configuration
     * @param currencyCodes Array of ISO-4217 currency codes
     */
    function registerMultipleWTokensDefault(string[] memory currencyCodes) external onlyRole(INTEGRATOR_ROLE) {
        for (uint256 i = 0; i < currencyCodes.length; i++) {
            registerWTokenDefault(currencyCodes[i]);
        }
    }

    /**
     * @notice Set default bridge configuration
     */
    function setDefaultMinBridgeAmount(uint256 minAmount) external onlyRole(DEFAULT_ADMIN_ROLE) {
        require(minAmount > 0, "WTokenBridgeIntegration: zero min amount");
        defaultMinBridgeAmount = minAmount;
    }

    function setDefaultMaxBridgeAmount(uint256 maxAmount) external onlyRole(DEFAULT_ADMIN_ROLE) {
        require(maxAmount >= defaultMinBridgeAmount, "WTokenBridgeIntegration: max < min");
        defaultMaxBridgeAmount = maxAmount;
    }

    function setDefaultRiskLevel(uint8 riskLevel) external onlyRole(DEFAULT_ADMIN_ROLE) {
        require(riskLevel <= 255, "WTokenBridgeIntegration: invalid risk level");
        defaultRiskLevel = riskLevel;
    }

    function setDefaultBridgeFeeBps(uint256 feeBps) external onlyRole(DEFAULT_ADMIN_ROLE) {
        require(feeBps <= 10000, "WTokenBridgeIntegration: fee > 100%");
        defaultBridgeFeeBps = feeBps;
    }

    function setDefaultEvmDestinations(uint256[] memory chainIds) external onlyRole(DEFAULT_ADMIN_ROLE) {
        require(chainIds.length > 0, "WTokenBridgeIntegration: no destinations");
        defaultEvmDestinations = chainIds;
    }

    function setDefaultNonEvmDestinations(uint256[] memory chainIds) external onlyRole(DEFAULT_ADMIN_ROLE) {
        defaultNonEvmDestinations = chainIds;
    }
}
