import { describe, expect, it } from "vitest"
import { flushPromises, mount } from "@vue/test-utils"
import HtmlEditor from "./HtmlEditor.vue"

async function mountEditor(
  props: Partial<InstanceType<typeof HtmlEditor>["$props"]> = {},
) {
  const wrapper = mount(HtmlEditor, { props, attachTo: document.body })
  await flushPromises()
  return wrapper
}

describe("HtmlEditor (props-based composition)", () => {
  it("mounts and renders the toolbar and content area", async () => {
    const wrapper = await mountEditor({ label: "HTML body" })
    expect(wrapper.find("[data-testid='html-editor']").exists()).toBe(true)
    expect(wrapper.find("[data-testid='html-editor-toolbar']").exists()).toBe(true)
    expect(wrapper.find("[data-testid='html-editor-content']").exists()).toBe(true)
    expect(wrapper.text()).toContain("HTML body")
  })

  it("renders the label via FieldFrame", async () => {
    const wrapper = await mountEditor({ label: "Custom label" })
    expect(wrapper.text()).toContain("Custom label")
  })

  it("hides the label when hideLabel is true", async () => {
    const wrapper = await mountEditor({ label: "Should hide", hideLabel: true })
    expect(wrapper.find("[data-testid='field-frame-label']").exists()).toBe(false)
  })

  it("renders errors from props", async () => {
    const wrapper = await mountEditor({ errors: ["Required"] })
    expect(wrapper.text()).toContain("Required")
    expect(wrapper.find("[data-testid='field-frame-errors']").exists()).toBe(true)
  })

  it("applies destructive border when errors are present", async () => {
    const wrapper = await mountEditor({ errors: ["Bad input"] })
    expect(wrapper.html()).toContain("border-destructive")
  })

  it("renders help text", async () => {
    const wrapper = await mountEditor({ helpText: "Supports full HTML" })
    expect(wrapper.text()).toContain("Supports full HTML")
  })

  it("forwards modelValue HTML into the editor content", async () => {
    const wrapper = await mountEditor({ modelValue: "<p>Hello world</p>" })
    const content = wrapper.find("[data-testid='html-editor-content']")
    expect(content.exists()).toBe(true)
    expect(content.text()).toContain("Hello world")
  })

  it("disables the toolbar when readonly is set", async () => {
    const wrapper = await mountEditor({ readonly: true })
    expect(wrapper.find("[data-testid='html-editor-toolbar']").classes()).toContain("pointer-events-none")
  })

  it("disables the toolbar when disabled is set", async () => {
    const wrapper = await mountEditor({ disabled: true })
    expect(wrapper.find("[data-testid='html-editor-toolbar']").classes()).toContain("pointer-events-none")
  })

  it("shows the source textarea inside the source dialog when opened", async () => {
    const wrapper = await mountEditor()
    // Source textarea is inside the dialog — not visible until opened.
    // Confirm the source button exists in the toolbar.
    const toolbar = wrapper.find("[data-testid='html-editor-toolbar']")
    expect(toolbar.exists()).toBe(true)
  })

  it("works without any props at all", async () => {
    const wrapper = await mountEditor()
    expect(wrapper.find("[data-testid='html-editor']").exists()).toBe(true)
    expect(wrapper.find("[data-testid='html-editor-content']").exists()).toBe(true)
  })
})
