const TOPICS = Object.freeze([
    {
        id: "authority",
        label: "Authority",
        question: "What legitimizes rule?",
        icon: "fas fa-crown",
        tenets: [
            {
                id: "authority.established-order",
                label: "Established Order",
                organizationDescription: "Legitimate authority comes from recognized institutions, inherited obligations, and established rank.",
                personalDescription: "They accept authority rooted in recognized institutions, inherited obligations, and established rank."
            },
            {
                id: "authority.earned-authority",
                label: "Earned Authority",
                organizationDescription: "Leadership must be justified through ability, service, or achievement.",
                personalDescription: "They believe leaders must prove themselves through ability, service, or achievement."
            }
        ]
    },
    {
        id: "change",
        label: "Change",
        question: "How should inherited customs be treated?",
        icon: "fas fa-hourglass-half",
        tenets: [
            {
                id: "change.sacred-tradition",
                label: "Sacred Tradition",
                organizationDescription: "Inherited laws and customs carry the wisdom and authority of earlier generations.",
                personalDescription: "They trust inherited laws and customs to carry the wisdom of earlier generations."
            },
            {
                id: "change.relentless-progress",
                label: "Relentless Progress",
                organizationDescription: "Old limits should be overcome through discovery, reform, or invention.",
                personalDescription: "They seek to overcome old limits through discovery, reform, or invention."
            }
        ]
    },
    {
        id: "society",
        label: "Society",
        question: "What does the individual owe society?",
        icon: "fas fa-people-group",
        tenets: [
            {
                id: "society.collective-duty",
                label: "Collective Duty",
                organizationDescription: "Individuals owe service and sacrifice to the greater community.",
                personalDescription: "They believe they owe service and sacrifice to the greater community."
            },
            {
                id: "society.personal-liberty",
                label: "Personal Liberty",
                organizationDescription: "Individuals must be free to choose their own lives and loyalties.",
                personalDescription: "They insist on the freedom to choose their own life and loyalties."
            }
        ]
    },
    {
        id: "wealth",
        label: "Wealth",
        question: "What is wealth for?",
        icon: "fas fa-coins",
        tenets: [
            {
                id: "wealth.prosperity-is-virtue",
                label: "Prosperity Is Virtue",
                organizationDescription: "Wealth, enterprise, and material success are signs of strength.",
                personalDescription: "They see wealth, enterprise, and material success as signs of strength."
            },
            {
                id: "wealth.shared-plenty",
                label: "Shared Plenty",
                organizationDescription: "Resources should sustain the community rather than enrich a privileged few.",
                personalDescription: "They believe resources should sustain the community rather than enrich a privileged few."
            }
        ]
    },
    {
        id: "world",
        label: "The World",
        question: "How should land, nature, and resources be treated?",
        icon: "fas fa-earth-americas",
        tenets: [
            {
                id: "world.stewardship",
                label: "Stewardship",
                organizationDescription: "Power carries responsibility for the people, land, and worlds under one's care.",
                personalDescription: "They feel responsible for the people, land, and worlds placed in their care."
            },
            {
                id: "world.dominion",
                label: "Dominion",
                organizationDescription: "Nature, territory, and resources exist to be mastered and put to use.",
                personalDescription: "They believe nature, territory, and resources exist to be mastered and put to use."
            }
        ]
    },
    {
        id: "knowledge",
        label: "Knowledge",
        question: "Who should control important knowledge?",
        icon: "fas fa-book-open",
        tenets: [
            {
                id: "knowledge.open-knowledge",
                label: "Open Knowledge",
                organizationDescription: "Discovery becomes valuable when it is shared.",
                personalDescription: "They believe discoveries become valuable when shared with others."
            },
            {
                id: "knowledge.guarded-knowledge",
                label: "Guarded Knowledge",
                organizationDescription: "Dangerous or powerful knowledge belongs only in responsible hands.",
                personalDescription: "They believe dangerous or powerful knowledge should remain in responsible hands."
            }
        ]
    },
    {
        id: "conflict",
        label: "Conflict",
        question: "How is security best achieved?",
        icon: "fas fa-shield-halved",
        tenets: [
            {
                id: "conflict.martial-honor",
                label: "Martial Honor",
                organizationDescription: "Courage, discipline, and strength of arms are worthy and necessary.",
                personalDescription: "They prize courage, discipline, and strength of arms as worthy and necessary."
            },
            {
                id: "conflict.peace-through-accord",
                label: "Peace Through Accord",
                organizationDescription: "Lasting security comes through diplomacy, compromise, and mutual obligation.",
                personalDescription: "They seek lasting security through diplomacy, compromise, and mutual obligation."
            }
        ]
    },
    {
        id: "purpose",
        label: "Purpose",
        question: "What matters when existence is threatened?",
        icon: "fas fa-star",
        tenets: [
            {
                id: "purpose.transcendent-purpose",
                label: "Transcendent Purpose",
                organizationDescription: "Life must serve a calling greater than comfort, wealth, or survival.",
                personalDescription: "They believe their life must serve a calling greater than comfort, wealth, or survival."
            },
            {
                id: "purpose.survival-above-principle",
                label: "Survival Above Principle",
                organizationDescription: "Principles are meaningless if the faction does not endure.",
                personalDescription: "They will set principle aside when necessary to survive."
            }
        ]
    }
]);

export class IdeologyCatalog {
    static SCHEMA_VERSION = 1;
    static ORGANIZATION_PERSPECTIVE = "organization";
    static PERSONAL_PERSPECTIVE = "personal";

    static getTopics(options = {}) {
        const perspective = this.#normalizePerspective(options.perspective);
        return TOPICS.map(topic => this.#resolveTopic(topic, perspective));
    }

    static getTopic(topicId = "", options = {}) {
        const topic = TOPICS.find(entry => entry.id === String(topicId || "").trim());
        return topic ? this.#resolveTopic(topic, this.#normalizePerspective(options.perspective)) : null;
    }

    static getTenet(topicId = "", tenetId = "", options = {}) {
        const topic = TOPICS.find(entry => entry.id === String(topicId || "").trim());
        const tenet = topic?.tenets.find(entry => entry.id === String(tenetId || "").trim());
        return tenet ? this.#resolveTenet(tenet, this.#normalizePerspective(options.perspective)) : null;
    }

    static normalize(ideology = {}) {
        const usedTopics = new Set();
        const selections = [];
        for (const selection of Array.isArray(ideology?.selections) ? ideology.selections : []) {
            const topicId = String(selection?.topicId || "").trim();
            const tenetId = String(selection?.tenetId || "").trim();
            if (!topicId || usedTopics.has(topicId) || !this.getTenet(topicId, tenetId)) continue;
            usedTopics.add(topicId);
            selections.push({ topicId, tenetId });
        }
        return { schemaVersion: this.SCHEMA_VERSION, selections };
    }

    static resolve(ideology = {}, options = {}) {
        const perspective = this.#normalizePerspective(options.perspective);
        return this.normalize(ideology).selections.map(selection => {
            const topic = this.getTopic(selection.topicId, { perspective });
            const tenet = this.getTenet(selection.topicId, selection.tenetId, { perspective });
            return {
                topicId: topic.id,
                topicLabel: topic.label,
                topicQuestion: topic.question,
                topicIcon: topic.icon,
                tenetId: tenet.id,
                tenetLabel: tenet.label,
                tenetDescription: tenet.description
            };
        });
    }

    static #resolveTopic(topic, perspective) {
        return {
            id: topic.id,
            label: topic.label,
            question: topic.question,
            icon: topic.icon,
            tenets: topic.tenets.map(tenet => this.#resolveTenet(tenet, perspective))
        };
    }

    static #resolveTenet(tenet, perspective) {
        return {
            ...tenet,
            description: perspective === this.PERSONAL_PERSPECTIVE
                ? tenet.personalDescription
                : tenet.organizationDescription
        };
    }

    static #normalizePerspective(perspective = this.ORGANIZATION_PERSPECTIVE) {
        return perspective === this.PERSONAL_PERSPECTIVE
            ? this.PERSONAL_PERSPECTIVE
            : this.ORGANIZATION_PERSPECTIVE;
    }
}
