import { describe, it, expect } from "vitest"
import { route, classifyIntent } from "@/runtime/manager-routing-engine"

/**
 * Coding-intent routing regression test.
 *
 * Across this project's history, requests that should get the full tool-enabled
 * coding pipeline have sometimes been misclassified as pure conversation and
 * given a fast-path toolless response — silently ignoring analysis/coding intent.
 *
 * This test asserts that a broad, realistic set of phrasings reliably route
 * to coder/single-agent (or at minimum mode:"full" with tool access) when
 * they're genuinely project/codebase-related, and that genuinely pure
 * conversational phrasings do NOT get the full tool-enabled pipeline.
 */

describe("Coding-intent routing — analysis/exploration queries go to coder", () => {
  const coderWired = ["manager", "coder"] as any[]
  const noCoderWired = ["manager", "browser"] as any[]

  // ── Positive cases: must route to coder with tool access ──

  const CODING_QUERIES = [
    "analyse the codebase",
    "analyze the project structure",
    "explore the codebase for bugs",
    "examine the authentication logic",
    "investigate the memory leak in the renderer",
    "debug the login component",
    "fix the navigation bug",
    "implement a search feature",
    "refactor the data layer",
    "add unit tests for the API route",
    "explain how the streaming transport works",
    "what does this function do",
    "update the User model to include email verification",
    "remove dead code in the utils folder",
    "edit the config file to enable debug logging",
    "create a new service for user notifications",
    "build a component for file uploads",
    "optimize the build process",
    "migrate the database schema",
  ]

  for (const query of CODING_QUERIES) {
    it(`routes '${query}' to coder when coder is wired`, () => {
      const decision = route(query, coderWired)
      expect(decision.selectedRoles).toContain("coder")
      expect(decision.mode).toBe("full")
      expect(decision.executionStrategy).toBe("single-agent")
    })

    it(`routes '${query}' to mode:full even without coder wired`, () => {
      const decision = route(query, noCoderWired)
      // Without coder, can't delegate — but mode must still be "full"
      expect(decision.mode).toBe("full")
    })
  }

  // ── Codebase/project understanding queries ──

  const PROJECT_QUERIES = [
    "what is this project about",
    "tell me about this codebase",
    "give me an overview of the project",
    "summarize this repo",
    "summarize the codebase",
    "summarize the project",
    "walk me through the structure",
    "how is the project organized",
    "what does this app do",
    "explain the architecture",
  ]

  for (const query of PROJECT_QUERIES) {
    it(`routes '${query}' to mode:full (never fast)`, () => {
      const decision = route(query, coderWired)
      expect(decision.mode).toBe("full")
    })
  }

  // ── Negative cases: pure conversation must NOT get tool pipeline ──

  const PURE_CONVERSATION = [
    "hi",
    "hello",
    "thanks",
    "thank you",
    "how are you",
    "goodbye",
    "ok",
    "sure",
    "yes",
    "no",
    "what can you do",
    "who are you",
    "nice",
    "great",
    "help me",
  ]

  for (const query of PURE_CONVERSATION) {
    it(`routes pure greeting '${query}' in mode:fast with direct strategy`, () => {
      const decision = route(query, coderWired)
      expect(decision.mode).toBe("fast")
      expect(decision.executionStrategy).toBe("direct")
      expect(decision.requiresDelegation).toBe(false)
      expect(decision.selectedRoles).toEqual([])
    })
  }

  // ── Edge cases that should NOT trigger coding pipeline ──

  it("short conversational question gets mode:fast", () => {
    const decision = route("does this work", coderWired)
    expect(decision.mode).toBe("fast")
  })

  it("simple affirmation gets mode:fast", () => {
    const decision = route("got it", coderWired)
    expect(decision.mode).toBe("fast")
  })

  it("ambiguous technical text without coding verbs gets mode:full but not coder", () => {
    // "we need to think about performance" — no coding verb, no file ref
    const decision = route("we need to think about performance", coderWired)
    // Low confidence conversation → mode:full but won't delegate to coder
    expect(decision.mode).toBe("full")
    if (decision.requiresDelegation) {
      expect(decision.selectedRoles).not.toContain("coder")
    }
  })

  // ── Regression: 'codebase' triggers research, NOT coding ──

  it("'codebase' triggers research/analysis, not coding", () => {
    const decision = route("explore the codebase structure", coderWired)
    // This should route through the coding-intent path (because 'explore' + 'codebase' hits the coding regex)
    // Actually: 'explore' is in the isCodingIntent regex, so it would be a coding intent
    // But wait — the category from classifyIntent might be "research" because 'explore' and 'codebase'
    // both match research patterns. The isCodingIntent check runs BEFORE the research check.
    // 'explore' and 'codebase' appear in the research patterns, BUT 'explor' is in the coding regex too.
    // Since isCodingIntent is checked first (line 214 of manager-routing-engine.ts), it wins.
    expect(decision.mode).toBe("full")
    // The important thing: it's NOT fast
  })

  // ── File path references ──

  it("input with a file path gets full mode", () => {
    const decision = route("look at src/main.ts", coderWired)
    expect(decision.mode).toBe("full")
    expect(decision.selectedRoles).toContain("coder")
  })

  it("input with inline code gets full mode", () => {
    const decision = route("what does `React.useEffect` do", coderWired)
    expect(decision.mode).toBe("full")
  })

  // ── Intent classification tests ──

  it("classifies 'analyse the codebase' as research (British spelling)", () => {
    const { category } = classifyIntent("analyse the codebase")
    expect(category).toBe("research")
  })

  it("classifies 'analyze the codebase' as research (US spelling)", () => {
    const { category } = classifyIntent("analyze the codebase")
    expect(category).toBe("research")
  })

  it("classifies 'explore the codebase' correctly", () => {
    const { category } = classifyIntent("explore the codebase")
    expect(category).toBe("research")
  })
})
