import { CampaignEntityVisibilityManager } from "../../campaign-entities/services/CampaignEntityVisibilityManager.js";
import { CampaignEntityJournalStore } from "../../campaign-entities/services/CampaignEntityJournalStore.js";
import { FactionEntityModel } from "../../campaign-entities/models/FactionEntityModel.js";
import { ConnectionStore } from "../../connections/services/ConnectionStore.js";
import { OwnershipService } from "../../connections/services/OwnershipService.js";

const TRANSPARENT_STYLE = Object.freeze({
    active: false,
    fillColor: "#020711",
    fillAlpha: 0.01,
    strokeColor: "#020711",
    strokeAlpha: 0,
    strokeWidth: 0
});

export class MarkerOwnershipPresentationResolver {
    static resolve(record = {}) {
        const target = record?.target || {};
        const ownershipTarget = this.#getOwnershipTarget(target);
        if (!ownershipTarget) return TRANSPARENT_STYLE;

        const ownership = OwnershipService.getOwnership(ownershipTarget, { includeHidden: true });
        if (!ownership || ownership.owner.entityType !== "faction") return TRANSPARENT_STYLE;

        const edge = ConnectionStore.getConnectionEdge(ownership.edgeId);
        if (!edge || !ConnectionStore.isConnectionVisibleToPlayers(edge)) return TRANSPARENT_STYLE;

        const faction = CampaignEntityJournalStore.getFaction(ownership.owner.entityId);
        if (!faction || !CampaignEntityVisibilityManager.isVisibleToPlayers(faction)) return TRANSPARENT_STYLE;

        const color = FactionEntityModel.getAccent(faction);
        return {
            active: true,
            factionId: faction.id,
            fillColor: color,
            fillAlpha: 0.78,
            strokeColor: this.#darken(color, 0.42),
            strokeAlpha: 0.9,
            strokeWidth: 2
        };
    }

    static #darken(color, factor = 0.5) {
        const hex = String(color || "").replace("#", "");
        if (!/^[0-9a-f]{6}$/i.test(hex)) return "#101317";
        const channels = [0, 2, 4].map(index => Math.round(Number.parseInt(hex.slice(index, index + 2), 16) * factor));
        return `#${channels.map(channel => channel.toString(16).padStart(2, "0")).join("")}`;
    }

    static #getOwnershipTarget(target = {}) {
        if (target.kind === "campaign-entity" && target.entityType === "location" && target.entityId) {
            return {
                id: `nexus-entity:${target.entityId}`,
                kind: "nexus-entity",
                entityType: "location",
                entityId: target.entityId
            };
        }
        if (target.kind === "nexus-site" && target.parentSceneId && target.siteId) return target;
        if (target.kind === "nexus-scene" && target.sceneId) return target;
        return null;
    }
}
