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

import {Test, console} from "forge-std/Test.sol";
import {TokenizedEUR} from "../../contracts/tokenization/TokenizedEUR.sol";
import {TokenRegistry} from "../../contracts/tokenization/TokenRegistry.sol";
import {BridgeEscrowVault} from "../../contracts/bridge/interop/BridgeEscrowVault.sol";

contract TokenizationIntegrationTest is Test {
    TokenizedEUR public tokenizedEUR;
    TokenRegistry public tokenRegistry;
    BridgeEscrowVault public escrowVault;
    
    address public admin = address(0x1);
    address public minter = address(0x2);
    address public issuer = address(0x3);
    address public user = address(0x4);

    function setUp() public {
        vm.startPrank(admin);
        
        // Deploy TokenRegistry
        tokenRegistry = new TokenRegistry(admin);
        tokenRegistry.grantRole(tokenRegistry.REGISTRAR_ROLE(), admin);
        
        // Deploy TokenizedEUR
        tokenizedEUR = new TokenizedEUR(admin);
        tokenizedEUR.grantRole(tokenizedEUR.MINTER_ROLE(), minter);
        tokenizedEUR.grantRole(tokenizedEUR.BURNER_ROLE(), minter);
        
        // Deploy BridgeEscrowVault
        escrowVault = new BridgeEscrowVault(admin);
        
        vm.stopPrank();
    }

    function test_TokenizationFlow() public {
        // 1. Register token in registry
        vm.startPrank(admin);
        tokenRegistry.registerToken(
            address(tokenizedEUR),
            "EUR-T-2025-001",
            "EUR",
            issuer,
            "RESERVE-EUR-001"
        );
        vm.stopPrank();

        // 2. Mint tokenized EUR from Fabric attestation
        bytes32 fabricTxHash = keccak256("fabric-mint-tx");
        TokenizedEUR.FabricAttestation memory attestation = TokenizedEUR.FabricAttestation({
            fabricTxHash: fabricTxHash,
            tokenId: "EUR-T-2025-001",
            amount: 1000 * 10**18,
            minter: issuer,
            timestamp: block.timestamp,
            signature: new bytes(65)
        });

        vm.startPrank(minter);
        tokenizedEUR.mintFromFabric(
            user,
            1000 * 10**18,
            "EUR-T-2025-001",
            fabricTxHash,
            attestation
        );
        vm.stopPrank();

        // 3. Verify token balance
        assertEq(tokenizedEUR.balanceOf(user), 1000 * 10**18);
        assertEq(tokenizedEUR.getFabricTokenBalance("EUR-T-2025-001"), 1000 * 10**18);

        // 4. Bridge tokenized asset
        vm.startPrank(user);
        tokenizedEUR.approve(address(escrowVault), 100 * 10**18);
        
        bytes32 transferId = escrowVault.depositERC20(
            address(tokenizedEUR),
            100 * 10**18,
            BridgeEscrowVault.DestinationType.EVM,
            abi.encodePacked(address(0x100)),
            3600,
            keccak256("bridge-transfer")
        );
        vm.stopPrank();

        assertNotEq(transferId, bytes32(0));
    }

    function test_RegistryIntegration() public {
        vm.startPrank(admin);
        tokenRegistry.registerToken(
            address(tokenizedEUR),
            "EUR-T-2025-001",
            "EUR",
            issuer,
            "RESERVE-EUR-001"
        );
        vm.stopPrank();

        // Get token by Fabric ID
        address tokenAddr = tokenRegistry.getTokenByFabricId("EUR-T-2025-001");
        assertEq(tokenAddr, address(tokenizedEUR));

        // Get token metadata
        TokenRegistry.TokenMetadata memory metadata = tokenRegistry.getToken(address(tokenizedEUR));
        assertEq(metadata.tokenId, "EUR-T-2025-001");
        assertEq(metadata.underlyingAsset, "EUR");
    }
}
