import { useTask, useThrelte } from '@threlte/core';
import { useXR } from '@threlte/xr';
import { getContext, setContext } from 'svelte';
import { fromStore } from 'svelte/store';
import {} from 'three';
const key = Symbol('anchors-context');
export const provideAnchors = () => {
    const { renderer } = useThrelte();
    const { isPresenting: isPresentingStore } = useXR();
    const isPresenting = fromStore(isPresentingStore);
    const map = new WeakMap();
    const createAnchor = (position, quaternion) => {
        const space = renderer.xr.getReferenceSpace();
        const frame = renderer.xr.getFrame();
        if (!space || !frame)
            return;
        const pose = new XRRigidTransform({ x: position.x, y: position.y, z: position.z }, { x: quaternion.x, y: quaternion.y, z: quaternion.z, w: quaternion.w });
        return frame.createAnchor?.(pose, space);
    };
    const bindAnchorObject = (anchor, object) => {
        map.set(anchor, object);
    };
    const unbindAnchorObject = (anchor) => {
        map.delete(anchor);
    };
    const persist = async (anchor) => {
        return anchor.requestPersistentHandle?.();
    };
    const restore = async (uuid) => {
        const session = renderer.xr.getSession();
        return session?.restorePersistentAnchor?.(uuid);
    };
    const remove = async (uuid) => {
        const session = renderer.xr.getSession();
        await session?.deletePersistentAnchor?.(uuid);
    };
    const getAnchorPose = (anchor) => {
        const space = renderer.xr.getReferenceSpace();
        const frame = renderer.xr.getFrame();
        if (!space || !frame)
            return;
        return frame.getPose(anchor.anchorSpace, space);
    };
    useTask(() => {
        const space = renderer.xr.getReferenceSpace();
        const frame = renderer.xr.getFrame();
        if (!space || !frame?.trackedAnchors) {
            return;
        }
        for (const anchor of frame.trackedAnchors) {
            const object3d = map.get(anchor);
            if (!object3d) {
                continue;
            }
            const anchorPose = frame.getPose(anchor.anchorSpace, space);
            if (!anchorPose) {
                continue;
            }
            object3d.matrixAutoUpdate = false;
            object3d.matrix.fromArray(anchorPose.transform.matrix);
        }
    }, {
        running: () => isPresenting.current,
    });
    setContext(key, {
        createAnchor,
        bindAnchorObject,
        unbindAnchorObject,
        persist,
        restore,
        remove,
        getAnchorPose,
    });
};
export const useAnchors = () => {
    return getContext(key);
};
