import { ConnectionStore } from "./ConnectionStore.js";
import { ConnectionTargetResolver } from "./ConnectionTargetResolver.js";

export class ShipCrewService {
    static getCrew(shipTarget, { user = game.user, includeHidden = false } = {}) {
        const shipNodeId = ConnectionTargetResolver.getNodeId(shipTarget);
        return (ConnectionStore.getGraphContext().adjacency.get(shipNodeId) || [])
            .filter(({ edge, node }) => edge.relationType === "ship-crew" && node?.kind === "nexus-entity" && node.entityType === "npc")
            .filter(({ edge, node }) => includeHidden || (ConnectionStore.canUserSeeConnection(edge, user) && ConnectionTargetResolver.canUserSeeNode(node, user)))
            .map(({ edge, node }) => {
                const display = ConnectionTargetResolver.resolveDisplayNodeSync(node) || node;
                return {
                    edgeId: edge.id,
                    nodeId: node.id,
                    entityId: node.entityId || "",
                    name: display.name || "Unknown Crew Member",
                    imageSrc: display.img || "",
                    subtitle: edge.views?.[shipNodeId]?.role || display.subtitle || "Crew"
                };
            })
            .sort((left, right) => left.name.localeCompare(right.name));
    }

    static async addCrew(shipTarget, npcTarget) {
        if (!game.user?.isGM) return null;
        const shipNode = this.#nodeLike(shipTarget);
        const npcNode = this.#nodeLike(npcTarget);
        if (shipNode?.entityType !== "ship" || npcNode?.entityType !== "npc") {
            throw new Error("Ship crew requires one Ship and one Person.");
        }
        const selected = (ConnectionStore.getGraphContext().adjacency.get(shipNode.id) || [])
            .find(({ node }) => node.id === npcNode.id)?.edge || null;
        const views = {
            ...(selected?.views || {}),
            [shipNode.id]: { ...(selected?.views?.[shipNode.id] || {}), category: "crew", role: "Crew" },
            [npcNode.id]: { ...(selected?.views?.[npcNode.id] || {}), category: "ship", role: `Crew of ${shipNode.name || "Ship"}` }
        };
        if (selected) {
            if (selected.shipCaptain) return selected;
            return ConnectionStore.updateConnection(selected.id, { relationType: "ship-crew", views });
        }
        return ConnectionStore.addConnection(shipNode, npcNode, {
            relationType: "ship-crew",
            sourceView: views[shipNode.id],
            targetView: views[npcNode.id]
        });
    }

    static async removeCrew(shipTarget, npcTarget) {
        if (!game.user?.isGM) return false;
        const shipNodeId = ConnectionTargetResolver.getNodeId(shipTarget);
        const npcNodeId = ConnectionTargetResolver.getNodeId(npcTarget);
        const edge = (ConnectionStore.getGraphContext().adjacency.get(shipNodeId) || [])
            .find(({ node }) => node.id === npcNodeId)?.edge || null;
        if (!edge || edge.shipCaptain || edge.relationType !== "ship-crew") return false;
        await ConnectionStore.updateConnection(edge.id, { relationType: "" });
        return true;
    }

    static #nodeLike(target) {
        const id = ConnectionTargetResolver.getNodeId(target);
        return id ? { ...(ConnectionStore.getNode(id) || {}), ...target, id } : null;
    }
}
