import { describe, expect, it, vi } from "vitest";
import { createJiraActionHandler } from "../src/live.js";

function fixture(confirmations: readonly boolean[]) {
  let confirmation = 0;
  const writes = vi.fn(async (
    operations: readonly { readonly id: string }[],
  ) => operations.map(operation => ({
      id: operation.id,
      status: "updated",
      propertiesRevision: "properties-next",
    }),
  ));
  const request = vi.fn(async (method: string, params: unknown) => {
    if (method === "search.query") {
      return {
        rows: [{
          kind: "note",
          id: "synthetic-note",
          title: "Synthetic note",
          path: "notes/synthetic.md",
          properties: { JiraNumber: "DEMO-1", JiraStatus: "Open" },
          propertiesRevision: "properties-1",
        }],
        total: 1,
        cursor: null,
        diagnostics: [],
        dateContext: {
          now: "2026-01-01T00:00:00.000Z",
          weekStart: "monday",
          timeZone: "UTC",
        },
      };
    }
    if (method === "network.request") {
      return {
        status: 200,
        headers: { etag: "\"synthetic\"" },
        body: {
          issues: [{
            key: "DEMO-1",
            fields: {
              status: { name: "Done" },
              assignee: { displayName: "Ada Synthetic" },
              updated: "2026-01-01T00:00:00.000Z",
            },
          }],
          isLast: true,
        },
      };
    }
    if (method === "dialogs.confirm") {
      return confirmations[confirmation++] ?? false;
    }
    if (method === "notes.updatePropertiesBatch") {
      return writes(
        (params as {
          readonly operations: readonly { readonly id: string }[];
        }).operations,
      );
    }
    throw new Error(`Unexpected synthetic method: ${method}`);
  });
  return {
    view: {
      request,
      ui: {
        setView: vi.fn(),
        updateView: vi.fn(),
        onAction: vi.fn(),
      },
    },
    request,
    writes,
  };
}

const action = (name: string) => ({ action: name, values: {} });

describe("live-sandboxed Jira workflow adapter", () => {
  it("routes one capability per action and writes only after confirmation", async () => {
    const configured = fixture([false, true]);
    const run = createJiraActionHandler(configured.view);
    await run(action("load-jira-notes"));
    await run(action("load-jira-issues"));
    await run(action("prepare-jira-preview"));
    await run(action("confirm-jira-preview"));
    await run(action("apply-jira-preview"));
    expect(configured.request).toHaveBeenCalledWith(
      "network.request",
      expect.objectContaining({ connection: "atlassian" }),
    );
    expect(configured.writes).not.toHaveBeenCalled();

    await run(action("confirm-jira-preview"));
    await run(action("apply-jira-preview"));
    expect(configured.writes).toHaveBeenCalledOnce();
  });
});
