/**
 * compareVisibleState — public entry point for visible-state comparison.
 *
 * Orchestrates readers, delta collection, and summary assembly.
 * All heavy lifting lives in diffKeys, diffProperties, and diffStructure.
 *
 * @module domain/services/comparison/VisibleStateComparison
 */
import { createStateReader } from "../state/StateReader.js";
import { summarizeReader, collectNodeProperties, collectEdgeProperties } from "./diffKeys.js";
import { compareNodePropertyMaps, compareEdgePropertyMaps } from "./diffProperties.js";
import { buildNodeDelta, buildEdgeDelta, hasVisibleStateChanges, normalizeTargetId, buildTargetComparison, } from "./diffStructure.js";
const VISIBLE_STATE_COMPARISON_VERSION = 'visible-state-compare/v1';
// ── Summary builders ─────────────────────────────────────────────────────────
/**
 * Builds the node/edge counts portion of the comparison summary.
 */
function buildTopologySummary(nodeDelta, edgeDelta) {
    return {
        nodes: {
            added: nodeDelta.added.length,
            removed: nodeDelta.removed.length,
        },
        edges: {
            added: edgeDelta.added.length,
            removed: edgeDelta.removed.length,
        },
    };
}
/**
 * Builds the property counts portion of the comparison summary.
 */
function buildPropertySummary(nodePropertyDelta, // nosemgrep: ts-no-unknown-outside-adapters -- 0025B
edgePropertyDelta) {
    return {
        nodeProperties: {
            added: nodePropertyDelta.added.length,
            removed: nodePropertyDelta.removed.length,
            changed: nodePropertyDelta.changed.length,
        },
        edgeProperties: {
            added: edgePropertyDelta.added.length,
            removed: edgePropertyDelta.removed.length,
            changed: edgePropertyDelta.changed.length,
        },
    };
}
/**
 * Assembles the full comparison summary from left/right summaries and deltas.
 */
function buildComparisonSummary(params) {
    const { leftSummary, rightSummary, nodeDelta, edgeDelta, nodePropertyDelta, edgePropertyDelta } = params;
    return {
        left: leftSummary,
        right: rightSummary,
        ...buildTopologySummary(nodeDelta, edgeDelta),
        ...buildPropertySummary(nodePropertyDelta, edgePropertyDelta),
    };
}
// ── Delta collection ─────────────────────────────────────────────────────────
/**
 * Collects all deltas between two readers (nodes, edges, properties).
 */
function collectAllDeltas(leftReader, rightReader) {
    return {
        nodeDelta: buildNodeDelta(leftReader, rightReader),
        edgeDelta: buildEdgeDelta(leftReader, rightReader),
        nodePropertyDelta: compareNodePropertyMaps(collectNodeProperties(leftReader), collectNodeProperties(rightReader)),
        edgePropertyDelta: compareEdgePropertyMaps(collectEdgeProperties(leftReader), collectEdgeProperties(rightReader)),
    };
}
function assembleResult({ deltas, leftSummary, rightSummary, target }) {
    const { nodeDelta, edgeDelta, nodePropertyDelta, edgePropertyDelta } = deltas;
    const changed = hasVisibleStateChanges({ nodeDelta, edgeDelta, nodePropertyDelta, edgePropertyDelta });
    return {
        comparisonVersion: VISIBLE_STATE_COMPARISON_VERSION,
        changed,
        summary: buildComparisonSummary({ leftSummary, rightSummary, nodeDelta, edgeDelta, nodePropertyDelta, edgePropertyDelta }),
        nodes: nodeDelta,
        edges: edgeDelta,
        nodeProperties: nodePropertyDelta,
        edgeProperties: edgePropertyDelta,
        ...(target !== undefined ? { target } : {}),
    };
}
/**
 * Compares two materialized states using only their visible substrate truth.
 *
 * The comparison remains reducer-agnostic and application-blind:
 * - visible node deltas
 * - visible edge deltas
 * - visible node-property deltas
 * - visible edge-property deltas
 * - optional node-local target diff helper
 */
export function compareVisibleState(leftState, rightState, options = {}) {
    const leftReader = createStateReader(leftState);
    const rightReader = createStateReader(rightState);
    return assembleResult({
        deltas: collectAllDeltas(leftReader, rightReader),
        leftSummary: summarizeReader(leftReader),
        rightSummary: summarizeReader(rightReader),
        target: buildTargetComparison(leftReader, rightReader, normalizeTargetId(options.targetId)),
    });
}
