import { describe, expect, it } from "vitest";
import { buildMatchResponse, buildPageOverlayResponse } from "./index.mjs";

const context = {
  product: {
    name: "web",
    directory: "/tmp/web",
  },
  services: [
    {
      name: "web",
      baseUrl: "http://localhost:3000",
      origin: "http://localhost:3000",
    },
  ],
  discovery: {
    files: [
      {
        path: "app/coverage/__testkit__/coverage.pw.testkit.ts",
        displayName: "Coverage",
        service: "web",
        suiteName: "coverage",
        selectionType: "pw",
        framework: "playwright",
        skipped: false,
      },
      {
        path: "app/api/coverage/__testkit__/coverage.int.testkit.ts",
        displayName: "Coverage API",
        service: "web",
        suiteName: "coverage",
        selectionType: "int",
        framework: "k6",
        skipped: false,
      },
    ],
    coverageGraph: {
      schemaVersion: 1,
      nodes: [
        {
          id: "page_view:web:/coverage",
          kind: "page_view",
          service: "web",
          label: "Coverage",
          route: "/coverage",
          filePath: "app/coverage/page.tsx",
        },
        {
          id: "ui_surface:web:/coverage:coverage-refresh-button",
          kind: "ui_surface",
          service: "web",
          label: "Refresh overlay",
          route: "/coverage",
          filePath: "app/coverage/page.tsx",
          target: {
            kind: "testId",
            value: "coverage-refresh-button",
            confidence: "high",
          },
        },
        {
          id: "api_route:web:GET:/api/coverage",
          kind: "api_route",
          service: "web",
          label: "GET /api/coverage",
          route: "/coverage",
          method: "GET",
          path: "/api/coverage",
          filePath: "app/api/coverage/route.ts",
        },
        {
          id: "test_file:web:app/coverage/__testkit__/coverage.pw.testkit.ts",
          kind: "test_file",
          service: "web",
          label: "coverage.pw.testkit.ts",
          filePath: "app/coverage/__testkit__/coverage.pw.testkit.ts",
        },
        {
          id: "test_file:web:app/api/coverage/__testkit__/coverage.int.testkit.ts",
          kind: "test_file",
          service: "web",
          label: "coverage.int.testkit.ts",
          filePath: "app/api/coverage/__testkit__/coverage.int.testkit.ts",
        },
      ],
      edges: [
        {
          id: "contains:page_view:web:/coverage:ui_surface:web:/coverage:coverage-refresh-button",
          kind: "contains",
          from: "page_view:web:/coverage",
          to: "ui_surface:web:/coverage:coverage-refresh-button",
          confidence: "high",
        },
        {
          id: "requests:ui_surface:web:/coverage:coverage-refresh-button:api_route:web:GET:/api/coverage",
          kind: "requests",
          from: "ui_surface:web:/coverage:coverage-refresh-button",
          to: "api_route:web:GET:/api/coverage",
          confidence: "high",
        },
      ],
      evidence: [
        {
          id: "evidence:web:app/coverage/__testkit__/coverage.pw.testkit.ts",
          source: "convention",
          confidence: "high",
          service: "web",
          suiteName: "coverage",
          selectionType: "pw",
          framework: "playwright",
          testFilePath: "app/coverage/__testkit__/coverage.pw.testkit.ts",
          coveredNodeIds: [
            "page_view:web:/coverage",
            "ui_surface:web:/coverage:coverage-refresh-button",
          ],
          details: {
            route: "/coverage",
            targets: [{ kind: "testId", value: "coverage-refresh-button", confidence: "high" }],
          },
        },
        {
          id: "evidence:web:app/api/coverage/__testkit__/coverage.int.testkit.ts",
          source: "convention",
          confidence: "high",
          service: "web",
          suiteName: "coverage",
          selectionType: "int",
          framework: "k6",
          testFilePath: "app/api/coverage/__testkit__/coverage.int.testkit.ts",
          coveredNodeIds: ["api_route:web:GET:/api/coverage"],
          details: { requestPaths: ["/api/coverage"] },
        },
      ],
    },
  },
  runArtifact: {
    generatedAt: "2026-01-01T00:00:00.000Z",
    run: {
      status: "failed",
    },
    services: [
      {
        name: "web",
        suites: [
          {
            name: "coverage",
            type: "pw",
            framework: "playwright",
            files: [
              {
                path: "app/coverage/__testkit__/coverage.pw.testkit.ts",
                status: "failed",
                error: "Expected coverage heading",
                failureDetails: [],
              },
            ],
          },
        ],
      },
    ],
  },
};

const routeLevelContext = {
  product: {
    name: "dashboard",
    directory: "/tmp/dashboard",
  },
  services: [
    {
      name: "dashboard",
      baseUrl: "http://localhost:3000",
      origin: "http://localhost:3000",
    },
  ],
  discovery: {
    files: [
      {
        path: "__testkit__/projects/projects.int.testkit.ts",
        displayName: "Projects",
        service: "dashboard",
        suiteName: "projects",
        selectionType: "int",
        framework: "k6",
        skipped: false,
      },
    ],
    coverageGraph: {
      schemaVersion: 1,
      nodes: [
        {
          id: "page_view:dashboard:/projects",
          kind: "page_view",
          service: "dashboard",
          label: "Projects",
          route: "/projects",
          filePath: "src/app/projects/page.tsx",
        },
        {
          id: "ui_surface:dashboard:/projects:project-create-button",
          kind: "ui_surface",
          service: "dashboard",
          label: "Create Project",
          route: "/projects",
          filePath: "src/app/projects/page.tsx",
          target: { kind: "testId", value: "project-create-button", confidence: "high" },
        },
        {
          id: "ui_action:dashboard:/projects:handleCreate",
          kind: "ui_action",
          service: "dashboard",
          label: "handleCreate",
          route: "/projects",
          filePath: "src/app/projects/page.tsx",
        },
        {
          id: "client_request:dashboard:provider:GET:/api/projects",
          kind: "client_request",
          service: "dashboard",
          label: "GET /api/projects",
          route: "/projects",
          method: "GET",
          path: "/api/projects",
          filePath: "src/components/project-context.tsx",
        },
        {
          id: "client_request:dashboard:projects:POST:/api/projects",
          kind: "client_request",
          service: "dashboard",
          label: "POST /api/projects",
          route: "/projects",
          method: "POST",
          path: "/api/projects",
          filePath: "src/app/projects/page.tsx",
        },
        {
          id: "api_route:dashboard:GET:/api/projects",
          kind: "api_route",
          service: "dashboard",
          label: "GET /api/projects",
          route: "/projects",
          method: "GET",
          path: "/api/projects",
          filePath: "src/app/api/projects/route.ts",
        },
        {
          id: "api_route:dashboard:POST:/api/projects",
          kind: "api_route",
          service: "dashboard",
          label: "POST /api/projects",
          route: "/projects",
          method: "POST",
          path: "/api/projects",
          filePath: "src/app/api/projects/route.ts",
        },
      ],
      edges: [
        {
          id: "contains:page_view:dashboard:/projects:ui_surface:dashboard:/projects:project-create-button",
          kind: "contains",
          from: "page_view:dashboard:/projects",
          to: "ui_surface:dashboard:/projects:project-create-button",
        },
        {
          id: "triggers:ui_surface:dashboard:/projects:project-create-button:ui_action:dashboard:/projects:handleCreate",
          kind: "triggers",
          from: "ui_surface:dashboard:/projects:project-create-button",
          to: "ui_action:dashboard:/projects:handleCreate",
        },
        {
          id: "requests:page_view:dashboard:/projects:client_request:dashboard:provider:GET:/api/projects",
          kind: "requests",
          from: "page_view:dashboard:/projects",
          to: "client_request:dashboard:provider:GET:/api/projects",
        },
        {
          id: "requests:ui_action:dashboard:/projects:handleCreate:client_request:dashboard:projects:POST:/api/projects",
          kind: "requests",
          from: "ui_action:dashboard:/projects:handleCreate",
          to: "client_request:dashboard:projects:POST:/api/projects",
        },
        {
          id: "handles:client_request:dashboard:provider:GET:/api/projects:api_route:dashboard:GET:/api/projects",
          kind: "handles",
          from: "client_request:dashboard:provider:GET:/api/projects",
          to: "api_route:dashboard:GET:/api/projects",
        },
        {
          id: "handles:client_request:dashboard:projects:POST:/api/projects:api_route:dashboard:POST:/api/projects",
          kind: "handles",
          from: "client_request:dashboard:projects:POST:/api/projects",
          to: "api_route:dashboard:POST:/api/projects",
        },
      ],
      evidence: [
        {
          id: "evidence:dashboard:__testkit__/projects/projects.int.testkit.ts",
          source: "convention",
          confidence: "high",
          service: "dashboard",
          suiteName: "projects",
          selectionType: "int",
          framework: "k6",
          testFilePath: "__testkit__/projects/projects.int.testkit.ts",
          coveredNodeIds: [
            "api_route:dashboard:GET:/api/projects",
            "api_route:dashboard:POST:/api/projects",
          ],
          details: {
            route: "/projects",
            requestPaths: ["/api/projects"],
          },
        },
      ],
      diagnostics: [],
    },
  },
  runArtifact: null,
};

describe("testkit bridge", () => {
  it("matches pages against service base URLs", () => {
    expect(buildMatchResponse(context, "http://localhost:3000/coverage")).toMatchObject({
      matched: true,
      route: "/coverage",
      service: {
        name: "web",
      },
    });
  });

  it("builds page overlay responses from graph coverage and run artifacts", () => {
    expect(buildPageOverlayResponse(context, "http://localhost:3000/coverage")).toMatchObject({
      summary: {
        failureState: "failing",
        coverageState: "covered",
        relatedFailureCount: 2,
        relatedCoverageCount: 2,
        coverageBreakdown: {
          direct: 1,
          indirect: 0,
          mixed: 1,
        },
      },
      failures: expect.arrayContaining([
        expect.objectContaining({
          kind: "page_view",
          label: "Coverage",
        }),
        expect.objectContaining({
          kind: "ui_surface",
          label: "Refresh overlay",
          importance: "high",
          reason: "Refresh overlay is implicated by 1 failing test.",
          targets: [{ kind: "testId", value: "coverage-refresh-button", confidence: "high" }],
          failedTests: [
            expect.objectContaining({
              filePath: "app/coverage/__testkit__/coverage.pw.testkit.ts",
              type: "pw",
            }),
          ],
        }),
      ]),
      coverage: expect.arrayContaining([
        expect.objectContaining({
          kind: "page_view",
          label: "Coverage",
          supportKind: "direct",
        }),
        expect.objectContaining({
          kind: "ui_surface",
          label: "Refresh overlay",
          importance: "high",
          supportKind: "mixed",
          targets: [{ kind: "testId", value: "coverage-refresh-button", confidence: "high" }],
          supportingTests: [
            expect.objectContaining({
              filePath: "app/coverage/__testkit__/coverage.pw.testkit.ts",
            }),
            expect.objectContaining({
              filePath: "app/api/coverage/__testkit__/coverage.int.testkit.ts",
            }),
          ],
        }),
      ]),
    });
  });

  it("retains route-level coverage when support comes from page-owned requests outside any surfaced control", () => {
    expect(buildPageOverlayResponse(routeLevelContext, "http://localhost:3000/projects")).toMatchObject({
      summary: {
        coverageState: "covered",
        relatedCoverageCount: 2,
      },
      coverage: expect.arrayContaining([
        expect.objectContaining({
          kind: "page_view",
          label: "Projects",
          supportKind: "indirect",
        }),
        expect.objectContaining({
          kind: "ui_surface",
          label: "Create Project",
          supportKind: "indirect",
        }),
      ]),
    });
  });
});
