import { mount } from "@vue/test-utils"
import { describe, expect, it, vi } from "vitest"
import EditorToolbar from "@/components/EditorToolbar.vue"

function createMockHandlers() {
  return {
    isActive: vi.fn(() => false),
    getActiveHeading: vi.fn(() => null),
    getActiveTask: vi.fn(() => null),
    setHeading: vi.fn(),
    toggleBold: vi.fn(),
    toggleItalic: vi.fn(),
    toggleCode: vi.fn(),
    toggleStrikethrough: vi.fn(),
    toggleHighlight: vi.fn(),
    toggleTask: vi.fn(),
    insertLink: vi.fn(),
    insertInlineMath: vi.fn(),
    insertBlockMath: vi.fn(),
    insertPageRef: vi.fn(),
    insertBlockRef: vi.fn(),
    insertTag: vi.fn(),
  }
}

function createWrapper(handlers: unknown = null) {
  return mount(EditorToolbar, {
    props: {
      handlers: handlers as any,
    },
    global: {
      stubs: {
        UButton: { template: "<button><slot /></button>" },
        UDropdownMenu: { template: "<div><slot /></div>" },
        UTooltip: { template: "<div><slot /></div>" },
        USeparator: { template: "<div />" },
        UModal: {
          props: ["open"],
          template:
            '<div v-if="open" class="modal-content"><slot name="content" /></div>',
        },
        UCard: {
          template:
            '<div><slot name="header" /><slot /><slot name="footer" /></div>',
        },
        UInput: {
          props: ["modelValue", "placeholder"],
          template:
            '<input :placeholder="placeholder" :value="modelValue" @input="$emit(\'update:modelValue\', $event.target.value)" @keydown="$emit(\'keydown\', $event)" />',
        },
      },
    },
  })
}

describe("EditorToolbar", () => {
  it("disables all buttons when handlers is null", () => {
    const wrapper = createWrapper(null)
    const buttons = wrapper.findAll("button")
    for (const btn of buttons) {
      expect(btn.attributes("disabled")).toBeDefined()
    }
  })

  it("enables buttons when handlers is provided", () => {
    const wrapper = createWrapper(createMockHandlers())
    const buttons = wrapper.findAll("button")
    // First button is the dropdown trigger (disabled via :disabled="!handlers")
    // but the stub doesn't pass disabled; the inner buttons should work.
    expect(buttons.length).toBeGreaterThan(0)
  })

  it("opens modal for page reference", async () => {
    const handlers = createMockHandlers()
    const wrapper = createWrapper(handlers)

    // Find and click the page reference button
    const buttons = wrapper.findAll("button")
    // Last group is references. Click the first reference button (page ref).
    const refButtons = buttons.filter((b) =>
      b.attributes("icon")?.includes("book-marked"),
    )
    if (refButtons.length > 0) {
      await refButtons[0].trigger("click")
    } else {
      // Fallback: click the last 3 buttons which are ref buttons
      const lastButtons = buttons.slice(-3)
      await lastButtons[0].trigger("click")
    }

    // Wait for nextTick (openPrompt uses it)
    await new Promise((r) => setTimeout(r, 10))

    // Modal should now be visible
    expect(wrapper.find(".modal-content").exists()).toBe(true)
    expect(wrapper.find("h3").text()).toBe("Insert Page Reference")
    expect(wrapper.find("input").attributes("placeholder")).toBe(
      "Enter page name...",
    )
  })

  it("confirming page ref calls insertPageRef", async () => {
    const handlers = createMockHandlers()
    const wrapper = createWrapper(handlers)

    // Open the page ref prompt
    const buttons = wrapper.findAll("button")
    const lastButtons = buttons.slice(-3)
    await lastButtons[0].trigger("click")
    await new Promise((r) => setTimeout(r, 10))

    // Type a value and press Enter
    const input = wrapper.find("input")
    await input.setValue("My Page")
    await input.trigger("keydown", { key: "Enter" })

    expect(handlers.insertPageRef).toHaveBeenCalledWith("My Page")
  })

  it("pressing Escape closes the modal", async () => {
    const handlers = createMockHandlers()
    const wrapper = createWrapper(handlers)

    // Open the page ref prompt
    const buttons = wrapper.findAll("button")
    const lastButtons = buttons.slice(-3)
    await lastButtons[0].trigger("click")
    await new Promise((r) => setTimeout(r, 10))

    expect(wrapper.find(".modal-content").exists()).toBe(true)

    // Press Escape
    const input = wrapper.find("input")
    await input.trigger("keydown", { key: "Escape" })

    expect(wrapper.find(".modal-content").exists()).toBe(false)
  })

  it("shows correct labels for block ref and tag modals", async () => {
    const handlers = createMockHandlers()
    const wrapper = createWrapper(handlers)
    const buttons = wrapper.findAll("button")
    const lastButtons = buttons.slice(-3)

    // Block ref
    await lastButtons[1].trigger("click")
    await new Promise((r) => setTimeout(r, 10))
    expect(wrapper.find("h3").text()).toBe("Insert Block Reference")
    expect(wrapper.find("input").attributes("placeholder")).toBe(
      "Enter block ID...",
    )

    // Close
    await wrapper.find("input").trigger("keydown", { key: "Escape" })
    await new Promise((r) => setTimeout(r, 10))

    // Tag
    await lastButtons[2].trigger("click")
    await new Promise((r) => setTimeout(r, 10))
    expect(wrapper.find("h3").text()).toBe("Insert Tag")
    expect(wrapper.find("input").attributes("placeholder")).toBe(
      "Enter tag name...",
    )
  })
})
