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

import "@openzeppelin/contracts/access/AccessControl.sol";
import "../RWAStorage.sol";
import "../libraries/RWAUriCodec.sol";
import "../interfaces/IRWADocumentFacet.sol";

/**
 * @title RWADocumentFacet
 * @notice Anchor document URIs (IPFS, Filecoin, Arweave, HTTPS, internal) with content hashes.
 */
contract RWADocumentFacet is AccessControl, IRWADocumentFacet {
    bytes32 public constant DOCUMENT_ADMIN_ROLE = keccak256("DOCUMENT_ADMIN_ROLE");

    constructor(address admin) {
        _grantRole(DEFAULT_ADMIN_ROLE, admin);
        _grantRole(DOCUMENT_ADMIN_ROLE, admin);
        RWAStorage.layout().documentAdmin = admin;
    }

    function anchorDocument(bytes32 assetId, string calldata uri, bytes32 contentHash)
        external
        onlyRole(DOCUMENT_ADMIN_ROLE)
        returns (uint256 docIndex)
    {
        require(contentHash != bytes32(0), "RWADocument: hash");
        RWAStorage.UriScheme scheme = RWAUriCodec.detectScheme(uri);
        require(scheme != RWAStorage.UriScheme.None, "RWADocument: scheme");

        RWAStorage.DocumentRef memory doc = RWAStorage.DocumentRef({
            contentHash: contentHash,
            uriHash: RWAUriCodec.uriHash(uri),
            scheme: scheme,
            updatedAt: uint64(block.timestamp)
        });

        RWAStorage.Layout storage l = RWAStorage.layout();
        l.assets[assetId].documents.push(doc);
        docIndex = l.assets[assetId].documents.length - 1;
        emit DocumentAnchored(assetId, contentHash, doc.uriHash, scheme, docIndex);
    }

    function setPrimaryContentHash(bytes32 assetId, bytes32 contentHash)
        external
        onlyRole(DOCUMENT_ADMIN_ROLE)
    {
        require(contentHash != bytes32(0), "RWADocument: hash");
        RWAStorage.layout().assets[assetId].primaryContentHash = contentHash;
        emit PrimaryContentHashSet(assetId, contentHash);
    }

    function documentCount(bytes32 assetId) external view returns (uint256) {
        return RWAStorage.layout().assets[assetId].documents.length;
    }

    function getDocument(bytes32 assetId, uint256 index)
        external
        view
        returns (bytes32 contentHash, bytes32 uriHash, RWAStorage.UriScheme scheme, uint64 updatedAt)
    {
        RWAStorage.DocumentRef storage doc = RWAStorage.layout().assets[assetId].documents[index];
        return (doc.contentHash, doc.uriHash, doc.scheme, doc.updatedAt);
    }
}
