const SCHEMA_VERSION = 1;

export class ShipLocationModel {
    static SCHEMA_VERSION = SCHEMA_VERSION;

    static create(shipNode, placeNode, {
        source = "manual",
        markerId = "",
        sceneId = "",
        managedConnection = false,
        previousViews = null
    } = {}) {
        const endpoints = this.resolveEndpoints(shipNode, placeNode);
        if (!endpoints) return null;
        const normalizedSource = source === "marker" ? "marker" : "manual";
        return {
            schemaVersion: SCHEMA_VERSION,
            shipNodeId: endpoints.shipNode.id,
            placeNodeId: endpoints.placeNode.id,
            source: normalizedSource,
            markerId: normalizedSource === "marker" ? String(markerId || "").trim() : "",
            sceneId: normalizedSource === "marker" ? String(sceneId || endpoints.placeNode.sceneId || "").trim() : "",
            managedConnection: managedConnection === true,
            previousViews: previousViews && typeof previousViews === "object"
                ? foundry.utils.deepClone(previousViews)
                : null
        };
    }

    static normalize(value, { sourceNode = null, targetNode = null } = {}) {
        if (!value || typeof value !== "object" || Array.isArray(value)) return null;
        return this.create(sourceNode, targetNode, value);
    }

    static createConnectionViews(shipNode, placeNode, {
        existingViews = null,
        preserveExistingViews = false
    } = {}) {
        const endpoints = this.resolveEndpoints(shipNode, placeNode);
        if (!endpoints) return {};
        const views = existingViews && typeof existingViews === "object"
            ? foundry.utils.deepClone(existingViews)
            : {};
        if (preserveExistingViews && Object.keys(views).length) return views;
        return {
            ...views,
            [endpoints.shipNode.id]: { ...(views[endpoints.shipNode.id] || {}), category: "place", role: "Current Location" },
            [endpoints.placeNode.id]: { ...(views[endpoints.placeNode.id] || {}), category: "ship", role: "Present" }
        };
    }

    static resolveEndpoints(leftNode = {}, rightNode = {}) {
        if (this.#isShip(leftNode) && this.#isPlace(rightNode)) return { shipNode: leftNode, placeNode: rightNode };
        if (this.#isShip(rightNode) && this.#isPlace(leftNode)) return { shipNode: rightNode, placeNode: leftNode };
        return null;
    }

    static isLocation(edge = {}) {
        return !!edge?.shipLocation;
    }

    static #isShip(node = {}) {
        return node?.kind === "nexus-entity" && node.entityType === "ship" && !!node.id;
    }

    static #isPlace(node = {}) {
        return (node?.kind === "nexus-entity" && node.entityType === "location" && !!node.id)
            || (node?.kind === "nexus-scene" && !!node.sceneId)
            || (node?.kind === "nexus-site" && !!node.parentSceneId && !!node.siteId);
    }
}
