import { evaluateRelation, type RelationVerdict } from "../../../universal/src/graph.js";
import { buildRelationGraphForWidget } from "./graph.js";
import type {
  RelationsCellEvidence,
  RelationsViolationFact,
  RelationsWidgetProbe,
} from "./types.js";

function verdictFacts(
  verdict: RelationVerdict,
): Array<{ nodeId: string; normalizedValue: unknown }> {
  if (verdict.status !== "contradiction") {
    return [];
  }
  return verdict.facts.map((fact) => ({
    nodeId: fact.nodeId,
    normalizedValue: fact.normalizedValue,
  }));
}

function violationForRelation(
  widget: RelationsWidgetProbe,
  relationId: string,
  verdict: RelationVerdict,
  representations: RelationsWidgetProbe["representations"],
): RelationsViolationFact | undefined {
  if (verdict.status !== "contradiction") {
    return undefined;
  }

  const facts = verdictFacts(verdict);
  if (facts.length === 0) {
    return undefined;
  }

  return {
    ruleId: "UI-034",
    uniRule: "UNI-024",
    kind: "same-semantic-contradiction",
    locator: widget.locator,
    relationId,
    noWinner: true,
    facts,
    summary:
      "same-semantic UI representations contradict after normalization without selecting intended side",
    measurement: {
      widgetId: widget.widgetId,
      widgetKind: widget.kind,
      relationId,
      verdict,
      representations,
    },
  };
}

function detectWidgetViolations(widget: RelationsWidgetProbe): RelationsViolationFact[] {
  const graph = buildRelationGraphForWidget(widget.kind, widget.representations);
  const violations: RelationsViolationFact[] = [];

  for (const relationId of Object.keys(graph.relations)) {
    const verdict = evaluateRelation(graph, relationId);
    const violation = violationForRelation(
      widget,
      relationId,
      verdict,
      widget.representations,
    );
    if (violation !== undefined) {
      violations.push(violation);
    }
  }

  return violations;
}

export function detectCrossRepresentationViolations(
  evidence: RelationsCellEvidence,
): RelationsViolationFact[] {
  return evidence.relationsProbe.widgets.flatMap((widget) => detectWidgetViolations(widget));
}
