import type { MatchSubject } from "../../../core/src/match/scope.js";
import { matchScope } from "../../../core/src/match/scope.js";
import {
  normalizeDecisionScope,
  type DecisionScope,
  type ExactDecisionScope,
  type ReviewedPolicyScope,
} from "../../../schema/src/decisions/scope.js";
import type { Finding } from "../../../schema/src/records/finding.js";
import type { ReportFindingRecord } from "../build/types.js";

function isRecord(value: unknown): value is Record<string, unknown> {
  return typeof value === "object" && value !== null && !Array.isArray(value);
}

function extractUiPayload(evidence: unknown): Record<string, unknown> | undefined {
  if (!Array.isArray(evidence)) {
    return isRecord(evidence) ? evidence : undefined;
  }
  for (const entry of evidence) {
    if (!isRecord(entry)) {
      continue;
    }
    if (entry.truthSource === "observed" || entry.truthSource === "universal") {
      return isRecord(entry.payload) ? entry.payload : undefined;
    }
  }
  const first: unknown = evidence[0];
  if (!isRecord(first)) {
    return undefined;
  }
  return isRecord(first.payload) ? first.payload : undefined;
}

function browserDimensions(
  finding: Finding,
  payload: Record<string, unknown> | undefined,
): Array<{ key: string; value: string }> {
  const dimensions: Array<{ key: string; value: string }> = [];
  if (finding.context.kind === "browser") {
    dimensions.push({ key: "cell", value: finding.context.cell.id });
  }
  if (payload !== undefined) {
    for (const key of ["route", "role", "locale"] as const) {
      const value = payload[key];
      if (typeof value === "string" && value.length > 0) {
        dimensions.push({ key, value });
      }
    }
  }
  return dimensions;
}

function nonBrowserDimensions(finding: Finding): Array<{ key: string; value: string }> {
  if (finding.context.kind === "browser") {
    return [];
  }
  const context = finding.context;
  const dimensions = [
    { key: "surface", value: context.surfaceId },
    { key: "adapter", value: context.adapterId },
    { key: "seed", value: context.seed },
  ];
  if (context.action !== undefined) {
    dimensions.push({ key: "action", value: context.action.id });
  }
  return dimensions;
}

export function exactScopeFromFinding(finding: Finding): ExactDecisionScope {
  const payload = extractUiPayload(finding.evidence);
  const dimensions =
    finding.context.kind === "browser"
      ? browserDimensions(finding, payload)
      : nonBrowserDimensions(finding);

  return normalizeDecisionScope({
    kind: "exact",
    detector: finding.detector,
    target: { kind: "exact", canonicalTarget: finding.target.canonical },
    context: {
      kind: finding.context.kind,
      dimensions,
    },
    contractVersion: null,
  }) as ExactDecisionScope;
}

export function matchSubjectFromFinding(
  finding: ReportFindingRecord,
  now: string,
): MatchSubject {
  const exactScope = exactScopeFromFinding(finding);
  const dimensions: Record<string, string> = {};
  for (const dimension of exactScope.context.dimensions) {
    dimensions[dimension.key] = dimension.value;
  }
  return {
    detector: finding.detector,
    target: finding.target.canonical,
    contextKind: finding.context.kind,
    dimensions,
    contractVersion: null,
    now,
  };
}

export function countPolicyImpact(
  scope: ReviewedPolicyScope,
  findings: ReportFindingRecord[],
  now: string,
): number {
  return findings.filter((finding) => {
    const result = matchScope(scope, matchSubjectFromFinding(finding, now));
    return result.matched;
  }).length;
}

export function validateReviewedPolicyScope(scope: DecisionScope): scope is ReviewedPolicyScope {
  return scope.kind === "reviewed-policy";
}

export function policyScopeRequiresReason(scope: DecisionScope): boolean {
  return scope.kind === "reviewed-policy";
}
