import { beforeEach, describe, expect, it } from "vitest"
import { mount } from "@vue/test-utils"
import { createPinia, setActivePinia } from "pinia"
import QuizBuilder from "./QuizBuilder.vue"
import {
  __resetQuizBuilderIdCounter,
  useQuizBuilderStore,
  type QuizBuilderSchema,
} from "@/stores/quizBuilderStore"

const BUILDER_ID = "qb-test"

/** Build the store and return the id of the auto-created default bank. */
function defaultBankId(): string {
  const store = useQuizBuilderStore()
  store.ensureBuilder(BUILDER_ID)
  return store.getSchema(BUILDER_ID).questionBanks[0]!.id
}

describe("QuizBuilder", () => {
  beforeEach(() => {
    setActivePinia(createPinia())
    __resetQuizBuilderIdCounter()
  })

  it("renders nav + canvas + inspector", () => {
    const wrapper = mount(QuizBuilder, { props: { builderId: BUILDER_ID } })
    expect(wrapper.find("[data-testid='quiz-builder-nav']").exists()).toBe(
      true,
    )
    expect(wrapper.find("[data-testid='quiz-builder-canvas']").exists()).toBe(
      true,
    )
    expect(
      wrapper.find("[data-testid='quiz-builder-inspector']").exists(),
    ).toBe(true)
  })

  it("schema always starts with at least one default bank", () => {
    mount(QuizBuilder, { props: { builderId: BUILDER_ID } })
    const store = useQuizBuilderStore()
    const schema = store.getSchema(BUILDER_ID)
    expect(schema.questionBanks).toHaveLength(1)
    expect(schema.questionBanks[0]!.name).toBe("Default bank")
  })

  it("shows the empty-state hint when there are no questions", () => {
    const wrapper = mount(QuizBuilder, { props: { builderId: BUILDER_ID } })
    expect(
      wrapper.find("[data-testid='quiz-builder-canvas-empty']").exists(),
    ).toBe(true)
  })

  it("opens the palette when the ? nav button is clicked", async () => {
    const wrapper = mount(QuizBuilder, { props: { builderId: BUILDER_ID } })
    expect(
      wrapper.find("[data-testid='quiz-builder-palette']").exists(),
    ).toBe(false)
    await wrapper
      .find("[data-testid='quiz-builder-nav-palette']")
      .trigger("click")
    expect(
      wrapper.find("[data-testid='quiz-builder-palette']").exists(),
    ).toBe(true)
    for (const type of ["single-choice", "multiple-choice", "essay"]) {
      expect(
        wrapper
          .find(`[data-testid='quiz-builder-palette-${type}']`)
          .exists(),
      ).toBe(true)
    }
  })

  it("clicking a chip appends a question to the active bank and selects it", async () => {
    const wrapper = mount(QuizBuilder, { props: { builderId: BUILDER_ID } })
    await wrapper
      .find("[data-testid='quiz-builder-nav-palette']")
      .trigger("click")
    await wrapper
      .find("[data-testid='quiz-builder-palette-multiple-choice']")
      .trigger("click")

    const store = useQuizBuilderStore()
    const schema = store.getSchema(BUILDER_ID)
    expect(schema.questions).toHaveLength(1)
    expect(schema.questions[0]!.type).toBe("multiple-choice")
    expect(schema.questions[0]!.options).toHaveLength(2)
    expect(schema.questions[0]!.bankId).toBe(schema.questionBanks[0]!.id)
    expect(
      wrapper.find("[data-testid='quiz-builder-inspector-fields']").exists(),
    ).toBe(true)
  })

  it("essay questions have no options", async () => {
    const wrapper = mount(QuizBuilder, { props: { builderId: BUILDER_ID } })
    await wrapper
      .find("[data-testid='quiz-builder-nav-palette']")
      .trigger("click")
    await wrapper
      .find("[data-testid='quiz-builder-palette-essay']")
      .trigger("click")

    const store = useQuizBuilderStore()
    expect(store.getSchema(BUILDER_ID).questions[0]!.options).toHaveLength(0)
  })

  it("editing the prompt patches the schema", async () => {
    const wrapper = mount(QuizBuilder, { props: { builderId: BUILDER_ID } })
    await wrapper
      .find("[data-testid='quiz-builder-nav-palette']")
      .trigger("click")
    await wrapper
      .find("[data-testid='quiz-builder-palette-single-choice']")
      .trigger("click")
    await wrapper
      .find("[data-testid='quiz-builder-inspector-prompt']")
      .setValue("What is 2 + 2?")

    const store = useQuizBuilderStore()
    expect(store.getSchema(BUILDER_ID).questions[0]!.prompt).toBe(
      "What is 2 + 2?",
    )
  })

  it("Add option adds an option to the selected question", async () => {
    const wrapper = mount(QuizBuilder, { props: { builderId: BUILDER_ID } })
    await wrapper
      .find("[data-testid='quiz-builder-nav-palette']")
      .trigger("click")
    await wrapper
      .find("[data-testid='quiz-builder-palette-single-choice']")
      .trigger("click")
    await wrapper
      .find("[data-testid='quiz-builder-inspector-add-option']")
      .trigger("click")

    const store = useQuizBuilderStore()
    expect(store.getSchema(BUILDER_ID).questions[0]!.options).toHaveLength(3)
  })

  it("removes the selected question when Remove question is clicked", async () => {
    const wrapper = mount(QuizBuilder, { props: { builderId: BUILDER_ID } })
    await wrapper
      .find("[data-testid='quiz-builder-nav-palette']")
      .trigger("click")
    await wrapper
      .find("[data-testid='quiz-builder-palette-single-choice']")
      .trigger("click")
    await wrapper.find("[data-testid='quiz-builder-remove']").trigger("click")

    const store = useQuizBuilderStore()
    expect(store.getSchema(BUILDER_ID).questions).toHaveLength(0)
  })

  it("loads an existing schema from modelValue on mount", () => {
    const bankId = "bank-seed"
    const existing: Partial<QuizBuilderSchema> = {
      questionBanks: [{ id: bankId, name: "Seeded" }],
      questions: [
        {
          id: "q1",
          prompt: "Q1?",
          type: "single-choice",
          required: true,
          bankId,
          options: [
            {
              id: "o1",
              label: "A",
              value: "a",
              correct: true,
              score: 2,
            },
          ],
        },
      ],
    }
    mount(QuizBuilder, {
      props: { builderId: BUILDER_ID, modelValue: existing },
    })

    const store = useQuizBuilderStore()
    const schema = store.getSchema(BUILDER_ID)
    expect(schema.questionBanks[0]!.name).toBe("Seeded")
    expect(schema.questions).toHaveLength(1)
    expect(schema.questions[0]!.options[0]!.correct).toBe(true)
  })

  it("legacy schema without banks gets a Default bank and migrates orphan questions", () => {
    const legacy: Partial<QuizBuilderSchema> = {
      questions: [
        {
          id: "q1",
          prompt: "Q1?",
          type: "essay",
          // Intentionally omit bankId — legacy shape.
          options: [],
        } as unknown as QuizBuilderSchema["questions"][number],
      ],
    }
    mount(QuizBuilder, {
      props: { builderId: BUILDER_ID, modelValue: legacy },
    })

    const store = useQuizBuilderStore()
    const schema = store.getSchema(BUILDER_ID)
    expect(schema.questionBanks).toHaveLength(1)
    expect(schema.questions[0]!.bankId).toBe(schema.questionBanks[0]!.id)
  })

  it("emits update:modelValue on schema mutation", async () => {
    const wrapper = mount(QuizBuilder, { props: { builderId: BUILDER_ID } })
    await wrapper
      .find("[data-testid='quiz-builder-nav-palette']")
      .trigger("click")
    await wrapper
      .find("[data-testid='quiz-builder-palette-single-choice']")
      .trigger("click")
    await wrapper.vm.$nextTick()

    const emitted = wrapper.emitted("update:modelValue")
    expect(emitted).toBeTruthy()
    const last = emitted![emitted!.length - 1] as unknown[]
    const schema = last[0] as QuizBuilderSchema
    expect(schema.questions).toHaveLength(1)
    expect(schema.questionBanks).toHaveLength(1)
  })

  describe("hideElementTypes", () => {
    it("hides chips listed in hideElementTypes", async () => {
      const wrapper = mount(QuizBuilder, {
        props: {
          builderId: BUILDER_ID,
          hideElementTypes: ["essay", "multiple-choice"],
        },
      })
      await wrapper
        .find("[data-testid='quiz-builder-nav-palette']")
        .trigger("click")
      expect(
        wrapper
          .find("[data-testid='quiz-builder-palette-single-choice']")
          .exists(),
      ).toBe(true)
      expect(
        wrapper
          .find("[data-testid='quiz-builder-palette-multiple-choice']")
          .exists(),
      ).toBe(false)
      expect(
        wrapper.find("[data-testid='quiz-builder-palette-essay']").exists(),
      ).toBe(false)
    })

    it("clicking a chip after hiding others adds the visible chip's type", async () => {
      const wrapper = mount(QuizBuilder, {
        props: {
          builderId: BUILDER_ID,
          hideElementTypes: ["single-choice"],
        },
      })
      await wrapper
        .find("[data-testid='quiz-builder-nav-palette']")
        .trigger("click")
      await wrapper
        .find("[data-testid='quiz-builder-palette-multiple-choice']")
        .trigger("click")

      const store = useQuizBuilderStore()
      expect(store.getSchema(BUILDER_ID).questions[0]!.type).toBe(
        "multiple-choice",
      )
    })
  })

  describe("customElementList", () => {
    it("renders custom items instead of default chips", async () => {
      const wrapper = mount(QuizBuilder, {
        props: {
          builderId: BUILDER_ID,
          customElementList: [
            { type: "single-choice", label: "Pick one", icon: "circle" },
            { type: "essay", label: "Tell us why", icon: "pencil" },
          ],
        },
      })
      await wrapper
        .find("[data-testid='quiz-builder-nav-palette']")
        .trigger("click")
      expect(
        wrapper.find("[data-testid='quiz-builder-palette-custom']").exists(),
      ).toBe(true)
      expect(
        wrapper
          .find("[data-testid='quiz-builder-palette-single-choice']")
          .exists(),
      ).toBe(false)
      expect(
        wrapper
          .find("[data-testid='quiz-builder-palette-custom-single-choice-0']")
          .exists(),
      ).toBe(true)
    })

    it("clicking a bare custom item adds a question with prompt + config", async () => {
      const wrapper = mount(QuizBuilder, {
        props: {
          builderId: BUILDER_ID,
          customElementList: [
            {
              type: "single-choice",
              label: "Confidence",
              config: { required: true, helpText: "Be honest" },
            },
          ],
        },
      })
      await wrapper
        .find("[data-testid='quiz-builder-nav-palette']")
        .trigger("click")
      await wrapper
        .find("[data-testid='quiz-builder-palette-custom-single-choice-0']")
        .trigger("click")

      const store = useQuizBuilderStore()
      const q = store.getSchema(BUILDER_ID).questions[0]!
      expect(q.prompt).toBe("Confidence")
      expect(q.required).toBe(true)
      expect(q.helpText).toBe("Be honest")
    })

    it("collapses items in a question-group until the header is clicked", async () => {
      const wrapper = mount(QuizBuilder, {
        props: {
          builderId: BUILDER_ID,
          customElementList: [
            {
              type: "question-group",
              label: "Likert",
              questions: [{ type: "single-choice", label: "Agreement" }],
            },
          ],
        },
      })
      await wrapper
        .find("[data-testid='quiz-builder-nav-palette']")
        .trigger("click")
      expect(
        wrapper
          .find("[data-testid='quiz-builder-palette-custom-single-choice-0']")
          .exists(),
      ).toBe(false)
      await wrapper
        .find("[data-testid='quiz-builder-palette-group-0']")
        .trigger("click")
      expect(
        wrapper
          .find("[data-testid='quiz-builder-palette-custom-single-choice-0']")
          .exists(),
      ).toBe(true)
    })
  })

  describe("question banks", () => {
    it("hides cog / bank icons / +bank when enableQuestionBanks is false", () => {
      const wrapper = mount(QuizBuilder, { props: { builderId: BUILDER_ID } })
      expect(
        wrapper.find("[data-testid='quiz-builder-nav-config']").exists(),
      ).toBe(false)
      expect(
        wrapper.find("[data-testid='quiz-builder-bank-add']").exists(),
      ).toBe(false)
      const bankId = defaultBankId()
      expect(
        wrapper
          .find(`[data-testid='quiz-builder-nav-bank-${bankId}']`)
          .exists(),
      ).toBe(false)
    })

    it("shows cog, default bank icon, and +bank when enableQuestionBanks is true", () => {
      const wrapper = mount(QuizBuilder, {
        props: { builderId: BUILDER_ID, enableQuestionBanks: true },
      })
      expect(
        wrapper.find("[data-testid='quiz-builder-nav-config']").exists(),
      ).toBe(true)
      expect(
        wrapper.find("[data-testid='quiz-builder-bank-add']").exists(),
      ).toBe(true)
      const bankId = defaultBankId()
      expect(
        wrapper
          .find(`[data-testid='quiz-builder-nav-bank-${bankId}']`)
          .exists(),
      ).toBe(true)
    })

    it("+bank adds a bank, selects it, and opens the config column", async () => {
      const wrapper = mount(QuizBuilder, {
        props: { builderId: BUILDER_ID, enableQuestionBanks: true },
      })
      await wrapper
        .find("[data-testid='quiz-builder-bank-add']")
        .trigger("click")

      const store = useQuizBuilderStore()
      const schema = store.getSchema(BUILDER_ID)
      expect(schema.questionBanks).toHaveLength(2)
      // Config column visible with the name input for the new bank.
      expect(
        wrapper.find("[data-testid='quiz-builder-config']").exists(),
      ).toBe(true)
      expect(
        wrapper.find("[data-testid='quiz-builder-config-name']").exists(),
      ).toBe(true)
    })

    it("cog button toggles the bank-config column for the active bank", async () => {
      const wrapper = mount(QuizBuilder, {
        props: { builderId: BUILDER_ID, enableQuestionBanks: true },
      })
      expect(
        wrapper.find("[data-testid='quiz-builder-config']").exists(),
      ).toBe(false)
      await wrapper
        .find("[data-testid='quiz-builder-nav-config']")
        .trigger("click")
      expect(
        wrapper.find("[data-testid='quiz-builder-config']").exists(),
      ).toBe(true)
      await wrapper
        .find("[data-testid='quiz-builder-config-close']")
        .trigger("click")
      expect(
        wrapper.find("[data-testid='quiz-builder-config']").exists(),
      ).toBe(false)
    })

    it("editing the bank name patches the schema", async () => {
      const wrapper = mount(QuizBuilder, {
        props: { builderId: BUILDER_ID, enableQuestionBanks: true },
      })
      await wrapper
        .find("[data-testid='quiz-builder-nav-config']")
        .trigger("click")
      await wrapper
        .find("[data-testid='quiz-builder-config-name']")
        .setValue("Round 1")

      const store = useQuizBuilderStore()
      expect(store.getSchema(BUILDER_ID).questionBanks[0]!.name).toBe(
        "Round 1",
      )
    })

    it("clicking a different bank changes the active scope", async () => {
      const wrapper = mount(QuizBuilder, {
        props: { builderId: BUILDER_ID, enableQuestionBanks: true },
      })
      const store = useQuizBuilderStore()
      const first = store.getSchema(BUILDER_ID).questionBanks[0]!.id
      store.addQuestion(BUILDER_ID, "essay", first)
      await wrapper
        .find("[data-testid='quiz-builder-bank-add']")
        .trigger("click")
      const second = store.getSchema(BUILDER_ID).questionBanks[1]!.id

      await wrapper
        .find(`[data-testid='quiz-builder-nav-bank-${first}']`)
        .trigger("click")
      let rows = wrapper
        .find("[data-testid='quiz-builder-canvas-list']")
        .findAll("li[data-testid^='quiz-builder-row-']")
      expect(rows).toHaveLength(1)

      await wrapper
        .find(`[data-testid='quiz-builder-nav-bank-${second}']`)
        .trigger("click")
      rows = wrapper.findAll("li[data-testid^='quiz-builder-row-']")
      expect(rows).toHaveLength(0)
    })

    it("removeBank refuses to delete the last bank", () => {
      const store = useQuizBuilderStore()
      store.ensureBuilder(BUILDER_ID)
      const onlyBank = store.getSchema(BUILDER_ID).questionBanks[0]!.id
      store.removeBank(BUILDER_ID, onlyBank)
      expect(store.getSchema(BUILDER_ID).questionBanks).toHaveLength(1)
    })

    it("removing a bank deletes its questions but keeps others", () => {
      const store = useQuizBuilderStore()
      store.ensureBuilder(BUILDER_ID)
      const a = store.getSchema(BUILDER_ID).questionBanks[0]!.id
      const b = store.addBank(BUILDER_ID, "B")
      store.addQuestion(BUILDER_ID, "single-choice", a)
      store.addQuestion(BUILDER_ID, "essay", b)
      store.removeBank(BUILDER_ID, b)
      const schema = store.getSchema(BUILDER_ID)
      expect(schema.questionBanks).toHaveLength(1)
      expect(schema.questions).toHaveLength(1)
      expect(schema.questions[0]!.bankId).toBe(a)
    })

    it("copyQuestion duplicates with a fresh id and fresh option ids", () => {
      const store = useQuizBuilderStore()
      store.ensureBuilder(BUILDER_ID)
      const a = store.getSchema(BUILDER_ID).questionBanks[0]!.id
      const qId = store.addQuestion(BUILDER_ID, "single-choice", a)
      const newId = store.copyQuestion(BUILDER_ID, qId)
      const schema = store.getSchema(BUILDER_ID)
      expect(schema.questions).toHaveLength(2)
      const original = schema.questions.find((q) => q.id === qId)!
      const copy = schema.questions.find((q) => q.id === newId)!
      expect(copy.bankId).toBe(a)
      expect(original.options.map((o) => o.id)).not.toEqual(
        copy.options.map((o) => o.id),
      )
    })
  })

  describe("dragToAdd", () => {
    it("renders grip handles on default chips when dragToAdd is true", async () => {
      const wrapper = mount(QuizBuilder, {
        props: { builderId: BUILDER_ID, dragToAdd: true },
      })
      await wrapper
        .find("[data-testid='quiz-builder-nav-palette']")
        .trigger("click")
      const chip = wrapper.find(
        "[data-testid='quiz-builder-palette-single-choice']",
      )
      expect(chip.exists()).toBe(true)
      expect(chip.classes()).toContain("cursor-grab")
    })

    it("reorderQuestionInBank moves a question within a bank", () => {
      const store = useQuizBuilderStore()
      store.ensureBuilder(BUILDER_ID)
      const bankId = store.getSchema(BUILDER_ID).questionBanks[0]!.id
      const a = store.addQuestion(BUILDER_ID, "single-choice", bankId)
      const b = store.addQuestion(BUILDER_ID, "essay", bankId)
      const c = store.addQuestion(BUILDER_ID, "multiple-choice", bankId)
      store.reorderQuestionInBank(BUILDER_ID, bankId, c, 0)
      const ids = store
        .getSchema(BUILDER_ID)
        .questions.map((q) => q.id)
      expect(ids).toEqual([c, a, b])
    })
  })

  describe("question type catalog", () => {
    it("palette renders all 11 question type chips", async () => {
      const wrapper = mount(QuizBuilder, { props: { builderId: BUILDER_ID } })
      await wrapper
        .find("[data-testid='quiz-builder-nav-palette']")
        .trigger("click")
      for (const type of [
        "single-choice",
        "multiple-choice",
        "true-false",
        "text-match",
        "numeric-range",
        "essay",
        "matching",
        "ordering",
        "fill-blank",
        "matching-categories",
        "ai-analysis",
      ]) {
        expect(
          wrapper
            .find(`[data-testid='quiz-builder-palette-${type}']`)
            .exists(),
        ).toBe(true)
      }
    })

    it("true-false defaults: correctAnswer = true, no options", () => {
      const store = useQuizBuilderStore()
      store.ensureBuilder(BUILDER_ID)
      const bankId = store.getSchema(BUILDER_ID).questionBanks[0]!.id
      const id = store.addQuestion(BUILDER_ID, "true-false", bankId)
      const q = store.getSchema(BUILDER_ID).questions.find((qq) => qq.id === id)!
      expect(q.correctAnswer).toBe(true)
      expect(q.options).toHaveLength(0)
    })

    it("text-match defaults: empty correctAnswers + trimWhitespace true", () => {
      const store = useQuizBuilderStore()
      store.ensureBuilder(BUILDER_ID)
      const bankId = store.getSchema(BUILDER_ID).questionBanks[0]!.id
      const id = store.addQuestion(BUILDER_ID, "text-match", bankId)
      const q = store.getSchema(BUILDER_ID).questions.find((qq) => qq.id === id)!
      expect(q.correctAnswers).toEqual([""])
      expect(q.caseSensitive).toBe(false)
      expect(q.trimWhitespace).toBe(true)
    })

    it("numeric-range defaults", () => {
      const store = useQuizBuilderStore()
      store.ensureBuilder(BUILDER_ID)
      const bankId = store.getSchema(BUILDER_ID).questionBanks[0]!.id
      const id = store.addQuestion(BUILDER_ID, "numeric-range", bankId)
      const q = store.getSchema(BUILDER_ID).questions.find((qq) => qq.id === id)!
      expect(q.correctAnswer).toBe(0)
      expect(q.tolerance).toBe(0)
    })

    it("matching defaults: two empty pairs + shuffleMatches true", () => {
      const store = useQuizBuilderStore()
      store.ensureBuilder(BUILDER_ID)
      const bankId = store.getSchema(BUILDER_ID).questionBanks[0]!.id
      const id = store.addQuestion(BUILDER_ID, "matching", bankId)
      const q = store.getSchema(BUILDER_ID).questions.find((qq) => qq.id === id)!
      expect(q.matchPairs).toHaveLength(2)
      expect(q.shuffleMatches).toBe(true)
    })

    it("ordering defaults: two empty slots", () => {
      const store = useQuizBuilderStore()
      store.ensureBuilder(BUILDER_ID)
      const bankId = store.getSchema(BUILDER_ID).questionBanks[0]!.id
      const id = store.addQuestion(BUILDER_ID, "ordering", bankId)
      const q = store.getSchema(BUILDER_ID).questions.find((qq) => qq.id === id)!
      expect(q.correctOrder).toEqual(["", ""])
    })

    it("fill-blank defaults: one blank with one empty answer", () => {
      const store = useQuizBuilderStore()
      store.ensureBuilder(BUILDER_ID)
      const bankId = store.getSchema(BUILDER_ID).questionBanks[0]!.id
      const id = store.addQuestion(BUILDER_ID, "fill-blank", bankId)
      const q = store.getSchema(BUILDER_ID).questions.find((qq) => qq.id === id)!
      expect(q.blanks).toHaveLength(1)
      expect(q.blanks![0]!.answers).toEqual([""])
    })

    it("matching-categories defaults: two categories with 4 items each", () => {
      const store = useQuizBuilderStore()
      store.ensureBuilder(BUILDER_ID)
      const bankId = store.getSchema(BUILDER_ID).questionBanks[0]!.id
      const id = store.addQuestion(BUILDER_ID, "matching-categories", bankId)
      const q = store.getSchema(BUILDER_ID).questions.find((qq) => qq.id === id)!
      expect(q.categories).toHaveLength(2)
      expect(q.categories![0]!.items).toHaveLength(4)
      expect(q.itemsPerCategory).toBe(4)
    })

    it("ai-analysis defaults: standard scoring + one criterion", () => {
      const store = useQuizBuilderStore()
      store.ensureBuilder(BUILDER_ID)
      const bankId = store.getSchema(BUILDER_ID).questionBanks[0]!.id
      const id = store.addQuestion(BUILDER_ID, "ai-analysis", bankId)
      const q = store.getSchema(BUILDER_ID).questions.find((qq) => qq.id === id)!
      expect(q.scoringMethod).toBe("standard")
      expect(q.aiCriteria).toHaveLength(1)
      expect(q.maxPoints).toBe(100)
    })

    it("changing type preserves the prompt and reseeds type-specific fields", () => {
      const store = useQuizBuilderStore()
      store.ensureBuilder(BUILDER_ID)
      const bankId = store.getSchema(BUILDER_ID).questionBanks[0]!.id
      const id = store.addQuestion(BUILDER_ID, "single-choice", bankId)
      store.updateQuestion(BUILDER_ID, id, {
        prompt: "Is it warm?",
        helpText: "any temp",
      })
      store.updateQuestion(BUILDER_ID, id, { type: "true-false" })
      const q = store.getSchema(BUILDER_ID).questions.find((qq) => qq.id === id)!
      expect(q.type).toBe("true-false")
      expect(q.prompt).toBe("Is it warm?")
      expect(q.helpText).toBe("any temp")
      expect(q.correctAnswer).toBe(true)
      expect(q.options).toHaveLength(0)
    })

    it("inspector shows the type-specific editor for the selected type", async () => {
      const wrapper = mount(QuizBuilder, { props: { builderId: BUILDER_ID } })
      const store = useQuizBuilderStore()
      const bankId = store.getSchema(BUILDER_ID).questionBanks[0]!.id

      store.addQuestion(BUILDER_ID, "matching", bankId)
      const matchingId = store.getSchema(BUILDER_ID).questions[0]!.id
      store.select(BUILDER_ID, matchingId)
      await wrapper.vm.$nextTick()
      expect(
        wrapper
          .find("[data-testid='quiz-builder-inspector-matching']")
          .exists(),
      ).toBe(true)

      store.addQuestion(BUILDER_ID, "ai-analysis", bankId)
      const aiId = store.getSchema(BUILDER_ID).questions[1]!.id
      store.select(BUILDER_ID, aiId)
      await wrapper.vm.$nextTick()
      expect(
        wrapper
          .find("[data-testid='quiz-builder-inspector-ai-analysis']")
          .exists(),
      ).toBe(true)
    })
  })

  describe("inspector tabs", () => {
    it("renders three icon tabs (general / options / grading)", async () => {
      const wrapper = mount(QuizBuilder, { props: { builderId: BUILDER_ID } })
      await wrapper
        .find("[data-testid='quiz-builder-nav-palette']")
        .trigger("click")
      await wrapper
        .find("[data-testid='quiz-builder-palette-single-choice']")
        .trigger("click")

      expect(
        wrapper.find("[data-testid='quiz-builder-inspector-tabs']").exists(),
      ).toBe(true)
      expect(
        wrapper
          .find("[data-testid='quiz-builder-inspector-tab-general']")
          .exists(),
      ).toBe(true)
      expect(
        wrapper
          .find("[data-testid='quiz-builder-inspector-tab-options']")
          .exists(),
      ).toBe(true)
      expect(
        wrapper
          .find("[data-testid='quiz-builder-inspector-tab-grading']")
          .exists(),
      ).toBe(true)
    })

    it("switches between panels via the tab buttons", async () => {
      const wrapper = mount(QuizBuilder, { props: { builderId: BUILDER_ID } })
      await wrapper
        .find("[data-testid='quiz-builder-nav-palette']")
        .trigger("click")
      await wrapper
        .find("[data-testid='quiz-builder-palette-single-choice']")
        .trigger("click")

      const panel = wrapper.find(
        "[data-testid='quiz-builder-inspector-fields']",
      )
      expect(panel.attributes("data-active-tab")).toBe("general")

      await wrapper
        .find("[data-testid='quiz-builder-inspector-tab-options']")
        .trigger("click")
      expect(panel.attributes("data-active-tab")).toBe("options")

      await wrapper
        .find("[data-testid='quiz-builder-inspector-tab-grading']")
        .trigger("click")
      expect(panel.attributes("data-active-tab")).toBe("grading")
    })

    it("grading tab edits feedback.correct / feedback.incorrect", async () => {
      const wrapper = mount(QuizBuilder, { props: { builderId: BUILDER_ID } })
      await wrapper
        .find("[data-testid='quiz-builder-nav-palette']")
        .trigger("click")
      await wrapper
        .find("[data-testid='quiz-builder-palette-single-choice']")
        .trigger("click")
      await wrapper
        .find("[data-testid='quiz-builder-inspector-tab-grading']")
        .trigger("click")

      await wrapper
        .find("[data-testid='quiz-builder-inspector-feedback-correct']")
        .setValue("Nice work!")
      await wrapper
        .find("[data-testid='quiz-builder-inspector-feedback-incorrect']")
        .setValue("Not quite.")

      const store = useQuizBuilderStore()
      const q = store.getSchema(BUILDER_ID).questions[0]!
      expect(q.feedback?.correct).toBe("Nice work!")
      expect(q.feedback?.incorrect).toBe("Not quite.")
    })
  })

  describe("inspector", () => {
    it("collapses to an icon when nothing is selected", () => {
      const wrapper = mount(QuizBuilder, { props: { builderId: BUILDER_ID } })
      expect(
        wrapper.find("[data-testid='quiz-builder-inspector-empty']").exists(),
      ).toBe(true)
      expect(
        wrapper.find("[data-testid='quiz-builder-inspector-fields']").exists(),
      ).toBe(false)
    })

    it("expands when a question is selected", async () => {
      const wrapper = mount(QuizBuilder, { props: { builderId: BUILDER_ID } })
      await wrapper
        .find("[data-testid='quiz-builder-nav-palette']")
        .trigger("click")
      await wrapper
        .find("[data-testid='quiz-builder-palette-single-choice']")
        .trigger("click")
      expect(
        wrapper.find("[data-testid='quiz-builder-inspector-fields']").exists(),
      ).toBe(true)
      expect(
        wrapper.find("[data-testid='quiz-builder-inspector-empty']").exists(),
      ).toBe(false)
    })
  })
})
