import type { Finding } from "../../../schema/src/records/finding.js";
import type { ImageStatus, ReportFindingRecord } from "./types.js";

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

function screenshotRefs(finding: Finding): Set<string> {
  if (!Array.isArray(finding.evidence)) {
    return new Set();
  }
  return new Set(
    finding.evidence.flatMap((entry) => {
      const refs = isRecord(entry) && isRecord(entry.payload)
        ? entry.payload.screenshotRefs
        : undefined;
      return Array.isArray(refs)
        ? refs.filter((ref): ref is string => typeof ref === "string")
        : [];
    }),
  );
}

function isScreenshotArtifact(
  relativePath: string,
  mediaType: string,
  referencedPaths: Set<string>,
): boolean {
  if (!mediaType.startsWith("image/")) {
    return false;
  }
  if (referencedPaths.has(relativePath)) {
    return true;
  }
  return (
    relativePath.includes("screenshot") ||
    relativePath.includes("consistency-full") ||
    relativePath.includes("geometry-full") ||
    relativePath.includes("geometry-crop")
  );
}

export function resolveImageStatus(finding: Finding): ImageStatus {
  if (finding.context.kind !== "browser") {
    return "not-applicable";
  }

  const referencedPaths = screenshotRefs(finding);
  const hasScreenshot = finding.artifacts.some((artifact) =>
    isScreenshotArtifact(artifact.relativePath, artifact.mediaType, referencedPaths),
  );
  return hasScreenshot ? "available" : "unavailable";
}

export function toReportFindingRecord(finding: Finding): ReportFindingRecord {
  const imageStatus = resolveImageStatus(finding);
  const referencedPaths = screenshotRefs(finding);
  const artifacts =
    imageStatus === "available"
      ? finding.artifacts
      : finding.artifacts.filter(
          (artifact) => !isScreenshotArtifact(artifact.relativePath, artifact.mediaType, referencedPaths),
        );

  return {
    ...finding,
    imageStatus,
    artifacts,
  };
}
