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

describe("ButtonAction (props-based composition)", () => {
  it("mounts and renders the label", () => {
    const wrapper = mount(ButtonAction, { props: { label: "Save" } })
    expect(wrapper.find("button").exists()).toBe(true)
    expect(wrapper.text()).toContain("Save")
  })

  it("emits a native click event", async () => {
    const wrapper = mount(ButtonAction, { props: { label: "Click me" } })
    await wrapper.find("button").trigger("click")
    const emitted = wrapper.emitted("click")
    expect(emitted).toBeTruthy()
    expect(emitted!.length).toBe(1)
  })

  it("renders as anchor when href is set (and confirm is false)", () => {
    const wrapper = mount(ButtonAction, {
      props: { label: "Docs", href: "https://example.com", target: "_blank" },
    })
    const a = wrapper.find("a")
    expect(a.exists()).toBe(true)
    expect(a.attributes("href")).toBe("https://example.com")
    expect(a.attributes("target")).toBe("_blank")
  })

  it("emits a named action event when 'emit' prop is set and no href", async () => {
    const wrapper = mount(ButtonAction, {
      props: { label: "Delete", emit: "delete-row" },
    })
    await wrapper.find("button").trigger("click")
    const emitted = wrapper.emitted("action")
    expect(emitted).toBeTruthy()
    expect(emitted![0]).toEqual([{ name: "delete-row" }])
  })

  it("supports the variant matrix", () => {
    const variants = [
      "default",
      "secondary",
      "destructive",
      "outline",
      "ghost",
      "link",
    ] as const
    for (const variant of variants) {
      const wrapper = mount(ButtonAction, {
        props: { label: variant, variant },
      })
      expect(wrapper.find("button").exists()).toBe(true)
    }
  })

  it("supports sm / md / lg sizes", () => {
    const sizes = ["sm", "md", "lg"] as const
    for (const size of sizes) {
      const wrapper = mount(ButtonAction, { props: { label: "X", size } })
      expect(wrapper.find("button").exists()).toBe(true)
    }
  })

  it("respects disabled", () => {
    const wrapper = mount(ButtonAction, {
      props: { label: "Off", disabled: true },
    })
    expect(
      (wrapper.find("button").element as HTMLButtonElement).disabled,
    ).toBe(true)
  })

  it("when confirm=true, opens the dialog and does not emit action immediately", async () => {
    const wrapper = mount(ButtonAction, {
      props: { label: "Delete", emit: "delete", confirm: true },
      attachTo: document.body,
    })
    await wrapper.find("button").trigger("click")
    expect(wrapper.emitted("action")).toBeFalsy()
    wrapper.unmount()
  })

  it("renders block (full width) when block=true", () => {
    const wrapper = mount(ButtonAction, {
      props: { label: "B", block: true },
    })
    expect(wrapper.find("button").classes()).toContain("w-full")
  })

  it("works without any props at all", () => {
    const wrapper = mount(ButtonAction)
    expect(wrapper.find("button").exists()).toBe(true)
  })
})
