import { kinds } from "nostr-tools";
import { canHaveEncryptedContent, EncryptedContentSymbol, getEncryptedContent, getEncryptedContentEncryptionMethods, hasEncryptedContent, isEncryptedContentUnlocked, lockEncryptedContent, setEncryptedContentCache, setEncryptedContentEncryptionMethod, } from "./encrypted-content.js";
/** Symbol for caching hidden content. Alias for {@link EncryptedContentSymbol} */
export const HiddenContentSymbol = EncryptedContentSymbol;
/** Alias for {@link getEncryptedContentEncryptionMethods} */
export const getHiddenContentEncryptionMethods = getEncryptedContentEncryptionMethods;
/** Various event kinds that can have hidden content */
export const HiddenContentKinds = new Set([setEncryptedContentEncryptionMethod(kinds.DraftLong, "nip04")]);
/** Sets the encryption method for hidden content on a kind */
export function setHiddenContentEncryptionMethod(kind, method) {
    HiddenContentKinds.add(setEncryptedContentEncryptionMethod(kind, method));
    return kind;
}
/** Checks if an event can have hidden content */
export function canHaveHiddenContent(kind) {
    return canHaveEncryptedContent(kind) && HiddenContentKinds.has(kind);
}
/** Checks if an event has hidden content */
export function hasHiddenContent(event) {
    return canHaveHiddenContent(event.kind) && hasEncryptedContent(event);
}
/** Checks if the hidden content is unlocked and casts it to the {@link UnlockedEncryptedContent} type */
export function isHiddenContentUnlocked(event) {
    if (!canHaveHiddenContent(event.kind))
        return false;
    return isEncryptedContentUnlocked(event) && Reflect.has(event, HiddenContentSymbol) === true;
}
export function getHiddenContent(event) {
    if (!canHaveHiddenContent(event.kind))
        return undefined;
    if (isHiddenContentUnlocked(event))
        return event[EncryptedContentSymbol];
    return getEncryptedContent(event);
}
/**
 * Unlocks the hidden content in the event
 * @param event The event with content to decrypt
 * @param signer A signer to use to decrypt the content
 * @throws
 */
export async function unlockHiddenContent(event, signer, override) {
    if (!canHaveHiddenContent(event.kind))
        throw new Error("Event kind does not support hidden content");
    // If the encrypted content is already unlocked, return the cached value
    if (isEncryptedContentUnlocked(event))
        return event[EncryptedContentSymbol];
    // Get the encryption method from the signer
    const encryption = getEncryptedContentEncryptionMethods(event.kind, signer, override);
    // Decrypt the content using the events pubkey
    const plaintext = await encryption.decrypt(event.pubkey, event.content);
    // Set the cached value
    setHiddenContentCache(event, plaintext);
    // Return the decrypted content
    return plaintext;
}
/**
 * Sets the hidden content on an event and updates it if its part of an event store
 * @throws If the event kind does not support hidden content
 */
export function setHiddenContentCache(event, plaintext) {
    if (!canHaveHiddenContent(event.kind))
        throw new Error("Event kind does not support hidden content");
    // Set the encrypted content
    setEncryptedContentCache(event, plaintext);
}
/** Removes the unencrypted hidden content on an event */
export function lockHiddenContent(event) {
    lockEncryptedContent(event);
}
