import type { MatrixCell } from "../../../schema/src/records/context.js";
import {
  fixturesForRule as a11yFixturesForRule,
  positiveFixture as a11yPositiveFixture,
  routesForFixture as a11yRoutesForFixture,
} from "../../fixtures/a11y/index.js";
import {
  fixturesForRule as assetsFixturesForRule,
  positiveFixture as assetsPositiveFixture,
  routesForFixture as assetsRoutesForFixture,
} from "../../fixtures/assets/index.js";
import {
  fixturesForRule as geometryFixturesForRule,
  positiveFixture as geometryPositiveFixture,
} from "../../fixtures/geometry/index.js";
import {
  fixturesForRule as interactionFixturesForRule,
  positiveFixture as interactionPositiveFixture,
} from "../../fixtures/interaction/index.js";
import {
  fixturesForRule as relationsFixturesForRule,
  positiveFixture as relationsPositiveFixture,
} from "../../fixtures/relations/index.js";
import {
  fixturesForRule as renderedFixturesForRule,
  positiveFixture as renderedPositiveFixture,
} from "../../fixtures/rendered/index.js";
import {
  fixturesForRule as sweepsFixturesForRule,
  positiveFixture as sweepsPositiveFixture,
  routesForFixture as sweepsRoutesForFixture,
} from "../../fixtures/sweeps/index.js";
import type { EngineName } from "../index.js";
import type { CalibrationFamily, CalibrationRuleId, TextDirection } from "./types.js";

type FixtureLike = {
  html?: string;
  route?: string;
  cell?: Partial<MatrixCell>;
};

function mergeCell(
  fixture: FixtureLike,
  engine: EngineName,
  direction: TextDirection,
): Partial<MatrixCell> | undefined {
  const locale = direction === "rtl" ? "ar-SA" : "en-US";
  const baseCell = fixture.cell ?? {};
  const baseState = baseCell.state ?? {};

  return {
    ...baseCell,
    locale,
    state: {
      ...baseState,
      engine,
    },
  };
}

function selectFixture<T extends { variant: string }>(
  gallery: T[],
  direction: TextDirection,
  fallback: T,
): T {
  if (direction === "rtl") {
    const rtl = gallery.find((entry) => entry.variant === "rtl");
    if (rtl !== undefined) {
      return rtl;
    }
  }
  return fallback;
}

export function calibrationFixture(
  family: CalibrationFamily,
  ruleId: CalibrationRuleId,
  engine: EngineName,
  direction: TextDirection,
): { fixture: unknown; routes: Record<string, string | { status: number; body: string }> } {
  switch (family) {
    case "rendered": {
      const gallery = renderedFixturesForRule(ruleId as "UI-010");
      const selected = selectFixture(gallery, direction, renderedPositiveFixture(ruleId as "UI-010"));
      const fixture = {
        ...selected,
        cell: mergeCell(selected, engine, direction),
      };
      return {
        fixture,
        routes: {
          "/fixture": selected.html,
          "/api/data": { status: 404, body: '{"error":"missing"}' },
          "/api/allowed": { status: 404, body: '{"error":"allowed"}' },
        },
      };
    }
    case "geometry": {
      const gallery = geometryFixturesForRule(ruleId as "UI-021");
      const selected = selectFixture(gallery, direction, geometryPositiveFixture(ruleId as "UI-021"));
      const fixture = {
        ...selected,
        cell: mergeCell(selected, engine, direction),
      };
      return {
        fixture,
        routes: { "/fixture": selected.html },
      };
    }
    case "interaction": {
      const gallery = interactionFixturesForRule(ruleId as "UI-033");
      const selected = selectFixture(
        gallery,
        direction,
        interactionPositiveFixture(ruleId as "UI-033"),
      );
      const fixture = {
        ...selected,
        cell: mergeCell(selected, engine, direction),
      };
      return {
        fixture,
        routes: { "/fixture": selected.html },
      };
    }
    case "relations": {
      const gallery = relationsFixturesForRule(ruleId as "UI-034");
      const selected = selectFixture(
        gallery,
        direction,
        relationsPositiveFixture(ruleId as "UI-034"),
      );
      const fixture = {
        ...selected,
        cell: mergeCell(selected, engine, direction),
      };
      return {
        fixture,
        routes: { "/fixture": selected.html },
      };
    }
    case "sweeps": {
      const gallery = sweepsFixturesForRule(ruleId as "UI-052");
      const selected = selectFixture(gallery, direction, sweepsPositiveFixture(ruleId as "UI-052"));
      const fixture = {
        ...selected,
        cell: mergeCell(selected, engine, direction),
      };
      return {
        fixture,
        routes: sweepsRoutesForFixture(selected),
      };
    }
    case "a11y": {
      const gallery = a11yFixturesForRule(ruleId as "UI-060");
      const selected = selectFixture(gallery, direction, a11yPositiveFixture(ruleId as "UI-060"));
      const fixture = {
        ...selected,
        cell: mergeCell(selected, engine, direction),
      };
      return {
        fixture,
        routes: a11yRoutesForFixture(selected),
      };
    }
    case "assets": {
      const gallery = assetsFixturesForRule(ruleId as "UI-070");
      const selected = selectFixture(gallery, direction, assetsPositiveFixture(ruleId as "UI-070"));
      const fixture = {
        ...selected,
        cell: mergeCell(selected, engine, direction),
      };
      return {
        fixture,
        routes: assetsRoutesForFixture(selected),
      };
    }
    default: {
      const exhaustive: never = family;
      throw new Error(`unsupported calibration family: ${String(exhaustive)}`);
    }
  }
}
