import { jest, describe, it, expect, beforeEach, afterEach, beforeAll } from "@jest/globals"
let createPr: typeof import("../create-pr").createPr
let triggerCreatePr: typeof import("../create-pr").triggerCreatePr
let setCreatePrDependencies: typeof import("../create-pr").setCreatePrDependencies
let resetCreatePrDependencies: typeof import("../create-pr").resetCreatePrDependencies
let setTriggerCreatePrDependencies: typeof import("../create-pr").setTriggerCreatePrDependencies
let resetTriggerCreatePrDependencies: typeof import("../create-pr").resetTriggerCreatePrDependencies
let createStandalonePRTitleAndBody: typeof import("../create-pr").createStandalonePRTitleAndBody
type PrContentBuilder = import("../create-pr").PrContentBuilder
// Note: Global mocks are set up in jest.setup.ts

describe("createPr", () => {
  beforeAll(async () => {
    process.env.KEY_VAULT_NAME = "mocked-keyvault-name"
    const mod = await import("../create-pr")
    createPr = mod.createPr
    triggerCreatePr = mod.triggerCreatePr
    setCreatePrDependencies = mod.setCreatePrDependencies
    resetCreatePrDependencies = mod.resetCreatePrDependencies
    setTriggerCreatePrDependencies = mod.setTriggerCreatePrDependencies
    resetTriggerCreatePrDependencies = mod.resetTriggerCreatePrDependencies
    createStandalonePRTitleAndBody = mod.createStandalonePRTitleAndBody
  })
  let mockReq: any
  let mockRes: any
  let mockDependencies: any

  beforeEach(() => {
    // Setup request mock
    mockReq = {
      body: {
        owner: "test-owner",
        repo: "test-repo",
        baseBranch: "main",
        diffContents: [{ file: "test.js", content: "test" }],
        prCommentFields: {
          function_name: "testFunction",
          speedup_pct: 50,
          speedup_x: 2,
          optimization_explanation: "Test optimization",
        },
        existingTests: [],
        generatedTests: [],
        coverage_message: "coverage message", // Changed from coverage to coverage_message
        traceId: "test-trace-id",
        replayTests: "replay tests",
        concolicTests: "concolic tests",
        optimizationReview: "medium",
      },
      userId: "test-user-id",
    }

    // Setup response mock
    mockRes = {
      status: jest.fn().mockReturnThis(),
      send: jest.fn(),
      json: jest.fn(),
    }

    // Setup mock dependencies with proper typing - cast to any to avoid complex Prisma types
    mockDependencies = {
      prisma: {
        optimization_features: {
          findUnique: jest.fn(),
          update: jest.fn(),
        },
      } as any, // Cast to any to avoid Prisma type complexity
      userNickname: jest.fn(),
      getInstallationOctokitByOwner: jest.fn(),
      isUserCollaborator: jest.fn(),
      requiresApproval: jest.fn(),
      requestApproval: jest.fn(),
      triggerCreatePr: jest.fn(),
      posthog: {
        capture: jest.fn(),
      },
      isDiffContentsWellFormed: jest.fn().mockReturnValue(true),
      githubApp: {},
      registerRepositoryAndMember: jest.fn(() => Promise.resolve(12345)),
    }

    setCreatePrDependencies(mockDependencies)
  })

  afterEach(() => {
    if (resetCreatePrDependencies) {
      resetCreatePrDependencies()
    }
    jest.clearAllMocks()
  })

  describe("input validation", () => {
    it("should return 400 when owner is missing", async () => {
      mockReq.body.owner = undefined

      await createPr(mockReq, mockRes)

      expect(mockRes.status).toHaveBeenCalledWith(400)
      expect(mockRes.send).toHaveBeenCalledWith("Missing or malformed fields")
    })

    it("should return 400 when repo is missing", async () => {
      mockReq.body.repo = undefined

      await createPr(mockReq, mockRes)

      expect(mockRes.status).toHaveBeenCalledWith(400)
      expect(mockRes.send).toHaveBeenCalledWith("Missing or malformed fields")
    })

    it("should return 400 when baseBranch is missing", async () => {
      mockReq.body.baseBranch = undefined

      await createPr(mockReq, mockRes)

      expect(mockRes.status).toHaveBeenCalledWith(400)
      expect(mockRes.send).toHaveBeenCalledWith("Missing or malformed fields")
    })

    it("should return 400 for malformed diff contents", async () => {
      mockDependencies.isDiffContentsWellFormed.mockReturnValue(false)

      await createPr(mockReq, mockRes)

      expect(mockRes.status).toHaveBeenCalledWith(400)
      expect(mockRes.send).toHaveBeenCalledWith("Missing or malformed fields")
      expect(mockDependencies.isDiffContentsWellFormed).toHaveBeenCalledWith(
        mockReq.body.diffContents,
      )
    })

    it("should handle missing traceId by defaulting to empty string", async () => {
      delete mockReq.body.traceId
      mockDependencies.userNickname.mockResolvedValue("test-user")
      mockDependencies.getInstallationOctokitByOwner.mockResolvedValue({
        rest: { git: { getRef: (jest.fn() as any).mockResolvedValue({ status: 200 }) } },
      })
      mockDependencies.isUserCollaborator.mockResolvedValue(true)
      mockDependencies.requiresApproval.mockReturnValue(false)
      mockDependencies.triggerCreatePr.mockResolvedValue(456)

      await createPr(mockReq, mockRes)

      expect(mockDependencies.triggerCreatePr).toHaveBeenCalledWith(
        "test-owner",
        "test-repo",
        "main",
        mockReq.body.diffContents,
        mockReq.body.prCommentFields,
        mockReq.body.existingTests,
        mockReq.body.generatedTests,
        mockReq.body.coverage_message,
        "test-user-id",
        "test-user",
        expect.anything(), // installationOctokit
        "replay tests",
        "concolic tests",
        "", // traceId should be empty string
        "medium",
        undefined, // stagingBranch
        "free", // userTier defaults to free
        null, // organizationId
        undefined, // originalLineProfiler
        undefined, // optimizedLineProfiler
      )
    })

    it("should not require diffContents when stagingBranch is provided", async () => {
      mockReq.body.stagingBranch = "codeflash-staging/test-branch"
      mockReq.body.diffContents = undefined
      mockDependencies.userNickname.mockResolvedValue("test-user")
      mockDependencies.getInstallationOctokitByOwner.mockResolvedValue({})
      mockDependencies.isUserCollaborator.mockResolvedValue(true)
      mockDependencies.requiresApproval.mockReturnValue(false)
      mockDependencies.triggerCreatePr.mockResolvedValue(456)

      await createPr(mockReq, mockRes)

      expect(mockRes.status).not.toHaveBeenCalledWith(400)
      expect(mockDependencies.triggerCreatePr).toHaveBeenCalledWith(
        "test-owner",
        "test-repo",
        "main",
        undefined,
        mockReq.body.prCommentFields,
        mockReq.body.existingTests,
        mockReq.body.generatedTests,
        mockReq.body.coverage_message,
        "test-user-id",
        "test-user",
        {},
        "replay tests",
        "concolic tests",
        "test-trace-id",
        "medium",
        "codeflash-staging/test-branch",
        "free",
        null, // organizationId
        undefined, // originalLineProfiler
        undefined, // optimizedLineProfiler
      )
      expect(mockRes.json).toHaveBeenCalledWith(456)
    })

    it("should pass userTier from subscriptionInfo", async () => {
      mockReq.subscriptionInfo = { tier: "pro" }
      mockDependencies.userNickname.mockResolvedValue("test-user")
      mockDependencies.getInstallationOctokitByOwner.mockResolvedValue({})
      mockDependencies.isUserCollaborator.mockResolvedValue(true)
      mockDependencies.requiresApproval.mockReturnValue(false)
      mockDependencies.triggerCreatePr.mockResolvedValue(456)

      await createPr(mockReq, mockRes)

      expect(mockDependencies.triggerCreatePr).toHaveBeenCalledWith(
        "test-owner",
        "test-repo",
        "main",
        mockReq.body.diffContents,
        mockReq.body.prCommentFields,
        mockReq.body.existingTests,
        mockReq.body.generatedTests,
        mockReq.body.coverage_message,
        "test-user-id",
        "test-user",
        {},
        "replay tests",
        "concolic tests",
        "test-trace-id",
        "medium",
        undefined,
        "pro",
        null, // organizationId
        undefined, // originalLineProfiler
        undefined, // optimizedLineProfiler
      )
    })
  })

  describe("authentication and authorization", () => {
    it("should return 401 when user nickname is null", async () => {
      mockDependencies.userNickname.mockResolvedValue(null)

      await createPr(mockReq, mockRes)

      expect(mockDependencies.userNickname).toHaveBeenCalledWith("test-user-id")
      expect(mockRes.status).toHaveBeenCalledWith(401)
      expect(mockRes.json).toHaveBeenCalledWith({ error: "Unauthorized" })
    })

    it("should return 401 when installation octokit returns Error", async () => {
      mockDependencies.userNickname.mockResolvedValue("test-user")
      mockDependencies.getInstallationOctokitByOwner.mockResolvedValue(
        new Error("Installation not found"),
      )

      await createPr(mockReq, mockRes)

      expect(mockDependencies.getInstallationOctokitByOwner).toHaveBeenCalledWith(
        mockDependencies.githubApp,
        "test-owner",
        "test-repo",
        "test-user-id",
      )
      expect(mockRes.status).toHaveBeenCalledWith(401)
      expect(mockRes.json).toHaveBeenCalledWith({ error: "Installation not found" })
    })

    it("should return 403 when user is not a collaborator", async () => {
      mockDependencies.userNickname.mockResolvedValue("test-user")
      mockDependencies.getInstallationOctokitByOwner.mockResolvedValue({})
      mockDependencies.isUserCollaborator.mockResolvedValue(false)

      const consoleSpy = jest.spyOn(console, "log").mockImplementation(() => {})

      await createPr(mockReq, mockRes)

      expect(mockDependencies.isUserCollaborator).toHaveBeenCalledWith(
        {},
        "test-owner",
        "test-repo",
        "test-user",
      )
      expect(consoleSpy).toHaveBeenCalledWith(
        expect.stringContaining("test-user is not a collaborator on test-owner/test-repo"),
      )
      expect(mockRes.status).toHaveBeenCalledWith(403)
      expect(mockRes.json).toHaveBeenCalledWith({
        error:
          "You are not a collaborator on test-owner/test-repo. Please ensure you have write access to the repository.",
      })

      consoleSpy.mockRestore()
    })
  })

  describe("approval workflow", () => {
    beforeEach(() => {
      mockDependencies.userNickname.mockResolvedValue("test-user")
      mockDependencies.getInstallationOctokitByOwner.mockResolvedValue({
        rest: {
          git: {
            getRef: (jest.fn() as any).mockResolvedValue({ status: 200 }),
          },
        },
      })
      mockDependencies.isUserCollaborator.mockResolvedValue(true)
    })

    it("should skip approval check when traceId is missing", async () => {
      mockReq.body.traceId = ""
      mockDependencies.requiresApproval.mockReturnValue(true)
      mockDependencies.triggerCreatePr.mockResolvedValue(456)

      await createPr(mockReq, mockRes)

      expect(mockDependencies.prisma.optimization_features.findUnique).not.toHaveBeenCalled()
      expect(mockDependencies.triggerCreatePr).toHaveBeenCalled()
      expect(mockRes.json).toHaveBeenCalledWith(456)
    })

    it("should skip approval check when approval is not required", async () => {
      mockDependencies.requiresApproval.mockReturnValue(false)
      mockDependencies.triggerCreatePr.mockResolvedValue(456)

      await createPr(mockReq, mockRes)

      expect(mockDependencies.prisma.optimization_features.findUnique).not.toHaveBeenCalled()
      expect(mockDependencies.triggerCreatePr).toHaveBeenCalled()
      expect(mockRes.json).toHaveBeenCalledWith(456)
    })

    it("should return 403 for rejected requests", async () => {
      mockDependencies.requiresApproval.mockReturnValue(true)
      mockDependencies.prisma.optimization_features.findUnique.mockResolvedValue({
        approval_status: "rejected",
        approval_required: true,
      })

      await createPr(mockReq, mockRes)

      expect(mockDependencies.prisma.optimization_features.findUnique).toHaveBeenCalledWith({
        where: { trace_id: "test-trace-id" },
        select: {
          approval_required: true,
          approval_status: true,
        },
      })
      expect(mockRes.status).toHaveBeenCalledWith(403)
      expect(mockRes.json).toHaveBeenCalledWith({
        status: "rejected",
        message: "This optimization request was rejected.",
      })
    })

    it("should proceed with PR creation for approved requests with successful PR", async () => {
      mockDependencies.requiresApproval.mockReturnValue(true)
      mockDependencies.prisma.optimization_features.findUnique.mockResolvedValue({
        approval_status: "approved",
        approval_required: true,
      })
      mockDependencies.triggerCreatePr.mockResolvedValue(123)

      const consoleSpy = jest.spyOn(console, "log").mockImplementation(() => {})

      await createPr(mockReq, mockRes)

      expect(consoleSpy).toHaveBeenCalledWith(
        expect.stringContaining(
          "Request test-trace-id was previously approved, continuing with PR creation",
        ),
      )
      expect(mockDependencies.triggerCreatePr).toHaveBeenCalled()
      expect(mockRes.json).toHaveBeenCalledWith(123)

      consoleSpy.mockRestore()
    })

    it("should return 500 for approved requests with failed PR creation", async () => {
      mockDependencies.requiresApproval.mockReturnValue(true)
      mockDependencies.prisma.optimization_features.findUnique.mockResolvedValue({
        approval_status: "approved",
        approval_required: true,
      })
      mockDependencies.triggerCreatePr.mockResolvedValue(-1)

      await createPr(mockReq, mockRes)

      expect(mockRes.status).toHaveBeenCalledWith(500)
      expect(mockRes.send).toHaveBeenCalledWith("Error creating pull request")
    })

    it("should request approval for pending requests", async () => {
      mockDependencies.requiresApproval.mockReturnValue(true)
      mockDependencies.prisma.optimization_features.findUnique.mockResolvedValue({
        approval_status: "pending",
        approval_required: true,
      })

      await createPr(mockReq, mockRes)

      expect(mockDependencies.requestApproval).toHaveBeenCalledWith(
        "test-trace-id",
        "test-owner",
        "test-repo",
        "testFunction",
        "test-user-id",
        {
          type: "create-pr",
          owner: "test-owner",
          repo: "test-repo",
          baseBranch: "main",
          diffContents: mockReq.body.diffContents,
          prCommentFields: mockReq.body.prCommentFields,
          existingTests: [],
          generatedTests: [],
          coverage_message: "coverage message", // Changed from coverage to coverage_message
          userId: "test-user-id",
          replayTests: "replay tests",
          concolicTests: "concolic tests",
        },
      )
      expect(mockRes.status).toHaveBeenCalledWith(202)
      expect(mockRes.json).toHaveBeenCalledWith({
        status: "pending_approval",
        message: "This optimization requires approval. You will be notified when it is processed.",
      })
    })

    it("should request approval for new requests (null approval_status)", async () => {
      mockDependencies.requiresApproval.mockReturnValue(true)
      mockDependencies.prisma.optimization_features.findUnique.mockResolvedValue({
        approval_status: null,
        approval_required: true,
      })

      await createPr(mockReq, mockRes)

      expect(mockDependencies.requestApproval).toHaveBeenCalled()
      expect(mockRes.status).toHaveBeenCalledWith(202)
    })

    it("should handle missing optimization record", async () => {
      mockDependencies.requiresApproval.mockReturnValue(true)
      mockDependencies.prisma.optimization_features.findUnique.mockResolvedValue(null)

      await createPr(mockReq, mockRes)

      expect(mockDependencies.requestApproval).toHaveBeenCalled()
      expect(mockRes.status).toHaveBeenCalledWith(202)
    })
  })

  describe("successful PR creation without approval", () => {
    beforeEach(() => {
      mockDependencies.userNickname.mockResolvedValue("test-user")
      mockDependencies.getInstallationOctokitByOwner.mockResolvedValue({
        rest: { git: { getRef: (jest.fn() as any).mockResolvedValue({ status: 200 }) } },
      })
      mockDependencies.isUserCollaborator.mockResolvedValue(true)
      mockDependencies.requiresApproval.mockReturnValue(false)
    })

    it("should create PR successfully", async () => {
      mockDependencies.triggerCreatePr.mockResolvedValue(456)

      await createPr(mockReq, mockRes)

      expect(mockDependencies.triggerCreatePr).toHaveBeenCalledWith(
        "test-owner",
        "test-repo",
        "main",
        mockReq.body.diffContents,
        mockReq.body.prCommentFields,
        mockReq.body.existingTests,
        mockReq.body.generatedTests,
        mockReq.body.coverage_message, // Changed from coverage to coverage_message
        "test-user-id",
        "test-user",
        expect.anything(),
        "replay tests",
        "concolic tests",
        "test-trace-id",
        "medium",
        undefined, // stagingBranch
        "free", // userTier
        null, // organizationId
        undefined, // originalLineProfiler
        undefined, // optimizedLineProfiler
      )
      expect(mockRes.json).toHaveBeenCalledWith(456)
    })

    it("should return 500 when PR creation fails", async () => {
      mockDependencies.triggerCreatePr.mockResolvedValue(-1)
      // Remove traceId to test direct error path (staging fallback requires traceId)
      mockReq.body.traceId = undefined

      await createPr(mockReq, mockRes)

      expect(mockRes.status).toHaveBeenCalledWith(500)
      expect(mockRes.send).toHaveBeenCalledWith("Error creating pull request")
    })

    it("should return 500 when PR creation returns 0", async () => {
      mockDependencies.triggerCreatePr.mockResolvedValue(0)
      // Remove traceId to test direct error path (staging fallback requires traceId)
      mockReq.body.traceId = undefined

      await createPr(mockReq, mockRes)

      expect(mockRes.status).toHaveBeenCalledWith(500)
      expect(mockRes.send).toHaveBeenCalledWith("Error creating pull request")
    })
  })

  describe("error handling", () => {
    it("should handle Error instances and track them", async () => {
      const error = new Error("Test error")
      error.stack = "Test stack trace"
      mockDependencies.userNickname.mockRejectedValue(error)

      const consoleErrorSpy = jest.spyOn(console, "error").mockImplementation(() => {})

      await createPr(mockReq, mockRes)

      expect(consoleErrorSpy).toHaveBeenCalledWith(
        expect.stringContaining("Error in /cfapi/create-pr"),
        expect.anything(),
      )
      expect(mockDependencies.posthog.capture).toHaveBeenCalledWith({
        distinctId: "test-user-id",
        event: "cfapi-create-pr-failed-error-creating-standalone-pr",
        properties: {
          error: error.message,
        },
      })
      expect(mockRes.status).toHaveBeenCalledWith(500)
      expect(mockRes.send).toHaveBeenCalledWith(`Error creating pull request: ${error.message}`)

      consoleErrorSpy.mockRestore()
    })

    it("should handle non-Error exceptions", async () => {
      mockDependencies.userNickname.mockRejectedValue("String error")

      const consoleErrorSpy = jest.spyOn(console, "error").mockImplementation(() => {})

      await createPr(mockReq, mockRes)

      expect(consoleErrorSpy).toHaveBeenCalledWith(
        expect.stringContaining("Error in /cfapi/create-pr"),
        expect.anything(),
      )
      expect(mockRes.status).toHaveBeenCalledWith(500)
      expect(mockRes.send).toHaveBeenCalledWith("Error creating pull request")

      consoleErrorSpy.mockRestore()
    })

    it("should handle errors in database queries during approval check", async () => {
      mockDependencies.userNickname.mockResolvedValue("test-user")
      mockDependencies.getInstallationOctokitByOwner.mockResolvedValue({
        rest: { git: { getRef: (jest.fn() as any).mockResolvedValue({ status: 200 }) } },
      })
      mockDependencies.isUserCollaborator.mockResolvedValue(true)
      mockDependencies.requiresApproval.mockReturnValue(true)
      mockDependencies.prisma.optimization_features.findUnique.mockRejectedValue(
        new Error("Database error"),
      )

      const consoleSpy = jest.spyOn(console, "log").mockImplementation(() => {})

      await createPr(mockReq, mockRes)

      expect(mockRes.status).toHaveBeenCalledWith(500)
      expect(mockRes.send).toHaveBeenCalledWith("Error creating pull request: Database error")

      consoleSpy.mockRestore()
    })

    it("should handle errors in requestApproval", async () => {
      mockDependencies.userNickname.mockResolvedValue("test-user")
      mockDependencies.getInstallationOctokitByOwner.mockResolvedValue({
        rest: { git: { getRef: (jest.fn() as any).mockResolvedValue({ status: 200 }) } },
      })
      mockDependencies.isUserCollaborator.mockResolvedValue(true)
      mockDependencies.requiresApproval.mockReturnValue(true)
      mockDependencies.prisma.optimization_features.findUnique.mockResolvedValue({
        approval_status: "pending",
      })
      mockDependencies.requestApproval.mockRejectedValue(new Error("Approval service error"))

      const consoleSpy = jest.spyOn(console, "log").mockImplementation(() => {})

      await createPr(mockReq, mockRes)

      expect(mockRes.status).toHaveBeenCalledWith(500)
      expect(mockRes.send).toHaveBeenCalledWith(
        "Error creating pull request: Approval service error",
      )

      consoleSpy.mockRestore()
    })
  })
})

describe("triggerCreatePr", () => {
  let mockDeps: any
  let mockInstallationOctokit: any
  let consoleSpy: any
  let consoleErrorSpy: any

  beforeEach(() => {
    // Mock console.log to prevent noisy output during tests
    consoleSpy = jest.spyOn(console, "log").mockImplementation(() => {})
    consoleErrorSpy = jest.spyOn(console, "error").mockImplementation(() => {})

    mockInstallationOctokit = { rest: { pulls: {} } }

    const mockPrContentBuilder: PrContentBuilder = {
      buildResultHeader: jest.fn(() => "## Header"),
      buildBenchmarkInfo: jest.fn(() => ""),
      buildResultDetails: jest.fn(() => "Details"),
      buildResultTestReport: jest.fn(() => "Test report"),
      buildResultFooter: jest.fn(() => "Footer"),
      buildPrTitle: jest.fn(() => "Test PR Title"),
    }

    mockDeps = {
      prisma: {
        optimization_events: {
          findUnique: jest.fn(),
          update: jest.fn(),
        },
        optimization_features: {
          findUnique: jest.fn(),
          update: jest.fn(),
        },
      } as any,
      fileDiffsToMap: jest.fn().mockReturnValue(new Map()),
      buildPrTitle: jest.fn().mockReturnValue("Test PR Title"),
      createNewBranchFromDiffContents: jest.fn(),
      createStandalonePullRequest: jest.fn(),
      addLabelToPullRequest: jest.fn(),
      assignReviewer: jest.fn(),
      posthog: {
        capture: jest.fn(),
      },
      createStandalonePRTitleAndBody: jest.fn().mockReturnValue({
        title: "Test PR Title",
        body: "Test PR Body",
      }),
      prContentBuilder: mockPrContentBuilder,
    }

    setTriggerCreatePrDependencies(mockDeps)
  })

  afterEach(() => {
    if (resetTriggerCreatePrDependencies) {
      resetTriggerCreatePrDependencies()
    }
    jest.clearAllMocks()
    if (consoleSpy) {
      consoleSpy.mockRestore()
    }
  })

  describe("successful PR creation", () => {
    it("should successfully create a PR with traceId", async () => {
      const mockPrCommentFields = {
        function_name: "testFunc",
        speedup_pct: 50,
        speedup_x: 2,
        optimization_explanation: "Test optimization",
      }

      mockDeps.createNewBranchFromDiffContents.mockResolvedValue(true)
      mockDeps.createStandalonePullRequest.mockResolvedValue({
        data: {
          id: 123,
          number: 456,
          html_url: "https://github.com/test/test/pull/456",
          head: { ref: "test-branch" },
        },
      })

      const result = await triggerCreatePr(
        "test-owner",
        "test-repo",
        "main",
        [],
        mockPrCommentFields,
        "existing tests",
        "generated tests",
        "coverage message",
        "user123",
        "testuser",
        mockInstallationOctokit,
        "replay tests",
        "concolic tests",
        "trace123",
        "medium",
      )

      expect(result).toBe(456)
      expect(mockDeps.fileDiffsToMap).toHaveBeenCalledWith([])
      // buildPrTitle is now called through createStandalonePRTitleAndBody, not directly
      expect(mockDeps.createNewBranchFromDiffContents).toHaveBeenCalledWith(
        mockInstallationOctokit,
        "test-owner",
        "test-repo",
        expect.stringContaining("codeflash/optimize-testFunc-"),
        "main",
        expect.any(Map),
        "Optimize testFunc\n\nTest optimization",
      )
      expect(mockDeps.createStandalonePRTitleAndBody).toHaveBeenCalledWith(
        mockPrCommentFields,
        "existing tests",
        "generated tests",
        "coverage message",
        expect.stringContaining("codeflash/optimize-testFunc-"),
        mockDeps.prContentBuilder,
        "replay tests",
        "concolic tests",
        "medium",
        "trace123",
        false, // hasLineProfilerData
      )
      expect(mockDeps.createStandalonePullRequest).toHaveBeenCalledWith(
        mockInstallationOctokit,
        "test-owner",
        "test-repo",
        "Test PR Title",
        "Test PR Body",
        expect.stringContaining("codeflash/optimize-testFunc-"),
        "main",
      )
      expect(mockDeps.addLabelToPullRequest).toHaveBeenCalledWith(
        mockInstallationOctokit,
        "test-owner",
        "test-repo",
        456,
      )
      expect(mockDeps.assignReviewer).toHaveBeenCalledWith(
        mockInstallationOctokit,
        "test-owner",
        "test-repo",
        456,
        "testuser",
      )
      expect(consoleSpy).toHaveBeenCalledWith(
        expect.stringContaining("Created new PR #456 with branch test-branch"),
      )
      expect(mockDeps.posthog.capture).toHaveBeenCalledWith({
        distinctId: "user123",
        event: "cfapi-create-pr-success-standalone-pr-created",
        properties: {
          owner: "test-owner",
          repo: "test-repo",
          newPrNumber: 456,
          newPrBranch: "test-branch",
          PRURL: "https://github.com/test/test/pull/456",
        },
      })
    })

    it("should successfully create a PR without traceId", async () => {
      const mockPrCommentFields = {
        function_name: "testFunc",
        speedup_pct: 50,
        speedup_x: 2,
        optimization_explanation: "Test optimization",
      }

      mockDeps.createNewBranchFromDiffContents.mockResolvedValue(true)
      mockDeps.createStandalonePullRequest.mockResolvedValue({
        data: {
          id: 123,
          number: 456,
          html_url: "https://github.com/test/test/pull/456",
          head: { ref: "test-branch" },
        },
      })
      // Mock findUnique to return null for empty traceId
      mockDeps.prisma.optimization_events.findUnique.mockResolvedValue(null)

      const result = await triggerCreatePr(
        "test-owner",
        "test-repo",
        "main",
        [],
        mockPrCommentFields,
        "",
        "",
        "",
        "user123",
        "testuser",
        mockInstallationOctokit,
        "replay tests",
        "concolic tests",
        "", // empty traceId
        "medium",
      )

      expect(result).toBe(456)
      // Expectations for logger calls
      expect(consoleSpy).toHaveBeenCalledWith(
        expect.stringContaining("Starting PR creation for test-owner/test-repo"),
      )
      expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Creating branch:"))
      expect(consoleSpy).toHaveBeenCalledWith(
        expect.stringContaining("Branch created successfully:"),
      )
      expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Creating PR with title:"))
      expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("PR created successfully:"))

      expect(mockDeps.prisma.optimization_events.update).toHaveBeenCalledWith({
        where: { trace_id: "" },
        data: expect.objectContaining({
          pr_id: "123",
          is_optimization_found: true,
          event_type: "pr_created",
          pr_url: "https://github.com/test-owner/test-repo/pull/456",
          function_name: "testFunc",
          speedup_x: 2,
          speedup_pct: 50,
        }),
      })
      // Should not call optimization_features operations when traceId is empty
      expect(mockDeps.prisma.optimization_features.findUnique).not.toHaveBeenCalled()
      expect(mockDeps.prisma.optimization_features.update).not.toHaveBeenCalled()
    })
  })

  describe("branch creation failure", () => {
    it("should return -1 when branch creation fails", async () => {
      mockDeps.createNewBranchFromDiffContents.mockResolvedValue(false)

      const consoleErrorSpy = jest.spyOn(console, "error").mockImplementation(() => {})

      const result = await triggerCreatePr(
        "test-owner",
        "test-repo",
        "main",
        [],
        { function_name: "testFunc" },
        "",
        "",
        "",
        "user123",
        "testuser",
        mockInstallationOctokit,
        "",
        "",
      )

      expect(result).toBe(-1)
      expect(consoleErrorSpy).toHaveBeenCalledWith(
        expect.stringContaining("Error creating PR for"),
        expect.anything(),
      )

      consoleErrorSpy.mockRestore()
    })
  })

  describe("optimization events handling", () => {
    beforeEach(() => {
      mockDeps.createNewBranchFromDiffContents.mockResolvedValue(true)
      mockDeps.createStandalonePullRequest.mockResolvedValue({
        data: {
          id: 123,
          number: 456,
          html_url: "https://github.com/test/test/pull/456",
          head: { ref: "test-branch" },
        },
      })
    })

    it("should handle optimization_events update failure gracefully", async () => {
      const mockPrCommentFields = {
        function_name: "testFunc",
        speedup_pct: 50,
        speedup_x: 2,
        optimization_explanation: "Test optimization",
      }

      mockDeps.prisma.optimization_events.update.mockRejectedValue(new Error("DB error"))

      const consoleErrorSpy = jest.spyOn(console, "error").mockImplementation(() => {})

      const result = await triggerCreatePr(
        "test-owner",
        "test-repo",
        "main",
        [],
        mockPrCommentFields,
        "",
        "",
        "",
        "user123",
        "testuser",
        mockInstallationOctokit,
        "replay tests",
        "concolic tests",
        "trace 123",
        "medium",
      )

      expect(result).toBe(456)
      expect(consoleErrorSpy).toHaveBeenCalledWith(
        expect.stringContaining("Failed to update optimization event"),
        expect.anything(),
      )

      consoleErrorSpy.mockRestore()
    })
  })

  describe("optimization features handling", () => {
    beforeEach(() => {
      mockDeps.createNewBranchFromDiffContents.mockResolvedValue(true)
      mockDeps.createStandalonePullRequest.mockResolvedValue({
        data: {
          id: 123,
          number: 456,
          html_url: "https://github.com/test/test/pull/456",
          head: { ref: "test-branch" },
        },
      })
    })

    it("should update optimization_features when traceId exists and record found", async () => {
      const mockPrCommentFields = {
        function_name: "testFunc",
        speedup_pct: 50,
        speedup_x: 2,
        optimization_explanation: "Test optimization",
      }

      mockDeps.prisma.optimization_features.findUnique.mockResolvedValue({
        pull_request: { existing: "data" },
      })

      const result = await triggerCreatePr(
        "test-owner",
        "test-repo",
        "main",
        [],
        mockPrCommentFields,
        "",
        "",
        "",
        "user123",
        "testuser",
        mockInstallationOctokit,
        "replay tests",
        "concolic tests",
        "trace123",
        "medium",
      )

      expect(result).toBe(456)
      expect(mockDeps.prisma.optimization_features.findUnique).toHaveBeenCalledWith({
        where: { trace_id: "trace123" },
        select: { pull_request: true },
      })
      expect(mockDeps.prisma.optimization_features.update).toHaveBeenCalledWith({
        where: { trace_id: "trace123" },
        data: {
          pull_request: {
            existing: "data",
            new_pr_url: "https://github.com/test/test/pull/456",
          },
        },
      })
    })

    it("should handle null pull_request in optimization_features", async () => {
      const mockPrCommentFields = {
        function_name: "testFunc",
        speedup_pct: 50,
        speedup_x: 2,
        optimization_explanation: "Test optimization",
      }

      mockDeps.prisma.optimization_features.findUnique.mockResolvedValue({
        pull_request: null,
      })

      const result = await triggerCreatePr(
        "test-owner",
        "test-repo",
        "main",
        [],
        mockPrCommentFields,
        "",
        "",
        "",
        "user123",
        "testuser",
        mockInstallationOctokit,
        "replay tests",
        "concolic tests",
        "trace123",
        "medium",
      )

      expect(result).toBe(456)
      expect(mockDeps.prisma.optimization_features.update).toHaveBeenCalledWith({
        where: { trace_id: "trace123" },
        data: {
          pull_request: {
            new_pr_url: "https://github.com/test/test/pull/456",
          },
        },
      })
    })

    it("should handle undefined pull_request in optimization_features", async () => {
      const mockPrCommentFields = {
        function_name: "testFunc",
        speedup_pct: 50,
        speedup_x: 2,
        optimization_explanation: "Test optimization",
      }

      mockDeps.prisma.optimization_features.findUnique.mockResolvedValue({
        pull_request: undefined,
      })

      const result = await triggerCreatePr(
        "test-owner",
        "test-repo",
        "main",
        [],
        mockPrCommentFields,
        "",
        "",
        "",
        "user123",
        "testuser",
        mockInstallationOctokit,
        "replay tests",
        "concolic tests",
        "trace123",
        "medium",
      )

      expect(result).toBe(456)
      expect(mockDeps.prisma.optimization_features.update).toHaveBeenCalledWith({
        where: { trace_id: "trace123" },
        data: {
          pull_request: {
            new_pr_url: "https://github.com/test/test/pull/456",
          },
        },
      })
    })

    it("should handle when optimization_features record is not found", async () => {
      const mockPrCommentFields = {
        function_name: "testFunc",
        speedup_pct: 50,
        speedup_x: 2,
        optimization_explanation: "Test optimization",
      }

      mockDeps.prisma.optimization_features.findUnique.mockResolvedValue(null)

      const result = await triggerCreatePr(
        "test-owner",
        "test-repo",
        "main",
        [],
        mockPrCommentFields,
        "",
        "",
        "",
        "user123",
        "testuser",
        mockInstallationOctokit,
        "replay tests",
        "concolic tests",
        "trace123",
        "medium",
      )

      expect(result).toBe(456)
      expect(mockDeps.prisma.optimization_features.findUnique).toHaveBeenCalled()
      expect(mockDeps.prisma.optimization_features.update).not.toHaveBeenCalled()
    })
  })

  describe("staging branch usage", () => {
    beforeEach(() => {
      mockDeps.createStandalonePullRequest.mockResolvedValue({
        data: {
          id: 123,
          number: 456,
          html_url: "https://github.com/test/test/pull/456",
          head: { ref: "staging-branch" },
        },
      })
    })

    it("should use staging branch directly without creating new branch", async () => {
      const mockPrCommentFields = {
        function_name: "testFunc",
        speedup_pct: 50,
        speedup_x: 2,
        optimization_explanation: "Test optimization",
      }

      const result = await triggerCreatePr(
        "test-owner",
        "test-repo",
        "main",
        [],
        mockPrCommentFields,
        "existing tests",
        "generated tests",
        "coverage message",
        "user123",
        "testuser",
        mockInstallationOctokit,
        "replay tests",
        "concolic tests",
        "trace123",
        "medium",
        "codeflash-staging/existing-branch", // stagingBranch provided
        "free",
      )

      expect(result).toBe(456)
      // Should NOT create a new branch when stagingBranch is provided
      expect(mockDeps.createNewBranchFromDiffContents).not.toHaveBeenCalled()
      expect(mockDeps.fileDiffsToMap).not.toHaveBeenCalled()
      // Should use the staging branch for the PR
      expect(mockDeps.createStandalonePullRequest).toHaveBeenCalledWith(
        mockInstallationOctokit,
        "test-owner",
        "test-repo",
        "Test PR Title",
        "Test PR Body",
        "codeflash-staging/existing-branch",
        "main",
      )
    })

    it("should create new branch when stagingBranch is not provided", async () => {
      const mockPrCommentFields = {
        function_name: "testFunc",
        speedup_pct: 50,
        speedup_x: 2,
        optimization_explanation: "Test optimization",
      }

      mockDeps.createNewBranchFromDiffContents.mockResolvedValue(true)

      const result = await triggerCreatePr(
        "test-owner",
        "test-repo",
        "main",
        [],
        mockPrCommentFields,
        "existing tests",
        "generated tests",
        "coverage message",
        "user123",
        "testuser",
        mockInstallationOctokit,
        "replay tests",
        "concolic tests",
        "trace123",
        "medium",
        "", // No stagingBranch
        "free",
      )

      expect(result).toBe(456)
      // Should create a new branch
      expect(mockDeps.createNewBranchFromDiffContents).toHaveBeenCalled()
      expect(mockDeps.fileDiffsToMap).toHaveBeenCalled()
    })
  })

  describe("paid user storage conversion", () => {
    beforeEach(() => {
      mockDeps.createNewBranchFromDiffContents.mockResolvedValue(true)
      mockDeps.createStandalonePullRequest.mockResolvedValue({
        data: {
          id: 123,
          number: 456,
          html_url: "https://github.com/test/test/pull/456",
          head: { ref: "test-branch" },
        },
      })
      // Note: The code uses findUnique, not findFirst
    })

    it("should convert storage to git_branch for paid user with plain_text staging", async () => {
      const mockPrCommentFields = {
        function_name: "testFunc",
        speedup_pct: 50,
        speedup_x: 2,
        optimization_explanation: "Test optimization",
      }

      // Mock finding existing event with plain_text storage and diffContents in metadata
      mockDeps.prisma.optimization_events.findUnique.mockResolvedValue({
        staging_storage_type: "plain_text",
        function_name: null,
        speedup_x: null,
        speedup_pct: null,
        file_path: null,
        metadata: {
          diffContents: { "file.ts": { oldContent: "old", newContent: "new" } },
          someOtherData: "preserved",
        },
      })

      const result = await triggerCreatePr(
        "test-owner",
        "test-repo",
        "main",
        [],
        mockPrCommentFields,
        "existing tests",
        "generated tests",
        "coverage message",
        "user123",
        "testuser",
        mockInstallationOctokit,
        "replay tests",
        "concolic tests",
        "trace123",
        "medium",
        "",
        "pro", // Paid user
      )

      expect(result).toBe(456)
      expect(mockDeps.prisma.optimization_events.findUnique).toHaveBeenCalledWith({
        where: { trace_id: "trace123" },
        select: {
          function_name: true,
          speedup_x: true,
          file_path: true,
          speedup_pct: true,
          staging_storage_type: true,
          metadata: true,
        },
      })
      expect(mockDeps.prisma.optimization_events.update).toHaveBeenCalledWith({
        where: { trace_id: "trace123" },
        data: expect.objectContaining({
          staging_storage_type: "git_branch",
          is_staging: true,
          metadata: expect.objectContaining({
            someOtherData: "preserved",
            staging_branch_name: expect.stringContaining("codeflash/optimize-testFunc-"),
            storageType: "git_branch",
          }),
        }),
      })
      // diffContents should be removed from metadata
      const updateCall = mockDeps.prisma.optimization_events.update.mock.calls[0][0]
      expect(updateCall.data.metadata.diffContents).toBeUndefined()
    })

    it("should convert storage for enterprise user", async () => {
      const mockPrCommentFields = {
        function_name: "testFunc",
        speedup_pct: 50,
        speedup_x: 2,
        optimization_explanation: "Test optimization",
      }

      mockDeps.prisma.optimization_events.findUnique.mockResolvedValue({
        staging_storage_type: "plain_text",
        function_name: null,
        speedup_x: null,
        speedup_pct: null,
        file_path: null,
        metadata: {},
      })

      await triggerCreatePr(
        "test-owner",
        "test-repo",
        "main",
        [],
        mockPrCommentFields,
        "",
        "",
        "",
        "user123",
        "testuser",
        mockInstallationOctokit,
        "",
        "",
        "trace123",
        "",
        "",
        "enterprise", // Enterprise user
      )

      expect(mockDeps.prisma.optimization_events.update).toHaveBeenCalledWith({
        where: { trace_id: "trace123" },
        data: expect.objectContaining({
          staging_storage_type: "git_branch",
        }),
      })
    })

    it("should NOT convert storage for free user", async () => {
      const mockPrCommentFields = {
        function_name: "testFunc",
        speedup_pct: 50,
        speedup_x: 2,
        optimization_explanation: "Test optimization",
      }

      // Mock existing event (but as free user, storage won't be converted)
      mockDeps.prisma.optimization_events.findUnique.mockResolvedValue({
        staging_storage_type: "plain_text",
        function_name: "testFunc",
        speedup_x: 2,
        speedup_pct: 50,
        file_path: null,
        metadata: {},
      })

      const result = await triggerCreatePr(
        "test-owner",
        "test-repo",
        "main",
        [],
        mockPrCommentFields,
        "",
        "",
        "",
        "user123",
        "testuser",
        mockInstallationOctokit,
        "",
        "",
        "trace123",
        "",
        "",
        "free", // Free user
      )

      expect(result).toBe(456)
      // findUnique is still called to check existing data
      expect(mockDeps.prisma.optimization_events.findUnique).toHaveBeenCalled()
      // Update should not include storage conversion fields (staging_storage_type, is_staging, metadata)
      expect(mockDeps.prisma.optimization_events.update).toHaveBeenCalledWith({
        where: { trace_id: "trace123" },
        data: {
          pr_id: "123",
          pr_url: "https://github.com/test-owner/test-repo/pull/456",
          is_optimization_found: true,
          event_type: "pr_created",
        },
      })
    })

    it("should handle when no existing event is found for paid user", async () => {
      const mockPrCommentFields = {
        function_name: "testFunc",
        speedup_pct: 50,
        speedup_x: 2,
        optimization_explanation: "Test optimization",
      }

      mockDeps.prisma.optimization_events.findUnique.mockResolvedValue(null)

      const result = await triggerCreatePr(
        "test-owner",
        "test-repo",
        "main",
        [],
        mockPrCommentFields,
        "",
        "",
        "",
        "user123",
        "testuser",
        mockInstallationOctokit,
        "",
        "",
        "trace123",
        "",
        "",
        "pro",
      )

      expect(result).toBe(456)
      // Should still update but without storage conversion (since no existing event found)
      // However, function_name, speedup_x, speedup_pct will be added since existing is null
      expect(mockDeps.prisma.optimization_events.update).toHaveBeenCalledWith({
        where: { trace_id: "trace123" },
        data: {
          pr_id: "123",
          pr_url: "https://github.com/test-owner/test-repo/pull/456",
          is_optimization_found: true,
          event_type: "pr_created",
          function_name: "testFunc",
          speedup_x: 2,
          speedup_pct: 50,
        },
      })
    })

    it("should update staging_branch_name when using existing staging branch for paid user", async () => {
      const mockPrCommentFields = {
        function_name: "testFunc",
        speedup_pct: 50,
        speedup_x: 2,
        optimization_explanation: "Test optimization",
      }

      mockDeps.prisma.optimization_events.findUnique.mockResolvedValue({
        staging_storage_type: "git_branch",
        function_name: null,
        speedup_x: null,
        speedup_pct: null,
        file_path: null,
        metadata: {
          staging_branch_name: "old-branch",
        },
      })

      await triggerCreatePr(
        "test-owner",
        "test-repo",
        "main",
        [],
        mockPrCommentFields,
        "",
        "",
        "",
        "user123",
        "testuser",
        mockInstallationOctokit,
        "",
        "",
        "trace123",
        "",
        "codeflash-staging/existing-branch", // Using staging branch
        "pro",
      )

      expect(mockDeps.prisma.optimization_events.update).toHaveBeenCalledWith({
        where: { trace_id: "trace123" },
        data: expect.objectContaining({
          metadata: expect.objectContaining({
            staging_branch_name: "codeflash-staging/existing-branch",
          }),
        }),
      })
    })
  })

  describe("error scenarios", () => {
    it("should handle errors in PR creation process", async () => {
      mockDeps.createNewBranchFromDiffContents.mockResolvedValue(true)
      mockDeps.createStandalonePullRequest.mockRejectedValue(new Error("PR creation failed"))

      const consoleErrorSpy = jest.spyOn(console, "error").mockImplementation(() => {})

      const result = await triggerCreatePr(
        "test-owner",
        "test-repo",
        "main",
        [],
        { function_name: "testFunc" },
        "",
        "",
        "",
        "user123",
        "testuser",
        mockInstallationOctokit,
        "replay tests",
        "concolic tests",
        "",
        "medium",
      )

      expect(result).toBe(-1)
      expect(consoleErrorSpy).toHaveBeenCalledWith(
        expect.stringContaining("Error creating PR for"),
        expect.anything(),
      )

      consoleErrorSpy.mockRestore()
    })

    it("should handle errors in labeling PR", async () => {
      mockDeps.createNewBranchFromDiffContents.mockResolvedValue(true)
      mockDeps.createStandalonePullRequest.mockResolvedValue({
        data: {
          id: 123,
          number: 456,
          html_url: "https://github.com/test/test/pull/456",
          head: { ref: "test-branch" },
        },
      })
      mockDeps.addLabelToPullRequest.mockRejectedValue(new Error("Label failed"))

      const consoleErrorSpy = jest.spyOn(console, "error").mockImplementation(() => {})

      const result = await triggerCreatePr(
        "test-owner",
        "test-repo",
        "main",
        [],
        { function_name: "testFunc" },
        "",
        "",
        "",
        "user123",
        "testuser",
        mockInstallationOctokit,
        "replay tests",
        "concolic tests",
        "",
        "medium",
      )

      expect(result).toBe(-1)
      expect(consoleErrorSpy).toHaveBeenCalledWith(
        expect.stringContaining("Error creating PR for"),
        expect.anything(),
      )

      consoleErrorSpy.mockRestore()
    })

    it("should handle errors in assigning reviewer", async () => {
      mockDeps.createNewBranchFromDiffContents.mockResolvedValue(true)
      mockDeps.createStandalonePullRequest.mockResolvedValue({
        data: {
          id: 123,
          number: 456,
          html_url: "https://github.com/test/test/pull/456",
          head: { ref: "test-branch" },
        },
      })
      mockDeps.addLabelToPullRequest.mockResolvedValue(undefined)
      mockDeps.assignReviewer.mockRejectedValue(new Error("Reviewer assignment failed"))

      const consoleErrorSpy = jest.spyOn(console, "error").mockImplementation(() => {})

      const result = await triggerCreatePr(
        "test-owner",
        "test-repo",
        "main",
        [],
        { function_name: "testFunc" },
        "",
        "",
        "",
        "user123",
        "testuser",
        mockInstallationOctokit,
        "replay tests",
        "concolic tests",
        "",
        "medium",
      )

      expect(result).toBe(-1)
      expect(consoleErrorSpy).toHaveBeenCalledWith(
        expect.stringContaining("Error creating PR for"),
        expect.anything(),
      )

      consoleErrorSpy.mockRestore()
    })
  })
})

describe("createStandalonePRTitleAndBody", () => {
  let mockBuilder: PrContentBuilder

  beforeEach(() => {
    // Use fake timers for consistent metadata timestamps
    jest.useFakeTimers()
    jest.setSystemTime(new Date("2025-01-01T00:00:00.000Z"))

    mockBuilder = {
      buildResultHeader: jest.fn(() => "## Header"),
      buildBenchmarkInfo: jest.fn(() => ""),
      buildResultDetails: jest.fn(() => "Details"),
      buildResultTestReport: jest.fn(() => "Test report"),
      buildResultFooter: jest.fn(() => "Footer"),
      buildPrTitle: jest.fn(() => "Test PR Title"),
    }
  })

  afterEach(() => {
    jest.useRealTimers()
  })

  it("should generate correct title and body without benchmark info", () => {
    const prCommentFields = {
      function_name: "testFunc",
      speedup_pct: 50,
      speedup_x: 2,
      optimization_explanation: "Test optimization",
      // No benchmark_details property
    } as any

    const result = createStandalonePRTitleAndBody(
      prCommentFields,
      "existing tests",
      "generated tests",
      "coverage",
      "branch-name",
      mockBuilder,
      "replay tests",
      "concolic tests",
      "medium",
      "f47ac10b-58cc-4372-a567-0e02b2c3d478",
    )

    expect(result.title).toBe("Test PR Title")
    expect(result.body).toBe(
      '<!-- CODEFLASH_OPTIMIZATION: {"trace_id":"f47ac10b-58cc-4372-a567-0e02b2c3d478","function":"testFunc","speedup_pct":50,"speedup_x":2,"optimization_type":"general","timestamp":"2025-01-01T00:00:00.000Z","version":"1.0"} -->\n## Header\nDetails\nTest report\nFooter ![Static Badge](https://img.shields.io/badge/🎯_Optimization_Quality-medium-blue)\n\n',
    )
    expect(mockBuilder.buildPrTitle).toHaveBeenCalledWith("testFunc", 50, 2)
    expect(mockBuilder.buildResultHeader).toHaveBeenCalledWith(prCommentFields)
    expect(mockBuilder.buildResultDetails).toHaveBeenCalledWith(prCommentFields)
    expect(mockBuilder.buildResultTestReport).toHaveBeenCalledWith(
      prCommentFields,
      "existing tests",
      "generated tests",
      "coverage",
      "replay tests",
      "concolic tests",
    )
    expect(mockBuilder.buildResultFooter).toHaveBeenCalledWith("branch-name")
    // buildBenchmarkInfo should NOT be called when benchmark_details is undefined
    expect(mockBuilder.buildBenchmarkInfo).not.toHaveBeenCalled()
  })

  it("should generate correct title and body with benchmark info", () => {
    mockBuilder.buildBenchmarkInfo = jest.fn(() => "Benchmark data")

    const prCommentFields = {
      function_name: "testFunc",
      speedup_pct: 50,
      speedup_x: 2,
      optimization_explanation: "Test optimization",
      benchmark_details: [
        {
          benchmark_name: "test",
          test_function: "func",
          original_timing: 100,
          expected_new_timing: 50,
          speedup_percent: 50,
        },
      ],
    } as any

    const result = createStandalonePRTitleAndBody(
      prCommentFields,
      "existing tests",
      "generated tests",
      "coverage",
      "branch-name",
      mockBuilder,
      "replay tests",
      "concolic tests",
      "medium",
      "f47ac10b-58cc-4372-a567-0e02b2c3d478",
    )

    expect(result.title).toBe("Test PR Title")
    expect(result.body).toBe(
      '<!-- CODEFLASH_OPTIMIZATION: {"trace_id":"f47ac10b-58cc-4372-a567-0e02b2c3d478","function":"testFunc","speedup_pct":50,"speedup_x":2,"optimization_type":"general","timestamp":"2025-01-01T00:00:00.000Z","version":"1.0"} -->\n## Header\nBenchmark data\nDetails\nTest report\nFooter ![Static Badge](https://img.shields.io/badge/🎯_Optimization_Quality-medium-blue)\n\n',
    )
    expect(mockBuilder.buildBenchmarkInfo).toHaveBeenCalledWith(prCommentFields)
  })

  it("should handle empty benchmark details array", () => {
    const prCommentFields = {
      function_name: "testFunc",
      speedup_pct: 50,
      speedup_x: 2,
      optimization_explanation: "Test optimization",
      benchmark_details: [],
    } as any

    const result = createStandalonePRTitleAndBody(
      prCommentFields,
      "existing tests",
      "generated tests",
      "coverage",
      "branch-name",
      mockBuilder,
      "replay tests",
      "concolic tests",
      "medium",
      "f47ac10b-58cc-4372-a567-0e02b2c3d478",
    )

    expect(result.body).toBe(
      '<!-- CODEFLASH_OPTIMIZATION: {"trace_id":"f47ac10b-58cc-4372-a567-0e02b2c3d478","function":"testFunc","speedup_pct":50,"speedup_x":2,"optimization_type":"general","timestamp":"2025-01-01T00:00:00.000Z","version":"1.0"} -->\n## Header\nDetails\nTest report\nFooter ![Static Badge](https://img.shields.io/badge/🎯_Optimization_Quality-medium-blue)\n\n',
    )
    // buildBenchmarkInfo should NOT be called when benchmark_details is empty array
    expect(mockBuilder.buildBenchmarkInfo).not.toHaveBeenCalled()
  })

  it("should handle null benchmark_details", () => {
    const prCommentFields = {
      function_name: "testFunc",
      speedup_pct: 50,
      speedup_x: 2,
      optimization_explanation: "Test optimization",
      benchmark_details: null,
    } as any

    const result = createStandalonePRTitleAndBody(
      prCommentFields,
      "existing tests",
      "generated tests",
      "coverage",
      "branch-name",
      mockBuilder,
      "replay tests",
      "concolic tests",
      "medium",
      "f47ac10b-58cc-4372-a567-0e02b2c3d478",
    )

    expect(result.body).toBe(
      '<!-- CODEFLASH_OPTIMIZATION: {"trace_id":"f47ac10b-58cc-4372-a567-0e02b2c3d478","function":"testFunc","speedup_pct":50,"speedup_x":2,"optimization_type":"general","timestamp":"2025-01-01T00:00:00.000Z","version":"1.0"} -->\n## Header\nDetails\nTest report\nFooter ![Static Badge](https://img.shields.io/badge/🎯_Optimization_Quality-medium-blue)\n\n',
    )
    // buildBenchmarkInfo should NOT be called when benchmark_details is null
    expect(mockBuilder.buildBenchmarkInfo).not.toHaveBeenCalled()
  })
})
