import { makeAppObjectRepo } from "@vived/core";
import { ParametricLine, Vector2, Vector3 } from "@vived/core";
import { makeMockSceneRayPickUC } from "../../Babylon/Mocks/MockSceneRayPickUC";
import { makeBaseAppState } from "../../BaseApp";
import { makeChallengeEntityMock } from "../../Challenge/Mocks/ChallengeEntityMock";
import { LabelDropDragMode, makeLabelDropRepo, } from "../Entities/LabelDropRepo";
import { makeDragLabelDropUC } from "./DragLabelDropUC";
function makeTestRig() {
    const appObjects = makeAppObjectRepo();
    const challenge = makeChallengeEntityMock(appObjects);
    const baseApp = makeBaseAppState(appObjects.getOrCreate("BaseApp"));
    const labelDropAO = appObjects.getOrCreate("labelDrop");
    const labelDrop = makeLabelDropRepo(labelDropAO);
    const changeObserver = jest.fn();
    labelDrop.addChangeObserver(changeObserver);
    const mockRayPick = makeMockSceneRayPickUC(appObjects);
    const mockPick = jest.fn().mockReturnValue({ appObjectID: "obj" });
    mockRayPick.sceneRayPick = mockPick;
    const dragLabelDropUC = makeDragLabelDropUC(labelDropAO);
    challenge.selectedChallenge = "LABEL_DROP";
    baseApp.isAuthoring = false;
    return {
        appObjects,
        labelDrop,
        dragLabelDropUC,
        changeObserver,
        baseApp,
        challenge,
        mockPick,
    };
}
describe("Drag Label Drop UC", () => {
    it("initializes id, screenMode, position, and alpha", () => {
        const { dragLabelDropUC, labelDrop } = makeTestRig();
        expect(labelDrop.draggingID).toBeUndefined();
        dragLabelDropUC.initialize("id1", new Vector2(1, 2));
        expect(labelDrop.draggingID).toEqual("id1");
        expect(labelDrop.dragMode).toEqual(LabelDropDragMode.SCREEN);
        expect(labelDrop.dragAlpha).toEqual(1);
        expect(labelDrop.screenPosition).toEqual(new Vector2(1, 2));
    });
    it("Does not initialize if challenge is not label drop", () => {
        const { dragLabelDropUC, labelDrop, challenge } = makeTestRig();
        challenge.selectedChallenge = "NONE";
        dragLabelDropUC.initialize("id1", Vector2.Zero());
        expect(labelDrop.draggingID).toBeUndefined();
    });
    it("Does not initialize if authoring", () => {
        const { dragLabelDropUC, labelDrop, baseApp } = makeTestRig();
        baseApp.isAuthoring = true;
        dragLabelDropUC.initialize("id1", Vector2.Zero());
        expect(labelDrop.draggingID).toBeUndefined();
    });
    it("Can set the 2D position", () => {
        const { dragLabelDropUC, labelDrop } = makeTestRig();
        dragLabelDropUC.initialize("id", Vector2.Zero());
        dragLabelDropUC.setPosition2D(new Vector2(1, 2));
        expect(labelDrop.screenPosition).toEqual(new Vector2(1, 2));
    });
    it("Does not set the 2D position if it did not initialize", () => {
        const { dragLabelDropUC, labelDrop } = makeTestRig();
        labelDrop.screenPosition = Vector2.Zero();
        dragLabelDropUC.setPosition2D(new Vector2(1, 2));
        expect(labelDrop.screenPosition).not.toEqual(new Vector2(1, 2));
    });
    it("Submits the object hit when released", () => {
        const { dragLabelDropUC, labelDrop, mockPick } = makeTestRig();
        mockPick.mockReturnValue({
            worldPickPoint: new Vector3(1, 2, 3),
            hit: true,
            normal: new Vector3(4, 5, 6),
            objectPickMeta: {
                appObjectID: "appObj1",
            },
        });
        dragLabelDropUC.initialize("labelDrop1", Vector2.Zero());
        labelDrop.submitLabelDrop = jest.fn();
        dragLabelDropUC.release(ParametricLine.Forward());
        expect(labelDrop.submitLabelDrop).toHaveBeenCalledWith("labelDrop1", "appObj1");
    });
    it("submits a label drop answer if an app object is hit", async () => {
        jest.useFakeTimers();
        const { dragLabelDropUC, labelDrop, mockPick } = makeTestRig();
        mockPick.mockReturnValue({
            worldPickPoint: new Vector3(1, 2, 3),
            hit: true,
            normal: new Vector3(4, 5, 6),
            objectPickMeta: {
                appObjectID: "appObj1",
            },
        });
        labelDrop.submitLabelDrop = jest.fn();
        dragLabelDropUC.initialize("labelDrop1", Vector2.Zero());
        dragLabelDropUC.release(ParametricLine.Forward());
        expect(labelDrop.submitLabelDrop).toHaveBeenCalled();
    });
    it("Does not submit a label drop answer if an app object is not hit", async () => {
        const { dragLabelDropUC, labelDrop, mockPick } = makeTestRig();
        mockPick.mockReturnValue({
            worldPickPoint: new Vector3(1, 2, 3),
            hit: false,
            normal: new Vector3(4, 5, 6),
        });
        labelDrop.submitLabelDrop = jest.fn();
        dragLabelDropUC.initialize("labelDrop1", Vector2.Zero());
        dragLabelDropUC.release(ParametricLine.Forward());
        expect(labelDrop.submitLabelDrop).not.toHaveBeenCalled();
    });
    it("Does not submit if no object hit on release", () => {
        const { dragLabelDropUC, labelDrop, mockPick } = makeTestRig();
        mockPick.mockReturnValue({
            worldPickPoint: new Vector3(1, 2, 3),
            hit: false,
            normal: new Vector3(4, 5, 6),
            objectPickMeta: {},
        });
        dragLabelDropUC.initialize("labelDrop1", Vector2.Zero());
        labelDrop.submitLabelDrop = jest.fn();
        dragLabelDropUC.release(ParametricLine.Forward());
        expect(labelDrop.submitLabelDrop).not.toHaveBeenCalled();
    });
    it("Does not wait to animate if no object is hit", async () => {
        jest.useFakeTimers();
        const { dragLabelDropUC, labelDrop, mockPick } = makeTestRig();
        mockPick.mockReturnValue({
            worldPickPoint: new Vector3(1, 2, 3),
            hit: false,
            normal: new Vector3(4, 5, 6),
        });
        dragLabelDropUC.initialize("labelDrop1", Vector2.Zero());
        dragLabelDropUC.onFinishRelease();
        jest.advanceTimersByTime(1000);
        expect(labelDrop.dragAlpha).toEqual(0);
    });
});
//# sourceMappingURL=DragLabelDropUC.test.js.map