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

import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";

/**
 * @title OMNLJurisdictionPolicyRegistry
 * @notice On-chain anchor for jurisdiction compliance matrices and Web3 control thresholds.
 *         Off-chain source: config/jurisdictions/catalog.v1.json + jurisdiction-web3-controls.v1.json
 */
contract OMNLJurisdictionPolicyRegistry is AccessControl {
    bytes32 public constant POLICY_PUBLISHER_ROLE = keccak256("POLICY_PUBLISHER_ROLE");

    struct JurisdictionPolicy {
        bytes32 jurisdictionId;
        bytes32 policyContentHash;
        uint8 notaryThreshold;
        uint8 reserveAttestationThreshold;
        uint8 adminMultisigThreshold;
        bool productionReady;
        uint256 publishedAt;
        uint256 version;
    }

    mapping(bytes32 jurisdictionId => JurisdictionPolicy) private _policies;
    mapping(bytes32 jurisdictionId => uint256) public policyVersion;

    event JurisdictionPolicyPublished(
        bytes32 indexed jurisdictionId,
        bytes32 policyContentHash,
        uint8 notaryThreshold,
        uint8 reserveAttestationThreshold,
        uint8 adminMultisigThreshold,
        bool productionReady,
        uint256 version
    );

    constructor(address admin) {
        require(admin != address(0), "OMNLJurisdictionPolicyRegistry: zero admin");
        _grantRole(DEFAULT_ADMIN_ROLE, admin);
        _grantRole(POLICY_PUBLISHER_ROLE, admin);
    }

    function publishPolicy(
        bytes32 jurisdictionId,
        bytes32 policyContentHash,
        uint8 notaryThreshold,
        uint8 reserveAttestationThreshold,
        uint8 adminMultisigThreshold,
        bool productionReady
    ) external onlyRole(POLICY_PUBLISHER_ROLE) {
        require(jurisdictionId != bytes32(0), "OMNLJurisdictionPolicyRegistry: zero id");
        require(policyContentHash != bytes32(0), "OMNLJurisdictionPolicyRegistry: zero hash");
        require(notaryThreshold > 0, "OMNLJurisdictionPolicyRegistry: notary threshold");
        require(reserveAttestationThreshold > 0, "OMNLJurisdictionPolicyRegistry: reserve threshold");
        require(adminMultisigThreshold > 0, "OMNLJurisdictionPolicyRegistry: admin threshold");

        uint256 nextVersion = policyVersion[jurisdictionId] + 1;
        policyVersion[jurisdictionId] = nextVersion;

        _policies[jurisdictionId] = JurisdictionPolicy({
            jurisdictionId: jurisdictionId,
            policyContentHash: policyContentHash,
            notaryThreshold: notaryThreshold,
            reserveAttestationThreshold: reserveAttestationThreshold,
            adminMultisigThreshold: adminMultisigThreshold,
            productionReady: productionReady,
            publishedAt: block.timestamp,
            version: nextVersion
        });

        emit JurisdictionPolicyPublished(
            jurisdictionId,
            policyContentHash,
            notaryThreshold,
            reserveAttestationThreshold,
            adminMultisigThreshold,
            productionReady,
            nextVersion
        );
    }

    function getPolicy(bytes32 jurisdictionId) external view returns (JurisdictionPolicy memory) {
        return _policies[jurisdictionId];
    }

    function isProductionReady(bytes32 jurisdictionId) external view returns (bool) {
        return _policies[jurisdictionId].productionReady;
    }
}
