import { LocationEntityStore } from "./LocationEntityStore.js";

const MODULE_ID = "augur-nexus";

const ENTITY_TYPES = {
    location: {
        label: "Location",
        settingKey: "playerLocationDisclosure",
        update: (idOrUuid, patch) => LocationEntityStore.updateLocation(idOrUuid, patch)
    }
};

export class CampaignEntityDisclosureManager {
    static VALUES = new Set(["inherit", "limited", "full"]);
    static DEFAULTS = new Set(["limited", "full"]);

    static getConfig(entityOrType = "location") {
        const type = this.normalizeEntityType(typeof entityOrType === "string" ? entityOrType : entityOrType?.type);
        return ENTITY_TYPES[type];
    }

    static normalizeEntityType(type = "location") {
        return ENTITY_TYPES[type] ? type : "location";
    }

    static normalizePlayerDisclosure(value = "inherit") {
        return this.VALUES.has(value) ? value : "inherit";
    }

    static getGlobalPlayerDisclosure(entityOrType = "location") {
        const value = game.settings.get(MODULE_ID, this.getConfig(entityOrType).settingKey) || "full";
        return this.DEFAULTS.has(value) ? value : "full";
    }

    static getPlayerDisclosureOverride(entityOrValue = "inherit") {
        return typeof entityOrValue === "string"
            ? this.normalizePlayerDisclosure(entityOrValue)
            : this.normalizePlayerDisclosure(entityOrValue?.access?.playerDisclosure);
    }

    static getEffectivePlayerDisclosure(entity = {}) {
        const override = this.getPlayerDisclosureOverride(entity);
        return override === "inherit" ? this.getGlobalPlayerDisclosure(entity) : override;
    }

    static canUserViewDetails(entity = {}, user = game.user) {
        return user?.isGM || this.getEffectivePlayerDisclosure(entity) === "full";
    }

    static getPlayerDisclosureLabel(entityOrValue = "inherit", { includeEffective = false } = {}) {
        const override = this.getPlayerDisclosureOverride(entityOrValue);
        if (override === "full") return "Visited";
        if (override === "limited") return "Unvisited";
        if (!includeEffective || typeof entityOrValue === "string") return "Global";
        return `Global (${this.getEffectivePlayerDisclosure(entityOrValue) === "full" ? "Visited" : "Unvisited"})`;
    }

    static getPlayerDisclosureIcon(entityOrValue = "inherit") {
        const override = this.getPlayerDisclosureOverride(entityOrValue);
        if (override === "full") return "fas fa-map-location-dot";
        if (override === "limited") return "fas fa-map";
        return "fas fa-layer-group";
    }

    static async setGlobalPlayerDisclosure(entityOrType = "location", value = "full") {
        if (!game.user?.isGM) return this.getGlobalPlayerDisclosure(entityOrType);
        const type = this.normalizeEntityType(typeof entityOrType === "string" ? entityOrType : entityOrType?.type);
        const normalized = this.DEFAULTS.has(value) ? value : "full";
        await game.settings.set(MODULE_ID, this.getConfig(type).settingKey, normalized);
        Hooks.callAll("augurNexusCampaignEntityDisclosureChanged", {
            reason: "globalSettingChanged",
            entityType: type,
            disclosure: normalized
        });
        return normalized;
    }

    static async setPlayerDisclosureOverride(idOrUuid, entityOrType = "location", value = "inherit") {
        if (!game.user?.isGM) return null;
        const type = this.normalizeEntityType(typeof entityOrType === "string" ? entityOrType : entityOrType?.type);
        const normalized = this.normalizePlayerDisclosure(value);
        const entity = await this.getConfig(type).update(idOrUuid, {
            access: { playerDisclosure: normalized }
        });
        Hooks.callAll("augurNexusCampaignEntityDisclosureChanged", {
            reason: "entityDisclosureOverrideChanged",
            entityType: type,
            entity
        });
        return entity;
    }
}
