import { ConnectionTargetResolver } from "../../connections/services/ConnectionTargetResolver.js";
import { LocationEntityModel } from "../models/LocationEntityModel.js";
import { LocationParentReference } from "../models/LocationParentReference.js";
import { CampaignEntityVisibilityManager } from "./CampaignEntityVisibilityManager.js";
import { CampaignEntityDisclosureManager } from "./CampaignEntityDisclosureManager.js";
import { LocationEntityStore } from "./LocationEntityStore.js";

export const LocationPlaceProvider = {
    type: "location",
    allowedParentTypes: ["scene", "site", "location"],
    pluralLabel: "Locations",

    listNodes({ includeHidden = false } = {}) {
        return LocationEntityStore.getLocations()
            .filter(entity => includeHidden || CampaignEntityVisibilityManager.canUserSee(entity, game.user))
            .map(entity => {
                const detailsVisible = CampaignEntityDisclosureManager.canUserViewDetails(entity, game.user);
                return {
                    key: `location:${entity.id}`,
                    type: "location",
                    objectId: entity.id,
                    parentKey: LocationParentReference.toNodeKey(entity.hierarchy?.parent),
                    entityId: entity.id,
                    entityType: "location",
                    name: LocationEntityModel.getName(entity),
                    subtitle: detailsVisible ? LocationEntityModel.getSubtitle(entity) : "Location",
                    searchText: detailsVisible ? LocationEntityModel.getSearchText(entity) : LocationEntityModel.getName(entity).toLocaleLowerCase(),
                    imageSrc: LocationEntityModel.getThumbnail(entity),
                    iconSrc: LocationEntityModel.getThumbnail(entity),
                    placementImageSrc: LocationEntityModel.getImage(entity),
                    accent: LocationEntityModel.getAccent(entity),
                    sourceModule: entity.sourceModule || "",
                    tags: detailsVisible ? entity.tags || [] : [],
                    journalEntryId: detailsVisible ? entity.journalEntryId || "" : "",
                    uuid: detailsVisible ? entity.uuid || "" : "",
                    primarySceneId: entity.scenes?.primarySceneId || null,
                    sceneId: entity.scenes?.primarySceneId || null,
                    connectionTarget: detailsVisible ? ConnectionTargetResolver.fromCampaignEntity(entity) : null,
                    isLocation: true,
                    isShop: false,
                    canContainChildren: true,
                    blocksPlayerDescendants: !detailsVisible,
                    suppressFactionGrouping: !detailsVisible,
                    isPlayerHidden: !CampaignEntityVisibilityManager.isVisibleToPlayers(entity),
                    playerVisibilityValue: CampaignEntityVisibilityManager.getPlayerVisibilityOverride(entity),
                    playerVisibilityLabel: CampaignEntityVisibilityManager.getPlayerVisibilityLabel(entity),
                    playerVisibilityIcon: CampaignEntityVisibilityManager.getPlayerVisibilityIcon(entity),
                    playerDisclosureValue: CampaignEntityDisclosureManager.getPlayerDisclosureOverride(entity),
                    playerDisclosureLabel: CampaignEntityDisclosureManager.getPlayerDisclosureLabel(entity, { includeEffective: true }),
                    playerDisclosureIcon: CampaignEntityDisclosureManager.getPlayerDisclosureIcon(entity)
                };
            });
    },

    async open(node) {
        const { openLocation } = await import("../../../api/locations.js");
        return openLocation(node.objectId);
    },

    setParent(node, parent) {
        return LocationEntityStore.updateLocation(node.objectId, {
            hierarchy: { parent: LocationParentReference.fromNode(parent) }
        });
    },

    deleteNode(node, options = {}) {
        return LocationEntityStore.deleteLocation(node.objectId, options);
    }
};
