import { ConnectionCategories } from "../../connections/services/ConnectionCategories.js";
import { ConnectionOpinionService } from "../../connections/services/ConnectionOpinionService.js";
import { ConnectionStore } from "../../connections/services/ConnectionStore.js";
import { ConnectionTargetResolver } from "../../connections/services/ConnectionTargetResolver.js";
import { FactionMembershipService } from "../../connections/services/FactionMembershipService.js";
import { LocationLeadershipService } from "../../connections/services/LocationLeadershipService.js";
import { LocationEntityModel } from "./LocationEntityModel.js";
import { OwnershipService } from "../../connections/services/OwnershipService.js";
import { TradingCenterService } from "../../connections/services/TradingCenterService.js";

export class LocationOverviewViewModel {
    static fromEntity(entity = {}) {
        const target = ConnectionTargetResolver.fromCampaignEntity(entity);
        const nodeId = ConnectionTargetResolver.getNodeId(target);
        const authority = LocationLeadershipService.getPresentation({ authorityType: LocationEntityModel.getAuthorityType(entity) });
        if (!target || !nodeId) return { owner: null, leader: null, authority, trade: null, people: [] };
        const ownership = OwnershipService.getOwnership(target);
        const leadership = LocationLeadershipService.getLeader(target);
        const tradingCenter = TradingCenterService.getTradingCenter(target);
        const connections = ConnectionStore.getConnectionsForNode(nodeId);
        const dependents = connections.filter(({ edge }) => edge?.relationType === TradingCenterService.RELATION_TYPE && edge.sourceNodeId === nodeId);
        return {
            owner: ownership?.owner ? { ...ownership.owner, nodeId: ownership.owner.id, edgeId: ownership.edgeId } : null,
            leader: leadership?.leader ? { ...leadership.leader, nodeId: leadership.leader.id, entityType: "npc", edgeId: leadership.edgeId, presentation: leadership.presentation || authority } : null,
            authority: leadership?.presentation || authority,
            trade: tradingCenter?.center ? { ...tradingCenter.center, nodeId: tradingCenter.center.id, kind: "through", label: "Trades through", icon: "fas fa-route" }
                : dependents.length ? { kind: "hub", label: "Trade position", name: "Regional Trade Hub", subtitle: `Receives from ${dependents.length} ${dependents.length === 1 ? "location" : "locations"}`, icon: "fas fa-scale-balanced" }
                    : null,
            people: connections.filter(({ node }) => node?.kind === "nexus-entity" && node.entityType === "npc" && node.id !== leadership?.leaderNodeId)
                .map(({ edge, node }) => this.#person(edge, node, nodeId))
                .sort((a, b) => a.sort - b.sort || a.name.localeCompare(b.name))
        };
    }

    static #person(edge, node, currentNodeId) {
        const display = ConnectionTargetResolver.resolveDisplayNodeSync(node) || node;
        const customCategories = ConnectionStore.getCustomCategories();
        const view = ConnectionStore.getConnectionView(edge, currentNodeId, customCategories);
        const category = ConnectionCategories.get(view.category, customCategories);
        const opinion = ConnectionOpinionService.resolvePerspective(edge, currentNodeId);
        const membership = FactionMembershipService.getMembershipsForNpc(node)
            .sort((left, right) => Number(right.rankValue || 0) - Number(left.rankValue || 0)
                || Number(right.isLeader) - Number(left.isLeader)
                || left.faction.name.localeCompare(right.faction.name))[0] || null;
        return {
            edgeId: edge.id, nodeId: node.id, entityId: node.entityId || "", name: display.name || "Unknown Person",
            imageSrc: display.img || "", subtitle: display.subtitle || "Person", role: String(view.role || category.singular || "Contact"),
            categoryIcon: String(category.icon || "fas fa-user"), categoryColor: String(category.color || "var(--nexus-accent-primary)"),
            sort: Number(view.sort || 100), opinion: opinion ? { score: Number(opinion.score || 0), scoreLabel: opinion.scoreLabel, tierLabel: opinion.tier.label, tierColor: opinion.tier.color } : null,
            allegiance: membership ? {
                name: membership.faction.name,
                imageSrc: membership.faction.imageSrc,
                rank: membership.rankLabel || (membership.isLeader ? "Faction Leader" : "Faction Member")
            } : null
        };
    }
}
