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

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

/**
 * @title ComplianceRegistry
 * @notice Registry for tracking legal compliance status of contracts
 * @dev This registry tracks contracts that inherit from LegallyCompliantBase
 *      Separate from eMoney ComplianceRegistry which has KYC/AML features
 */
contract ComplianceRegistry is AccessControl {
    bytes32 public constant REGISTRAR_ROLE = keccak256("REGISTRAR_ROLE");
    
    /**
     * @notice Compliance status for a contract
     */
    struct ContractComplianceStatus {
        bool isRegistered;
        string legalFrameworkVersion;
        string legalJurisdiction;
        bytes32 lastLegalNoticeHash;
        uint256 registeredAt;
        uint256 lastUpdated;
    }
    
    mapping(address => ContractComplianceStatus) private _contractCompliance;
    
    event ContractRegistered(
        address indexed contractAddress,
        string legalFrameworkVersion,
        string legalJurisdiction,
        uint256 timestamp
    );
    
    event ContractComplianceUpdated(
        address indexed contractAddress,
        bytes32 lastLegalNoticeHash,
        uint256 timestamp
    );
    
    /**
     * @notice Constructor
     * @param admin Address that will receive DEFAULT_ADMIN_ROLE
     */
    constructor(address admin) {
        _grantRole(DEFAULT_ADMIN_ROLE, admin);
        _grantRole(REGISTRAR_ROLE, admin);
    }
    
    /**
     * @notice Register a contract that inherits from LegallyCompliantBase
     * @param contractAddress Address of the compliant contract
     * @dev Requires REGISTRAR_ROLE
     */
    function registerContract(address contractAddress) external onlyRole(REGISTRAR_ROLE) {
        require(contractAddress != address(0), "ComplianceRegistry: zero address");
        require(!_contractCompliance[contractAddress].isRegistered, "ComplianceRegistry: contract already registered");
        
        // Get compliance information from the contract
        LegallyCompliantBase compliantContract = LegallyCompliantBase(contractAddress);
        
        _contractCompliance[contractAddress] = ContractComplianceStatus({
            isRegistered: true,
            legalFrameworkVersion: compliantContract.LEGAL_FRAMEWORK_VERSION(),
            legalJurisdiction: compliantContract.LEGAL_JURISDICTION(),
            lastLegalNoticeHash: bytes32(0),
            registeredAt: block.timestamp,
            lastUpdated: block.timestamp
        });
        
        emit ContractRegistered(
            contractAddress,
            compliantContract.LEGAL_FRAMEWORK_VERSION(),
            compliantContract.LEGAL_JURISDICTION(),
            block.timestamp
        );
    }
    
    /**
     * @notice Update compliance status with a new legal notice
     * @param contractAddress Address of the compliant contract
     * @param newLegalNoticeHash Hash of the new legal notice
     * @dev Requires REGISTRAR_ROLE
     */
    function updateContractCompliance(
        address contractAddress,
        bytes32 newLegalNoticeHash
    ) external onlyRole(REGISTRAR_ROLE) {
        require(_contractCompliance[contractAddress].isRegistered, "ComplianceRegistry: contract not registered");
        
        _contractCompliance[contractAddress].lastLegalNoticeHash = newLegalNoticeHash;
        _contractCompliance[contractAddress].lastUpdated = block.timestamp;
        
        emit ContractComplianceUpdated(contractAddress, newLegalNoticeHash, block.timestamp);
    }
    
    /**
     * @notice Get compliance status for a contract
     * @param contractAddress Address of the contract
     * @return Compliance status struct
     */
    function getContractComplianceStatus(
        address contractAddress
    ) external view returns (ContractComplianceStatus memory) {
        return _contractCompliance[contractAddress];
    }
    
    /**
     * @notice Check if a contract is registered
     * @param contractAddress Address of the contract
     * @return True if registered, false otherwise
     */
    function isContractRegistered(address contractAddress) external view returns (bool) {
        return _contractCompliance[contractAddress].isRegistered;
    }
}

