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

import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import {IERC20Permit} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol";
import {IERC5267} from "@openzeppelin/contracts/interfaces/IERC5267.sol";
import {IeMoneyToken} from "../../emoney/interfaces/IeMoneyToken.sol";
import {IRegulatedAssetMetadata} from "../../interfaces/IRegulatedAssetMetadata.sol";

/**
 * @title ICompliantFiatTokenV2
 * @notice Canonical interface for GRU c* V2 compliant money tokens.
 */
interface ICompliantFiatTokenV2 is IERC20Metadata, IERC20Permit, IERC5267, IeMoneyToken, IRegulatedAssetMetadata {
    event TokenURIUpdated(string tokenURI);
    event SymbolDisplayUpdated(string symbolDisplay);
    event LegacyAliasAdded(string aliasValue);
    event ForwardCanonicalUpdated(bool forwardCanonical);
    event SupplyControlsUpdated(uint256 supplyCap, uint256 mintingPeriodCap, uint256 mintingPeriodDuration);
    event GovernanceProfileUpdated(bytes32 governanceProfileId);
    event SupervisionProfileUpdated(bytes32 supervisionProfileId);
    event StorageNamespaceUpdated(bytes32 storageNamespace);
    event PrimaryJurisdictionUpdated(string jurisdiction);
    event RegulatoryDisclosureURIUpdated(string disclosureURI);
    event ReportingURIUpdated(string reportingURI);
    event CanonicalUnderlyingAssetUpdated(address canonicalUnderlyingAsset);
    event SupervisionConfigurationUpdated(
        bool supervisionRequired,
        bool governmentApprovalRequired,
        uint256 minimumUpgradeNoticePeriod
    );
    event RegulatoryApprovalRecorded(bytes32 indexed approvalId, string actionType, bytes32 referenceHash);
    event SupervisoryNoticeRecorded(bytes32 indexed noticeId, string category, string uri);
    event AuthorizationUsed(address indexed authorizer, address indexed to, bytes32 indexed nonce, uint256 value);
    event AuthorizationCanceled(address indexed authorizer, bytes32 indexed nonce);

    function assetId() external view returns (bytes32);
    function assetVersionId() external view returns (bytes32);
    function owner() external view returns (address);
    function currencyCode() external view returns (string memory);
    function versionTag() external view returns (string memory);
    function symbolDisplay() external view returns (string memory);
    function tokenURI() external view returns (string memory);
    function forwardCanonical() external view returns (bool);
    function governanceController() external view returns (address);
    function legacyAliases() external view returns (string[] memory);
    function authorizationState(address authorizer, bytes32 nonce) external view returns (bool);
    function transferOwnership(address newOwner) external;
    function setGovernanceController(address governanceController_) external;
    function mint(address to, uint256 amount) external;
    function burn(uint256 amount) external;
    function transferWithAuthorization(
        address from,
        address to,
        uint256 value,
        uint256 validAfter,
        uint256 validBefore,
        bytes32 nonce,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;
    function receiveWithAuthorization(
        address from,
        address to,
        uint256 value,
        uint256 validAfter,
        uint256 validBefore,
        bytes32 nonce,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;
    function cancelAuthorization(address authorizer, bytes32 nonce, uint8 v, bytes32 r, bytes32 s) external;
    function setGovernanceProfileId(bytes32 governanceProfileId_) external;
    function setSupervisionProfileId(bytes32 supervisionProfileId_) external;
    function setStorageNamespace(bytes32 storageNamespace_) external;
    function setPrimaryJurisdiction(string calldata jurisdiction_) external;
    function setRegulatoryDisclosureURI(string calldata disclosureURI_) external;
    function setReportingURI(string calldata reportingURI_) external;
    function setCanonicalUnderlyingAsset(address canonicalUnderlyingAsset_) external;
    function setSupervisionConfiguration(
        bool supervisionRequired_,
        bool governmentApprovalRequired_,
        uint256 minimumUpgradeNoticePeriod_
    ) external;
    function recordRegulatoryApproval(bytes32 approvalId, string calldata actionType, bytes32 referenceHash) external;
    function recordSupervisoryNotice(bytes32 noticeId, string calldata category, string calldata uri) external;
}
