import type {
  RedactionReport,
  RedactionRule,
} from "../../../playwright/src/redaction.js";
import type { CoverageOutcome } from "../../../schema/src/records/coverage.js";
import type { Finding } from "../../../schema/src/records/finding.js";
import type { HarnessOutcome } from "../../../schema/src/records/harness.js";
import type { ReviewDecision } from "../../../schema/src/decisions/decision.js";
import type { MatrixCell } from "../../../schema/src/records/context.js";

export const REPORT_DATA_VERSION = "report/v1" as const;
export const REPORT_MANIFEST_VERSION = "report-manifest/v1" as const;

export type ImageStatus = "available" | "unavailable" | "not-applicable";

export type ReportFindingRecord = Finding & {
  imageStatus: ImageStatus;
  reopenedFrom?: PriorDecisionDiff;
};

export type PriorDecisionDiff = {
  priorDecisionId: string;
  priorFingerprint: string;
  currentFingerprint: string;
  reviewer: string;
  reviewedAt: string;
  reason?: string;
  scope: ReviewDecision["scope"];
};

export type AcceptedFindingInput = {
  finding: Finding;
  decision: ReviewDecision;
};

export type AcceptedFindingRecord = {
  finding: ReportFindingRecord;
  decision: ReviewDecision;
  status: "accepted" | "revoked";
  revokedAt?: string;
};

export type ReportRunRecords = {
  findings: Finding[];
  acceptedFindings?: AcceptedFindingInput[];
  priorDecisions?: ReviewDecision[];
  coverageOutcomes: CoverageOutcome[];
  harnessOutcomes: HarnessOutcome[];
  cells?: MatrixCell[];
};

export type ReportCell = {
  id: string;
  route: string;
  url: string;
  role: string;
  locale: string;
  direction: string;
  viewport: MatrixCell["viewport"];
  engine: string;
};

export type ReportArtifactInput = {
  relativePath: string;
  sourcePath: string;
};

export type BuildReportDirOptions = {
  runRecords: ReportRunRecords;
  artifacts: ReportArtifactInput[];
  redaction: RedactionRule[];
  outDir: string;
  staticReview?: StaticReviewInput;
};

export type StaticReviewInput = {
  projectIdentity: string;
  configHash: string;
  report: { id: string; revision: string };
};

export type StaticReviewMetadata = StaticReviewInput & {
  report: StaticReviewInput["report"] & { findingSetHash: string };
};

export type ReportData = {
  schemaVersion: typeof REPORT_DATA_VERSION;
  findings: ReportFindingRecord[];
  acceptedFindings?: AcceptedFindingRecord[];
  coverageOutcomes: CoverageOutcome[];
  harnessOutcomes: HarnessOutcome[];
  cellIndex: ReportCell[];
  staticReview?: StaticReviewMetadata;
};

export type ReportManifest = {
  schemaVersion: typeof REPORT_MANIFEST_VERSION;
  outDir: string;
  dataPath: string;
  contentHash: string;
  redaction: RedactionReport;
};
