import type { Doc, Id } from "@code/backend/convex/_generated/dataModel";
import { describe, expect, test } from "vitest";

import {
  buildProjectLoopView,
  summarizeProjectIssues,
} from "./project-evidence";

const makeIssue = (
  status: Doc<"projectIssues">["status"],
  issueId: Id<"projectIssues"> = "issue-1" as Id<"projectIssues">
): Doc<"projectIssues"> =>
  ({
    _creationTime: 1,
    _id: issueId,
    body: "Make the project loop visible in the web app.",
    createdAt: 1000,
    number: 8,
    projectId: "project-1",
    status,
    title: "Build project loop UI",
    updatedAt: 2000,
  }) as Doc<"projectIssues">;

const makeArtifact = (content: string): Doc<"projectArtifacts"> =>
  ({
    _creationTime: 1,
    _id: "artifact-1",
    content,
    createdAt: 1000,
    path: "artifacts.md",
    projectId: "project-1",
    revision: 2,
    updatedAt: 2000,
  }) as Doc<"projectArtifacts">;

describe("project evidence", () => {
  test("turns published PR evidence into a review action", () => {
    const view = buildProjectLoopView({
      artifacts: [
        makeArtifact(
          "Verification: 14 unit tests passed.\nPull request: PR #42"
        ),
      ],
      issue: makeIssue("completed"),
      source: {
        host: "git.example.com",
        repositoryPath: "puter/zopu",
        url: "https://git.example.com/puter/zopu",
      },
    });

    expect(view?.progress).toBe(100);
    expect(view?.verification).toBe("passed");
    expect(view?.pullRequest.reviewUrl).toBe(
      "https://git.example.com/puter/zopu/pulls/42"
    );
    expect(view?.verificationNote).toContain(
      "Verification: 14 unit tests passed."
    );
  });

  test("keeps the review slot pending when no PR is published", () => {
    const view = buildProjectLoopView({
      artifacts: [
        makeArtifact("The run is recording implementation evidence."),
      ],
      issue: makeIssue("working"),
      source: undefined,
    });

    expect(view?.verification).toBe("running");
    expect(view?.pullRequest.state).toBe("pending");
    expect(view?.pullRequest.reviewUrl).toBeUndefined();
  });

  test("summarizes the project queue without inventing work", () => {
    const summary = summarizeProjectIssues([
      makeIssue("working"),
      makeIssue("needs-input", "issue-2" as Id<"projectIssues">),
      makeIssue("completed", "issue-3" as Id<"projectIssues">),
    ]);

    expect(summary).toEqual({
      active: 2,
      completed: 1,
      needsInput: 1,
      total: 3,
    });
  });
});
