import { describe, expect, test } from "bun:test";
import { findMatch } from "./requests-dedup";
import type { RequestRow } from "./requests-store";

function row(overrides: Partial<RequestRow> = {}): RequestRow {
  return {
    id: "req-a", title: "Build the requests board filter", project: "overdeck", state: "shipped",
    priority: "NORMAL", origin: "owner", asked_at: "2026-08-09T00:00:00.000Z", updated_at: "2026-08-09T00:00:00.000Z",
    worker: null, detail: null, proof_url: "https://proof.example/a", plan_ref: null, session_name: null, session_id: null, announced_at: null,
    original_body: null, original_body_format: null, intake_source: null, intake_source_event_id: null, ...overrides,
  };
}

describe("findMatch", () => {
  test("exact normalized title match is confident", () => {
    const match = findMatch([row()], { title: "build the requests board filter", project: "overdeck" });
    expect(match?.confidence).toBe("confident");
    expect(match?.row.id).toBe("req-a");
  });

  test("shared plan_ref is confident regardless of title wording", () => {
    const existing = row({ plan_ref: "docs/plans/2026-08-09-diff-viewer.md" });
    const match = findMatch([existing], { title: "add the diff viewer to the drawer", project: "overdeck", plan_ref: "docs/plans/2026-08-09-diff-viewer.md" });
    expect(match?.confidence).toBe("confident");
  });

  test("high token overlap is confident", () => {
    const existing = row({ title: "Fix the login bug in auth middleware" });
    const match = findMatch([existing], { title: "fix login bug auth middleware", project: "overdeck" });
    expect(match?.confidence).toBe("confident");
  });

  test("moderate overlap is weak, not confident", () => {
    const existing = row({ title: "Fix the login bug in auth middleware" });
    const match = findMatch([existing], { title: "fix login bug middleware flow", project: "overdeck" });
    expect(match?.confidence).toBe("weak");
  });

  test("unrelated titles produce no match", () => {
    const existing = row({ title: "Fix the login bug in auth middleware" });
    const match = findMatch([existing], { title: "deploy the new pricing page", project: "overdeck" });
    expect(match).toBeNull();
  });

  test("different project never matches", () => {
    const existing = row({ title: "Fix the login bug in auth middleware", project: "press-zone" });
    const match = findMatch([existing], { title: "Fix the login bug in auth middleware", project: "overdeck" });
    expect(match).toBeNull();
  });

  test("exact work_key (plan_ref) match wins even against a very different title", () => {
    const existing = row({ plan_ref: "wt-task-board-sync", title: "Something else entirely" });
    const match = findMatch([existing], { title: "Totally unrelated wording", project: "overdeck", plan_ref: "wt-task-board-sync" });
    expect(match?.confidence).toBe("confident");
    expect(match?.row.id).toBe("req-a");
  });

  test("a keyed candidate with a DIFFERENT key never falls back to title similarity, even on a near-identical title", () => {
    const existing = row({ plan_ref: "wt-other-slug", title: "Agent started work on: task board sync" });
    const match = findMatch([existing], { title: "Agent started work on: task board sync", project: "overdeck", plan_ref: "wt-task-board-sync" });
    expect(match).toBeNull();
  });

  test("a keyed candidate against a keyless row never falls back to title similarity", () => {
    const existing = row({ plan_ref: null, title: "Agent started work on: task board sync" });
    const match = findMatch([existing], { title: "Agent started work on: task board sync", project: "overdeck", plan_ref: "wt-task-board-sync" });
    expect(match).toBeNull();
  });

  test("keyless candidates still fall back to title similarity unchanged", () => {
    const existing = row({ title: "Fix the login bug in auth middleware" });
    const match = findMatch([existing], { title: "fix login bug auth middleware", project: "overdeck" });
    expect(match?.confidence).toBe("confident");
  });

  test("matches across every lifecycle state, including terminal rows", () => {
    for (const state of ["asked", "in_flight", "blocked_needs_owner", "orphaned", "shipped", "canceled"] as const) {
      const existing = row({ title: "Ship the diff viewer", state });
      const match = findMatch([existing], { title: "ship the diff viewer", project: "overdeck" });
      expect(match?.confidence).toBe("confident");
    }
  });
});
