//
// Copyright 2025 DXOS.org
//
import { useCallback, useEffect, useMemo, useState } from 'react';
import { Filter, Obj } from '@dxos/echo';
import { Function, Script, getUserFunctionIdInMetadata } from '@dxos/functions';
import { InvocationOutcome } from '@dxos/functions-runtime';
import { createInvocationSpans } from '@dxos/functions-runtime';
import { useQuery, useQueue } from '@dxos/react-client/echo';
import { getUuidFromDxn } from './utils';
/**
 * Maps invocation target identifiers to readable script names.
 */
export const useFunctionNameResolver = ({ db }) => {
    const functions = useQuery(db, Filter.type(Function.Function));
    return useCallback((invocationTargetId) => {
        if (!invocationTargetId) {
            return undefined;
        }
        const uuidPart = getUuidFromDxn(invocationTargetId);
        const matchingFunction = functions.find((fn) => getUserFunctionIdInMetadata(Obj.getMeta(fn)) === uuidPart);
        return matchingFunction?.name;
    }, [functions]);
};
export const useInvocationTargetsForScript = (target) => {
    const db = Obj.instanceOf(Script.Script, target) ? Obj.getDatabase(target) : undefined;
    const functions = useQuery(db, Filter.type(Function.Function));
    return useMemo(() => {
        if (!Obj.instanceOf(Script.Script, target)) {
            return undefined;
        }
        return new Set(functions
            .filter((fn) => fn.source?.target?.id === target.id)
            .map((fn) => getUserFunctionIdInMetadata(Obj.getMeta(fn))));
    }, [functions, target]);
};
export const useInvocationSpans = ({ queueDxn, target }) => {
    const functionsForScript = useInvocationTargetsForScript(target);
    const invocationsQueue = useQueue(queueDxn, {
        pollInterval: 1000,
    });
    const invocationSpans = useMemo(() => createInvocationSpans(invocationsQueue?.objects), [invocationsQueue?.objects]);
    const scopedInvocationSpans = useMemo(() => {
        if (functionsForScript) {
            return invocationSpans.filter((span) => {
                if (!span.invocationTarget) {
                    return false;
                }
                const targetId = span.invocationTarget.dxn;
                const uuidPart = getUuidFromDxn(targetId);
                return uuidPart ? functionsForScript?.has(uuidPart) : false;
            });
        }
        else if (target) {
            return invocationSpans.filter((span) => span.invocationTarget?.dxn.toString() === Obj.getDXN(target).toString());
        }
        return invocationSpans;
    }, [functionsForScript, target, invocationSpans]);
    // If there are any pending spans, update the current time every second.
    const [_, update] = useState({});
    useEffect(() => {
        if (scopedInvocationSpans.some((span) => span.outcome === InvocationOutcome.PENDING)) {
            const interval = setInterval(() => update({}), 1_000);
            return () => clearInterval(interval);
        }
    }, [scopedInvocationSpans]);
    return scopedInvocationSpans;
};
//# sourceMappingURL=hooks.js.map