const SCHEMA_VERSION = 2;

const AUTHORITY_PRESENTATION = Object.freeze({
    ruler: Object.freeze({
        type: "ruler",
        icon: "fas fa-crown",
        title: "Ruler",
        label: "Ruled by",
        emptyLabel: "No ruler appointed",
        npcRole: "Location Ruler",
        activeLabel: "Rules this Location",
        relationshipRole: "Rules",
        appointLabel: "Appoint as Location Ruler",
        removeLabel: "Remove as Location Ruler"
    }),
    owner: Object.freeze({
        type: "owner",
        icon: "fas fa-key",
        title: "Owner",
        label: "Owned by",
        emptyLabel: "No owner assigned",
        npcRole: "Location Owner",
        activeLabel: "Owns this Location",
        relationshipRole: "Owns",
        appointLabel: "Appoint as Location Owner",
        removeLabel: "Remove as Location Owner"
    })
});

export class LocationLeadershipModel {
    static SCHEMA_VERSION = SCHEMA_VERSION;

    static create(locationNode, leaderNode, { authorityType = "ruler" } = {}) {
        const endpoints = this.resolveEndpoints(locationNode, leaderNode);
        if (!endpoints) return null;
        return {
            schemaVersion: SCHEMA_VERSION,
            locationNodeId: endpoints.locationNode.id,
            leaderNodeId: endpoints.leaderNode.id,
            authorityType: this.normalizeAuthorityType(authorityType)
        };
    }

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

    static normalizeAuthorityType(value = "ruler") {
        return String(value || "").trim().toLocaleLowerCase() === "owner" ? "owner" : "ruler";
    }

    static getPresentation(value = "ruler") {
        const authorityType = typeof value === "object" ? value?.authorityType : value;
        return AUTHORITY_PRESENTATION[this.normalizeAuthorityType(authorityType)];
    }

    static canRepresent(leftNode = {}, rightNode = {}) {
        return !!this.resolveEndpoints(leftNode, rightNode);
    }

    static resolveEndpoints(leftNode = {}, rightNode = {}) {
        const leftLocation = this.#isEntityType(leftNode, "location");
        const rightLocation = this.#isEntityType(rightNode, "location");
        const leftNpc = this.#isEntityType(leftNode, "npc");
        const rightNpc = this.#isEntityType(rightNode, "npc");
        if (leftLocation && rightNpc) return { locationNode: leftNode, leaderNode: rightNode };
        if (rightLocation && leftNpc) return { locationNode: rightNode, leaderNode: leftNode };
        return null;
    }

    static isLeadership(edge = {}) {
        return !!edge?.locationLeadership && typeof edge.locationLeadership === "object";
    }

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