import { ConnectionOpinionService } from "../../connections/services/ConnectionOpinionService.js";
import { FactionEntityModel } from "./FactionEntityModel.js";
import { ConnectionStore } from "../../connections/services/ConnectionStore.js";
import { ConnectionTargetResolver } from "../../connections/services/ConnectionTargetResolver.js";
import { FactionMembershipService } from "../../connections/services/FactionMembershipService.js";
import { FactionSeatService } from "../../connections/services/FactionSeatService.js";
import { LocationLeadershipService } from "../../connections/services/LocationLeadershipService.js";
import { OwnershipService } from "../../connections/services/OwnershipService.js";
import { ShipOwnershipService } from "../../connections/services/ShipOwnershipService.js";

export class FactionDomainViewModel {
    static fromEntity(entity = {}, options = {}) {
        const target = ConnectionTargetResolver.fromCampaignEntity(entity);
        const factionNodeId = ConnectionTargetResolver.getNodeId(target);
        if (!target || !factionNodeId) return this.#empty();

        const memberships = FactionMembershipService.getMembershipsForFaction(target, options);
        const leader = memberships.find(entry => entry.isLeader) || null;
        const members = memberships
            .filter(entry => !entry.isLeader)
            .map(entry => this.#member(entry, factionNodeId));
        const seat = FactionSeatService.getSeat(target, options);
        const holdings = [
            ...OwnershipService.getHoldingsForOwner(target, options)
                .map(entry => this.#holding(entry, seat)),
            ...ShipOwnershipService.getShipsForOwner(target, options)
                .map(entry => this.#shipHolding(entry))
        ]
            .sort((left, right) => Number(right.isSeat) - Number(left.isSeat) || left.name.localeCompare(right.name));
        const seatHolding = holdings.find(entry => entry.isSeat) || null;
        const ideology = FactionEntityModel.getIdeology(entity);

        return {
            canManage: options.isGM === true,
            hasLeader: !!leader,
            leader: leader ? this.#member(leader, factionNodeId) : null,
            hasSeat: !!seatHolding,
            seat: seatHolding,
            members,
            holdings: holdings.filter(entry => !entry.isSeat),
            hasMembers: members.length > 0,
            hasHoldings: holdings.length > 0,
            memberCount: memberships.length,
            holdingCount: holdings.length,
            ideology,
            hasIdeology: ideology.length > 0
        };
    }

    static #member(entry, factionNodeId) {
        const edge = ConnectionStore.getConnectionEdge(entry.edgeId);
        const opinion = edge ? ConnectionOpinionService.resolvePerspective(edge, factionNodeId) : null;
        return {
            nodeId: entry.memberNodeId,
            name: entry.member.name,
            imageSrc: entry.member.imageSrc,
            subtitle: entry.rankLabel || (entry.isLeader ? "Faction Leader" : entry.member.subtitle || "Member"),
            rankValue: Number(entry.rankValue || 0),
            rankLabel: entry.rankLabel || "",
            isLeader: entry.isLeader,
            opinion: opinion ? {
                scoreLabel: opinion.scoreLabel,
                tierLabel: opinion.tier.label,
                tierColor: opinion.tier.color
            } : null
        };
    }

    static #holding(entry, seat) {
        const node = ConnectionStore.getNode(entry.assetNodeId);
        const leadership = node ? LocationLeadershipService.getLeader(node) : null;
        return {
            nodeId: entry.assetNodeId,
            name: entry.asset.name,
            imageSrc: entry.asset.imageSrc,
            subtitle: entry.asset.subtitle || "Holding",
            isSeat: seat?.placeNodeId === entry.assetNodeId,
            supportsLeadership: node?.kind === "nexus-entity" && node.entityType === "location",
            ruler: leadership ? {
                nodeId: leadership.leaderNodeId,
                name: leadership.leader.name,
                imageSrc: leadership.leader.imageSrc,
                subtitle: leadership.leader.subtitle || "Ruler"
            } : null
        };
    }

    static #shipHolding(entry) {
        return {
            nodeId: entry.shipNodeId,
            name: entry.ship.name,
            imageSrc: entry.ship.imageSrc,
            subtitle: entry.ship.subtitle || "Ship",
            isSeat: false,
            isShip: true,
            supportsLeadership: false,
            ruler: null
        };
    }

    static #empty() {
        return {
            canManage: false,
            hasLeader: false,
            leader: null,
            hasSeat: false,
            seat: null,
            members: [],
            holdings: [],
            hasMembers: false,
            hasHoldings: false,
            memberCount: 0,
            holdingCount: 0,
            ideology: [],
            hasIdeology: false
        };
    }
}
