import { existsSync, readFileSync } from "node:fs";
import { resolve } from "node:path";
import { describe, expect, test, beforeEach } from "bun:test";
import { MEMORY } from "@/core/constants.js";
import {
  isTicketReviewCommentEligibleBySessionStart,
  isTicketReviewTriggerProcessed,
  markTicketReviewTriggerProcessed,
  resetTicketReviewProcessedStoreForTests,
  ticketReviewPersistenceFileExists,
  ticketReviewSessionStartMsForTests,
  ticketReviewTriggerKey,
} from "@/poller/ticket-review-processed.js";

function storeFilePath(): string {
  const override = process.env.TICKET_REVIEW_STORE_PATH?.trim();
  if (override) return resolve(override);
  return resolve(process.cwd(), MEMORY.DIR, "ticket-review-triggers.json");
}

describe("ticket-review-processed", () => {
  beforeEach(() => {
    resetTicketReviewProcessedStoreForTests({ removePersistedFile: true });
  });

  test("ticketReviewTriggerKey joins issue and comment id", () => {
    expect(ticketReviewTriggerKey("SQDP-1", "c99")).toBe("SQDP-1:c99");
  });

  test("mark then is returns true for same key", () => {
    expect(isTicketReviewTriggerProcessed("X", "1")).toBe(false);
    markTicketReviewTriggerProcessed("X", "1");
    expect(isTicketReviewTriggerProcessed("X", "1")).toBe(true);
  });

  test("persists to disk and reloads after simulated restart", () => {
    markTicketReviewTriggerProcessed("SQEG-2316", "comment-abc");
    const path = storeFilePath();

    expect(existsSync(path)).toBe(true);
    expect(ticketReviewPersistenceFileExists()).toBe(true);
    const parsed = JSON.parse(readFileSync(path, "utf-8")) as { keys: string[] };
    expect(parsed.keys).toContain("SQEG-2316:comment-abc");

    resetTicketReviewProcessedStoreForTests();
    expect(isTicketReviewTriggerProcessed("SQEG-2316", "comment-abc")).toBe(true);
  });

  test("persistence file is absent until first mark", () => {
    expect(ticketReviewPersistenceFileExists()).toBe(false);
    markTicketReviewTriggerProcessed("TMP", "1");
    expect(ticketReviewPersistenceFileExists()).toBe(true);
  });

  test("isTicketReviewCommentEligibleBySessionStart compares to process session", () => {
    const start = ticketReviewSessionStartMsForTests();
    expect(
      isTicketReviewCommentEligibleBySessionStart(new Date(start - 60_000).toISOString()),
    ).toBe(false);
    expect(
      isTicketReviewCommentEligibleBySessionStart(new Date(start + 60_000).toISOString()),
    ).toBe(true);
  });

  test("invalid comment created ISO is not eligible by session", () => {
    expect(isTicketReviewCommentEligibleBySessionStart("")).toBe(false);
    expect(isTicketReviewCommentEligibleBySessionStart("not-a-date")).toBe(false);
  });
});
