import { expect } from "e2e";
import { test, WEB } from "./t3.ts";
import { APP_DIR } from "../e2e.config.ts";

test(
  "Composer keeps the newest GitLab merge request with mixed timestamp offsets",
  WEB,
  async ({ t3, app, screen, browser }) => {
    const project = await t3.project("gitlab-offset-demo", {
      ".git/config":
        '[core]\nrepositoryformatversion = 0\nbare = false\n[remote "origin"]\nurl = https://gitlab.example.com/owner/repo.git\nfetch = +refs/heads/*:refs/remotes/origin/*\n',
      "README.md": "Synthetic GitLab merge requests for timestamp ordering.\n",
    });
    await t3.thread({
      project,
      title: "GitLab update ordering",
      messages: ["Check merge request ordering"],
    });
    await t3.open();
    await screen
      .getByRole("button", "GitLab update ordering, Done, gitlab-offset-demo")
      .waitFor({ state: "visible" });
    const threadPath = await browser.evaluate(async (root) => {
      const load = (path: string) => import(/* @vite-ignore */ path);
      const { appAtomRegistry } = await load("/src/rpc/atomRegistry.ts");
      const { environmentThreadShells } = await load("/src/state/threads.ts");
      const { connectionAtomRuntime } = await load("/src/connection/runtime.ts");
      const { createEnvironmentRpcCommand, runAtomCommand } = await load(
        `/@fs${root}/packages/client-runtime/src/state/runtime.ts`,
      );
      const threads = appAtomRegistry.get(environmentThreadShells.threadShellsAtom);
      const thread = threads.find(
        (item: { title: string }) => item.title === "GitLab update ordering",
      );
      if (!thread) throw new Error("Seed thread not loaded");
      const command = createEnvironmentRpcCommand(connectionAtomRuntime, {
        label: "scenario.seed",
        tag: "orchestration.dispatchCommand",
      });
      const dispatch = async (input: Record<string, unknown>) => {
        const result = await runAtomCommand(appAtomRegistry, command, {
          environmentId: thread.environmentId,
          input: { ...input, threadId: thread.id, commandId: crypto.randomUUID() },
        });
        if (result._tag === "Failure") throw new Error(JSON.stringify(result));
      };
      const rows = [
        ...Array.from({ length: 12 }, (_, index) => ({
          number: 401 + index,
          at: "2026-10-25T02:50:00+02:00",
        })),
        { number: 499, at: "2026-10-25T02:10:00+01:00" },
      ];
      const { decodeMergeRequestListJson, decodeMergeRequestGraphqlListJson } = await load(
        `/@fs${root}/packages/source-control-gitlab/src/server/gitLabMergeRequestJson.ts`,
      );
      const rest = decodeMergeRequestListJson(
        JSON.stringify(
          rows.map(({ number, at }) => ({
            iid: number,
            title:
              number === 499
                ? "Newer merge request (01:10 UTC)"
                : `Older merge request ${number} (00:50 UTC)`,
            web_url: `https://gitlab.example.com/owner/repo/-/merge_requests/${number}`,
            source_branch: `feature-${number}`,
            target_branch: "main",
            state: "opened",
            created_at: "2026-10-01T00:00:00Z",
            updated_at: at,
          })),
        ),
      );
      if (rest._tag !== "Success") throw new Error("REST decode failed");
      const graphql = decodeMergeRequestGraphqlListJson(
        JSON.stringify({
          data: {
            project: {
              mergeRequests: {
                pageInfo: { hasNextPage: false, endCursor: null },
                nodes: rest.success.items.map((row) => ({
                  iid: String(row.number),
                  title: row.title,
                  webUrl: row.url,
                  state: "opened",
                  draft: false,
                  createdAt: row.createdAt,
                  updatedAt: row.updatedAt,
                  sourceBranch: row.headBranch,
                  targetBranch: row.baseBranch,
                })),
              },
            },
          },
        }),
      );
      if (graphql._tag !== "Success") throw new Error("GraphQL decode failed");
      for (const row of graphql.success.items) {
        const { number, updatedAt: at } = row;
        const key = { host: "gitlab.example.com", repository: "owner/repo", number };
        await dispatch({
          type: "thread.pull-request.link",
          ...key,
          url: `https://gitlab.example.com/owner/repo/-/merge_requests/${number}`,
          source: "manual",
        });
        await dispatch({
          type: "thread.pull-request-link.sync",
          ...key,
          stack: null,
          snapshot: {
            state: "open",
            title:
              number === 499
                ? "Newer merge request (01:10 UTC)"
                : `Older merge request ${number} (00:50 UTC)`,
            headBranch: `feature-${number}`,
            baseBranch: "main",
            isDraft: false,
            updatedAt: at,
            syncedAt: "2026-10-25T02:00:00.000Z",
          },
        });
      }
      return `/threads/${thread.environmentId}/${thread.id}`;
    }, APP_DIR);
    await app.open(threadPath);
    await screen.getByRole("textbox").fill("#499");
    await screen
      .getByText("Newer merge request (01:10 UTC)", { exact: true })
      .waitFor({ state: "visible" });
    await app.screenshot("exact-number-workaround");
    await screen.getByText("Newer merge request (01:10 UTC)", { exact: true }).tap();
    await screen.getByRole("textbox").fill("#4");
    // Wait for the menu's old rows to render before capturing either ordering.
    await screen
      .getByText("Older merge request 401 (00:50 UTC)", { exact: true })
      .first()
      .waitFor({ state: "visible" });
    await app.screenshot("mixed-offset-number-suggestions");
    await expect(
      screen.getByText("Newer merge request (01:10 UTC)", { exact: true }),
    ).toBeVisible();
  },
);
