import { describe, expect, test } from "bun:test";
import { join } from "node:path";
import { repoRoot } from "./config";
import { ghScopedHelp } from "./gh/help";
import { parseOptions } from "./gh/options";
import { isRemovableHeadWorktree, runPrMergeCloseout } from "./gh/pr-merge-closeout";
import { prMergeRetryCommand } from "./gh/pr-summary";
import type { GitHubPullRequest } from "./gh/types";

describe("gh pr merge branch lifecycle", () => {
  test("preserves the head branch by default", () => {
    expect(parseOptions(["pr", "merge", "24"]).deleteBranch).toBe(false);
    expect(prMergeRetryCommand("owner/repo", 24, "merge", false)).toBe(
      "bun scripts/cli.ts gh pr merge 24 --repo owner/repo --merge",
    );
  });

  test("deletes only when explicitly requested", () => {
    expect(parseOptions(["pr", "merge", "24", "--delete-branch"]).deleteBranch).toBe(true);
    expect(prMergeRetryCommand("owner/repo", 24, "merge", true)).toEndWith("--merge --delete-branch");
  });

  test("keeps the compatibility flag and rejects conflicting intent", () => {
    expect(parseOptions(["pr", "merge", "24", "--keep-branch"]).deleteBranch).toBe(false);
    expect(() => parseOptions(["pr", "merge", "24", "--keep-branch", "--delete-branch"])).toThrow(
      "either --delete-branch or --keep-branch",
    );
  });

  test("documents the safe default in scoped help", () => {
    const help = ghScopedHelp(["pr", "merge", "--help"]) as { notes: string[] };
    const notes = help.notes.join("\n");
    expect(notes).toContain("preserves remote and local head branch state by default");
    expect(notes).toContain("--delete-branch");
    expect(notes).not.toContain("deletes the same-repo head branch by default");
  });

  test("never removes the main worktree and accepts registered task worktrees outside the repo", () => {
    expect(isRemovableHeadWorktree(repoRoot)).toBe(false);
    expect(isRemovableHeadWorktree(join(repoRoot, "..", ".worktree", "task"))).toBe(true);
    expect(isRemovableHeadWorktree(join(repoRoot, ".worktree", "task"))).toBe(true);
  });

  test("preserves local head state unless deletion is explicit", () => {
    const pullRequest = {
      head: { ref: "development" },
      base: { ref: "master" },
    } as GitHubPullRequest;
    const result = runPrMergeCloseout(
      "pikasTech/unidesk",
      pullRequest,
      parseOptions(["pr", "merge", "24", "--dry-run"]),
    );

    expect(result.localWorktree).toMatchObject({
      skipped: true,
      skippedReason: "branch-preserved",
    });
  });
});
