import { readFileSync } from "node:fs";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import { MATRIX_CELL_VERSION } from "../../../schema/src/records/context.js";
import type { MatrixCell } from "../../../schema/src/records/context.js";
import type {
  ConsistencyFixture,
  ConsistencyFixturePage,
  ConsistencyRuleId,
} from "../../src/consistency/types.js";

const FIXTURES_DIR = join(dirname(fileURLToPath(import.meta.url)), "html");

function readHtml(name: string): string {
  return readFileSync(join(FIXTURES_DIR, name), "utf8");
}

function baseCell(overrides: Partial<MatrixCell> = {}): MatrixCell {
  return {
    schemaVersion: MATRIX_CELL_VERSION,
    id: "consistency-cell-fixture",
    creationSource: {
      runId: "consistency-fixture-run",
      component: "orchestrator",
      componentId: "consistency-fixtures",
    },
    routeId: "consistency-fixture",
    url: "/fixture",
    role: "anonymous",
    locale: "en-US",
    viewport: { width: 800, height: 600, deviceScaleFactor: 1 },
    state: { uiCompletionSignal: "#ready" },
    actions: [],
    seed: "",
    ...overrides,
  };
}

function settledCell(overrides: Partial<MatrixCell> = {}): Partial<MatrixCell> {
  return {
    state: { uiCompletionSignal: "#ready", ...(overrides.state ?? {}) },
    ...overrides,
  };
}

function standardMatrixPages(
  outlierHtml = "chrome-outlier.html",
): ConsistencyFixturePage[] {
  return [
    { route: "/page-a", html: readHtml("chrome-standard.html"), cell: { id: "page-a" } },
    { route: "/page-b", html: readHtml("chrome-standard.html"), cell: { id: "page-b" } },
    { route: "/page-c", html: readHtml("chrome-standard.html"), cell: { id: "page-c" } },
    {
      route: "/page-outlier",
      html: readHtml(outlierHtml),
      cell: { id: "page-outlier" },
    },
  ];
}

function clusteredMatrixPages(
  outlierHtml = "chrome-outlier.html",
): ConsistencyFixturePage[] {
  return [
    ...standardMatrixPages(outlierHtml),
    {
      route: "/page-outlier-b",
      html: readHtml(outlierHtml),
      cell: { id: "page-outlier-b" },
    },
  ];
}

function uniformMatrixPages(htmlFile: string): ConsistencyFixturePage[] {
  return [
    { route: "/page-a", html: readHtml(htmlFile), cell: { id: "page-a" } },
    { route: "/page-b", html: readHtml(htmlFile), cell: { id: "page-b" } },
    { route: "/page-c", html: readHtml(htmlFile), cell: { id: "page-c" } },
  ];
}

function fixture(
  ruleId: ConsistencyRuleId,
  variant: ConsistencyFixture["variant"],
  options: {
    htmlFile?: string;
    pages?: ConsistencyFixturePage[];
    cell?: Partial<MatrixCell>;
    intentionalContractId?: string;
  } = {},
): ConsistencyFixture {
  return {
    fixtureId: `${ruleId.toLowerCase()}-${variant}`,
    ruleId,
    variant,
    ...(options.pages === undefined
      ? {
          route: "/fixture",
          html: readHtml(options.htmlFile ?? "chrome-standard.html"),
        }
      : { pages: options.pages }),
    ...(options.cell === undefined ? {} : { cell: options.cell }),
    ...(options.intentionalContractId === undefined
      ? {}
      : { intentionalContractId: options.intentionalContractId }),
  };
}

export const consistencyFixtureGallery: ConsistencyFixture[] = [
  fixture("UI-040", "positive", {
    htmlFile: "ui-040-positive.html",
    cell: settledCell({
      state: {
        uiCompletionSignal: "#ready",
        uiExpectedLandmarks: "main,nav",
      },
    }),
  }),
  fixture("UI-040", "negative", {
    htmlFile: "ui-040-negative.html",
    cell: settledCell({
      state: {
        uiCompletionSignal: "#ready",
        uiExpectedLandmarks: "main,nav",
      },
    }),
  }),
  fixture("UI-040", "intentional-exception", {
    htmlFile: "ui-040-positive.html",
    cell: settledCell({
      state: {
        uiCompletionSignal: "#ready",
        uiExpectedLandmarks: "main,nav",
        uiChromeContract: "confirmed",
      },
    }),
    intentionalContractId: "consistency-ui-040-exception",
  }),
  fixture("UI-040", "rtl", {
    htmlFile: "ui-040-positive.html",
    cell: settledCell({
      locale: "ar-SA",
      id: "ui-040-rtl",
      state: {
        uiCompletionSignal: "#ready",
        uiExpectedLandmarks: "main,nav",
        uiChromeContract: "confirmed",
      },
    }),
  }),
  fixture("UI-040", "changed-fingerprint", {
    htmlFile: "ui-040-positive.html",
    cell: settledCell({
      id: "ui-040-changed-fingerprint",
      state: {
        uiCompletionSignal: "#ready",
        uiExpectedLandmarks: "main,navigation,banner",
        uiChromeContract: "confirmed",
      },
    }),
  }),

  fixture("UI-041", "positive", { pages: clusteredMatrixPages() }),
  fixture("UI-041", "negative", { pages: uniformMatrixPages("chrome-standard.html") }),
  fixture("UI-041", "intentional-exception", {
    pages: clusteredMatrixPages(),
    intentionalContractId: "consistency-ui-041-exception",
  }),
  fixture("UI-041", "rtl", {
    pages: [
      ...uniformMatrixPages("chrome-standard.html").slice(0, 2),
      {
        route: "/page-rtl",
        html: readHtml("chrome-outlier-rtl.html"),
        cell: { id: "page-rtl", locale: "ar-SA" },
      },
      {
        route: "/page-c",
        html: readHtml("chrome-standard.html"),
        cell: { id: "page-c" },
      },
    ],
  }),
  fixture("UI-041", "changed-fingerprint", {
    pages: clusteredMatrixPages("chrome-outlier-missing-auth.html"),
  }),

  fixture("UI-042", "positive", { pages: standardMatrixPages() }),
  fixture("UI-042", "negative", { pages: uniformMatrixPages("chrome-standard.html") }),
  fixture("UI-042", "intentional-exception", {
    pages: standardMatrixPages("ui-042-intentional-exception.html"),
    intentionalContractId: "consistency-ui-042-exception",
  }),
  fixture("UI-042", "rtl", {
    pages: [
      ...uniformMatrixPages("chrome-standard.html").slice(0, 3),
      {
        route: "/page-rtl-outlier",
        html: readHtml("chrome-outlier-rtl.html"),
        cell: { id: "page-rtl-outlier", locale: "ar-SA" },
      },
    ],
  }),
  fixture("UI-042", "changed-fingerprint", {
    pages: standardMatrixPages("chrome-outlier-missing-auth.html"),
  }),

  fixture("UI-043", "positive", {
    pages: [
      ...uniformMatrixPages("chrome-standard.html").slice(0, 2),
      {
        route: "/checkout",
        html: readHtml("chrome-standard.html"),
        cell: { id: "checkout-page", state: { uiCohortKind: "checkout" } },
      },
      {
        route: "/auth",
        html: readHtml("chrome-authentication.html"),
        cell: { id: "auth-page", state: { uiCohortKind: "authentication" } },
      },
    ],
  }),
  fixture("UI-043", "negative", {
    pages: [
      {
        route: "/checkout-a",
        html: readHtml("chrome-checkout.html"),
        cell: { id: "checkout-a", state: { uiCohortKind: "checkout" } },
      },
      {
        route: "/checkout-b",
        html: readHtml("chrome-checkout.html"),
        cell: { id: "checkout-b", state: { uiCohortKind: "checkout" } },
      },
    ],
  }),
  fixture("UI-043", "intentional-exception", {
    pages: [
      ...uniformMatrixPages("chrome-standard.html").slice(0, 2),
      {
        route: "/checkout",
        html: readHtml("chrome-checkout.html"),
        cell: { id: "checkout-page", state: { uiCohortKind: "checkout" } },
      },
    ],
    intentionalContractId: "consistency-ui-043-exception",
  }),
  fixture("UI-043", "rtl", {
    pages: [
      {
        route: "/checkout-rtl",
        html: readHtml("chrome-checkout.html"),
        cell: {
          id: "checkout-rtl",
          locale: "ar-SA",
          state: { uiCohortKind: "checkout" },
        },
      },
      {
        route: "/auth-rtl",
        html: readHtml("chrome-authentication.html"),
        cell: {
          id: "auth-rtl",
          locale: "ar-SA",
          state: { uiCohortKind: "authentication" },
        },
      },
    ],
  }),
  fixture("UI-043", "changed-fingerprint", {
    pages: [
      {
        route: "/embedded",
        html: readHtml("chrome-standard.html"),
        cell: { id: "embedded-page", state: { uiCohortKind: "embedded" } },
      },
      {
        route: "/offline",
        html: readHtml("chrome-checkout.html"),
        cell: { id: "offline-page", state: { uiCohortKind: "offline" } },
      },
    ],
  }),

  fixture("UI-044", "positive", {
    pages: [
      {
        route: "/style-a",
        html: readHtml("ui-044-style-baseline.html"),
        cell: {
          id: "style-a",
          state: { uiStyleFingerprintEnabled: "true" },
        },
      },
      {
        route: "/style-b",
        html: readHtml("ui-044-style-baseline.html"),
        cell: {
          id: "style-b",
          state: { uiStyleFingerprintEnabled: "true" },
        },
      },
      {
        route: "/style-c",
        html: readHtml("ui-044-style-baseline.html"),
        cell: {
          id: "style-c",
          state: { uiStyleFingerprintEnabled: "true" },
        },
      },
      {
        route: "/style-outlier",
        html: readHtml("ui-044-style-outlier.html"),
        cell: {
          id: "style-outlier",
          state: { uiStyleFingerprintEnabled: "true" },
        },
      },
    ],
  }),
  fixture("UI-044", "negative", {
    pages: [
      {
        route: "/style-a",
        html: readHtml("ui-044-style-baseline.html"),
        cell: {
          id: "style-a",
          state: { uiStyleFingerprintEnabled: "true" },
        },
      },
      {
        route: "/style-b",
        html: readHtml("ui-044-style-baseline.html"),
        cell: {
          id: "style-b",
          state: { uiStyleFingerprintEnabled: "true" },
        },
      },
    ],
  }),
  fixture("UI-044", "intentional-exception", {
    pages: [
      {
        route: "/style-a",
        html: readHtml("ui-044-style-baseline.html"),
        cell: {
          id: "style-a",
          state: { uiStyleFingerprintEnabled: "true" },
        },
      },
      {
        route: "/style-outlier",
        html: readHtml("ui-044-style-outlier.html"),
        cell: {
          id: "style-outlier",
          state: { uiStyleFingerprintEnabled: "true" },
        },
      },
    ],
    intentionalContractId: "consistency-ui-044-exception",
  }),
  fixture("UI-044", "rtl", {
    pages: [
      {
        route: "/style-rtl-a",
        html: readHtml("ui-044-style-baseline.html"),
        cell: {
          id: "style-rtl-a",
          locale: "ar-SA",
          state: { uiStyleFingerprintEnabled: "true" },
        },
      },
      {
        route: "/style-rtl-outlier",
        html: readHtml("ui-044-style-outlier.html"),
        cell: {
          id: "style-rtl-outlier",
          locale: "ar-SA",
          state: { uiStyleFingerprintEnabled: "true" },
        },
      },
    ],
  }),
  fixture("UI-044", "changed-fingerprint", {
    pages: [
      {
        route: "/style-a",
        html: readHtml("ui-044-style-baseline.html"),
        cell: {
          id: "style-a",
          state: { uiStyleFingerprintEnabled: "true" },
        },
      },
      {
        route: "/style-b",
        html: readHtml("ui-044-style-baseline.html"),
        cell: {
          id: "style-b",
          state: { uiStyleFingerprintEnabled: "true" },
        },
      },
      {
        route: "/style-outlier",
        html: readHtml("ui-044-style-outlier.html"),
        cell: {
          id: "style-outlier",
          state: {
            uiStyleFingerprintEnabled: "true",
            uiComponentSignatures: "[data-component='primary-button']",
          },
        },
      },
    ],
  }),
];

export function cellForFixture(entry: ConsistencyFixture): MatrixCell {
  return baseCell({
    id: entry.fixtureId,
    routeId: entry.fixtureId,
    url: entry.route ?? "/fixture",
    ...(entry.cell ?? {}),
  });
}

export function cellsForFixture(entry: ConsistencyFixture): MatrixCell[] {
  if (entry.pages !== undefined) {
    return entry.pages.map((page, index) =>
      baseCell({
        id: page.cell?.id ?? `${entry.fixtureId}-${String(index)}`,
        routeId: page.cell?.id ?? `${entry.fixtureId}-${String(index)}`,
        url: page.route,
        ...(page.cell ?? {}),
        state: {
          uiCompletionSignal: "#ready",
          ...(page.cell?.state ?? {}),
        },
      }),
    );
  }
  return [cellForFixture(entry)];
}

export function routesForFixture(entry: ConsistencyFixture): Record<string, string> {
  if (entry.pages !== undefined) {
    const routes: Record<string, string> = {};
    for (const page of entry.pages) {
      routes[page.route] = page.html;
    }
    return routes;
  }
  return { [entry.route ?? "/fixture"]: entry.html ?? "" };
}

export function fixturesForRule(ruleId: ConsistencyRuleId): ConsistencyFixture[] {
  return consistencyFixtureGallery.filter((entry) => entry.ruleId === ruleId);
}

export function positiveFixture(ruleId: ConsistencyRuleId): ConsistencyFixture {
  const match = fixturesForRule(ruleId).find((entry) => entry.variant === "positive");
  if (match === undefined) {
    throw new Error(`positive fixture missing for ${ruleId}`);
  }
  return match;
}

export function negativeFixture(ruleId: ConsistencyRuleId): ConsistencyFixture {
  const match = fixturesForRule(ruleId).find((entry) => entry.variant === "negative");
  if (match === undefined) {
    throw new Error(`negative fixture missing for ${ruleId}`);
  }
  return match;
}
