import { NexusLineageManager } from "./NexusLineageManager.js";
import { NexusSceneTransitionEffects } from "./NexusSceneTransitionEffects.js";
import { LocationSceneService } from "../../campaign-entities/services/LocationSceneService.js";

const MODULE_ID = "augur-nexus";

export class NexusSceneNavigationManager {
    static NAVIGATION_FLAG = "navigation";

    static getSceneNavigation(scene) {
        const navigation = scene?.getFlag(MODULE_ID, this.NAVIGATION_FLAG) || null;
        if (navigation?.parentSceneId && game.scenes.get(navigation.parentSceneId)) return navigation;
        return LocationSceneService.getReturnNavigation(scene);
    }

    static async setSceneNavigation(scene, {
        parentSceneId = null,
        parentSiteId = null,
        transitionStyle = "scene-default",
        transitionContext = {}
    } = {}) {
        if (!scene) throw new Error("No scene provided.");

        await NexusLineageManager.setSceneParent(scene, {
            parentSceneId,
            parentSiteId
        });

        if (!parentSceneId) {
            await scene.unsetFlag(MODULE_ID, this.NAVIGATION_FLAG);
            return scene;
        }

        await scene.setFlag(MODULE_ID, this.NAVIGATION_FLAG, {
            parentSceneId,
            sceneId: parentSceneId,
            parentSiteId: parentSiteId || null,
            transitionStyle,
            transitionContext: transitionContext || {}
        });
        return scene;
    }

    static async returnToParent(scene = canvas.scene) {
        const navigation = this.getSceneNavigation(scene);
        if (!navigation) return false;
        return NexusSceneTransitionEffects.returnToParent(scene, this.#resolveReturnFocus(scene, navigation));
    }

    static #resolveReturnFocus(scene, navigation) {
        const parentScene = game.scenes.get(navigation.parentSceneId) || null;
        if (!parentScene) return navigation;

        const parentSiteId = navigation.parentSiteId || null;
        const locationId = navigation.locationId || null;
        const childSceneId = scene?.id || null;
        const marker = parentScene.tiles?.contents?.find(tile => {
            const target = tile.flags?.[MODULE_ID]?.marker?.target || null;
            if (!target) return false;
            if (parentSiteId) {
                return target.kind === "nexus-site"
                    && target.parentSceneId === parentScene.id
                    && target.siteId === parentSiteId;
            }
            if (locationId) {
                return target.kind === "campaign-entity"
                    && target.entityType === "location"
                    && target.entityId === locationId;
            }
            return target.kind === "nexus-scene" && target.sceneId === childSceneId;
        }) || (parentSiteId ? this.#findLegacySitePlaceable(parentScene, parentSiteId) : null);

        if (!marker) return navigation;
        return {
            ...navigation,
            transitionStyle: "focus-placeable",
            transitionContext: {
                placeableId: marker.id,
                documentName: marker.documentName || "Tile"
            }
        };
    }

    static #findLegacySitePlaceable(scene, siteId) {
        return scene.tiles?.contents?.find(tile => tile.flags?.[MODULE_ID]?.siteId === siteId)
            || scene.notes?.contents?.find(note => note.flags?.[MODULE_ID]?.siteId === siteId)
            || null;
    }
}
