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

import {Test} from "forge-std/Test.sol";
import {CompliantUSDT} from "../../contracts/tokens/CompliantUSDT.sol";
import {ComplianceRegistry} from "../../contracts/compliance/ComplianceRegistry.sol";

contract CompliantUSDTTest is Test {
    CompliantUSDT public usdt;
    ComplianceRegistry public registry;
    address public owner;
    address public admin;
    address public user1;
    address public user2;
    
    function setUp() public {
        owner = address(this);
        admin = address(this);
        user1 = address(0x1);
        user2 = address(0x2);
        
        usdt = new CompliantUSDT(owner, admin);
        registry = new ComplianceRegistry(admin);
    }
    
    function testInitialSupply() public {
        assertEq(usdt.totalSupply(), 1000000 * 10**6);
        assertEq(usdt.balanceOf(address(this)), 1000000 * 10**6);
    }
    
    function testDecimals() public {
        assertEq(usdt.decimals(), 6);
    }
    
    function testTransfer() public {
        uint256 amount = 1000 * 10**6;
        // forge-lint: disable-next-line(erc20-unchecked-transfer)
        usdt.transfer(user1, amount);
        
        assertEq(usdt.balanceOf(user1), amount);
        assertEq(usdt.balanceOf(address(this)), 1000000 * 10**6 - amount);
    }
    
    function testPause() public {
        usdt.pause();
        assertTrue(usdt.paused());
        
        vm.expectRevert();
        // forge-lint: disable-next-line(erc20-unchecked-transfer)
        usdt.transfer(user1, 1000 * 10**6);
    }
    
    function testUnpause() public {
        usdt.pause();
        usdt.unpause();
        assertFalse(usdt.paused());
        
        // forge-lint: disable-next-line(erc20-unchecked-transfer)
        usdt.transfer(user1, 1000 * 10**6);
        assertEq(usdt.balanceOf(user1), 1000 * 10**6);
    }
    
    function testMint() public {
        uint256 amount = 5000 * 10**6;
        usdt.mint(user1, amount);
        
        assertEq(usdt.balanceOf(user1), amount);
        assertEq(usdt.totalSupply(), 1000000 * 10**6 + amount);
    }
    
    function testBurn() public {
        uint256 amount = 1000 * 10**6;
        // forge-lint: disable-next-line(erc20-unchecked-transfer)
        usdt.transfer(user1, amount);
        
        vm.prank(user1);
        usdt.burn(amount);
        
        assertEq(usdt.balanceOf(user1), 0);
        assertEq(usdt.totalSupply(), 1000000 * 10**6 - amount);
    }
    
    function testComplianceRegistration() public {
        registry.registerContract(address(usdt));
        
        assertTrue(registry.isContractRegistered(address(usdt)));
        
        ComplianceRegistry.ContractComplianceStatus memory status = 
            registry.getContractComplianceStatus(address(usdt));
        
        assertTrue(status.isRegistered);
        assertEq(status.legalFrameworkVersion, "1.0.0");
    }
    
    function testValueTransferEvent() public {
        uint256 amount = 1000 * 10**6;
        
        // Check that the ValueTransferDeclared event is emitted during transfer
        // The event is defined in LegallyCompliantBase and inherited by CompliantUSDT
        // We can't emit it directly from abstract contract, so we just verify it happens
        vm.expectEmit(true, true, false, false); // Check indexed params only, ignore data
        // Event signature: ValueTransferDeclared(address indexed, address indexed, uint256, bytes32)
        // We check the indexed parameters (from, to) and ignore the non-indexed ones
        emit ValueTransferDeclared(
            address(this),
            user1,
            amount,
            bytes32(0)
        );
        
        // forge-lint: disable-next-line(erc20-unchecked-transfer)
        usdt.transfer(user1, amount);
    }
    
    // Helper event for testing (matches LegallyCompliantBase.ValueTransferDeclared)
    event ValueTransferDeclared(
        address indexed from,
        address indexed to,
        uint256 value,
        bytes32 legalReferenceHash
    );
}

