import { describe, vi } from "vitest";
import { RecordingTracer } from "@repo/core-testing/instrumentation";
import { PagesRepository } from "@/infrastructure/repositories/pages.repository";
import {
  pagesRepositoryContract,
  CONTRACT_PAGES_SEED,
} from "@/__contracts__/pages-repository.contract";
import { stubPayloadConfig } from "@repo/core-testing/payload/stub-config";
import type { Page } from "@/entities/models/page";

// ---------------------------------------------------------------------------
// In-memory Payload stub for pages (read-only collection)
// ---------------------------------------------------------------------------

function buildPayloadPagesStub(seed: Page[]) {
  const store = new Map<string, Record<string, unknown>>(
    seed.map((p) => [
      p.id,
      {
        id: p.id,
        title: p.title,
        slug: p.slug,
        hero: p.hero
          ? {
              heading: p.hero.heading,
              subheading: p.hero.subheading,
            }
          : null,
        layout: p.layout,
        status: p.status,
        publishedAt: p.publishedAt ? p.publishedAt.toISOString() : null,
        seo: p.seo ? { title: p.seo.title, description: p.seo.description } : null,
        createdAt: p.createdAt.toISOString(),
        updatedAt: p.updatedAt.toISOString(),
      },
    ]),
  );

  return {
    find: vi.fn(
      async ({
        where,
        limit,
      }: {
        collection: string;
        where?: { slug?: { equals: string }; status?: { equals: string } };
        limit?: number;
        page?: number;
        overrideAccess?: boolean;
      }) => {
        let docs = Array.from(store.values());
        if (where?.slug) {
          docs = docs.filter((d) => d.slug === where.slug?.equals);
        }
        if (where?.status) {
          docs = docs.filter((d) => d.status === where.status?.equals);
        }
        if (limit !== undefined) {
          docs = docs.slice(0, limit);
        }
        return { docs };
      },
    ),
  };
}

vi.mock("payload", () => ({
  getPayload: vi.fn(),
}));

// ---------------------------------------------------------------------------
// Contract suite
// ---------------------------------------------------------------------------

describe("PagesRepository", () => {
  describe("contract", () => {
    const tracer = new RecordingTracer();
    pagesRepositoryContract.run(
      async () => {
        const stub = buildPayloadPagesStub(CONTRACT_PAGES_SEED);
        const { getPayload } = await import("payload");
        (getPayload as ReturnType<typeof vi.fn>).mockResolvedValue(stub);
        return new PagesRepository(stubPayloadConfig, tracer);
      },
      { tracer: () => tracer },
    );
  });
});
