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

describe("FieldFrame", () => {
  it("renders the slot content", () => {
    const wrapper = mount(FieldFrame, {
      slots: { default: '<input data-testid="inner" />' },
    })
    expect(wrapper.find("[data-testid='inner']").exists()).toBe(true)
  })

  it("renders a label when set", () => {
    const wrapper = mount(FieldFrame, {
      props: { label: "First name" },
      slots: { default: '<input />' },
    })
    expect(wrapper.find("[data-testid='field-frame-label']").text()).toBe(
      "First name",
    )
  })

  it("does not render a visible label when hideLabel is true", () => {
    const wrapper = mount(FieldFrame, {
      props: { label: "Hidden label", hideLabel: true },
      slots: { default: '<input />' },
    })
    expect(wrapper.find("[data-testid='field-frame-label']").exists()).toBe(
      false,
    )
    expect(
      wrapper.find("[data-testid='field-frame-label-sr']").classes(),
    ).toContain("sr-only")
  })

  it("forwards the `for` attribute to the label", () => {
    const wrapper = mount(FieldFrame, {
      props: { label: "Email", for: "email-input" },
      slots: { default: '<input id="email-input" />' },
    })
    expect(
      wrapper.find("[data-testid='field-frame-label']").attributes("for"),
    ).toBe("email-input")
  })

  it("renders helpText when set", () => {
    const wrapper = mount(FieldFrame, {
      props: { helpText: "Help me" },
      slots: { default: '<input />' },
    })
    expect(wrapper.find("[data-testid='field-frame-help']").text()).toBe(
      "Help me",
    )
  })

  it("renders an errors list with role=alert when errors is non-empty", () => {
    const wrapper = mount(FieldFrame, {
      props: { errors: ["First error", "Second error"] },
      slots: { default: '<input />' },
    })
    const errs = wrapper.find("[data-testid='field-frame-errors']")
    expect(errs.exists()).toBe(true)
    expect(errs.attributes("role")).toBe("alert")
    expect(errs.findAll("li")).toHaveLength(2)
    expect(errs.text()).toContain("First error")
    expect(errs.text()).toContain("Second error")
  })

  it("omits the errors list when errors is empty", () => {
    const wrapper = mount(FieldFrame, {
      props: { errors: [] },
      slots: { default: '<input />' },
    })
    expect(wrapper.find("[data-testid='field-frame-errors']").exists()).toBe(
      false,
    )
  })

  it("merges a custom class with the default flex column classes", () => {
    const wrapper = mount(FieldFrame, {
      props: { class: "custom-class" },
      slots: { default: '<input />' },
    })
    expect(wrapper.classes()).toContain("custom-class")
    expect(wrapper.classes()).toContain("flex")
    expect(wrapper.classes()).toContain("flex-col")
  })

  it("renders complex slot content like Vue components", () => {
    const Inner = { template: '<div class="inner-test">Inner</div>' }
    const wrapper = mount(FieldFrame, {
      props: { label: "Wrapper" },
      slots: { default: h(Inner) },
    })
    expect(wrapper.find(".inner-test").exists()).toBe(true)
  })

  it("supports a required asterisk via the Label primitive", () => {
    const wrapper = mount(FieldFrame, {
      props: { label: "Required field", required: true },
      slots: { default: '<input />' },
    })
    // The Label primitive renders an `after:content-['*']` pseudo-element
    // when required; assert the class is present on the rendered <label>.
    const label = wrapper.find("[data-testid='field-frame-label']")
    expect(label.html()).toContain("after:content-['*']")
  })
})
