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

describe("NumberInput (props-based composition)", () => {
  it("mounts and renders the label via FieldFrame", () => {
    const wrapper = mount(NumberInput, { props: { label: "Age" } })
    expect(wrapper.find("input").exists()).toBe(true)
    expect(wrapper.find("input").attributes("type")).toBe("number")
    expect(wrapper.text()).toContain("Age")
  })

  it("forwards modelValue to the input element", () => {
    const wrapper = mount(NumberInput, { props: { modelValue: 42 } })
    expect((wrapper.find("input").element as HTMLInputElement).value).toBe("42")
  })

  it("emits update:modelValue as a number when the user types", async () => {
    const wrapper = mount(NumberInput, { props: { modelValue: null } })
    await wrapper.find("input").setValue("7")
    const emitted = wrapper.emitted("update:modelValue")
    expect(emitted).toBeTruthy()
    expect(emitted![emitted!.length - 1]).toEqual([7])
  })

  it("emits null when the input is cleared", async () => {
    const wrapper = mount(NumberInput, { props: { modelValue: 5 } })
    await wrapper.find("input").setValue("")
    const emitted = wrapper.emitted("update:modelValue")
    expect(emitted).toBeTruthy()
    expect(emitted![emitted!.length - 1]).toEqual([null])
  })

  it("forwards min, max, step", () => {
    const wrapper = mount(NumberInput, {
      props: { min: 0, max: 100, step: 5 },
    })
    const el = wrapper.find("input").element as HTMLInputElement
    expect(el.min).toBe("0")
    expect(el.max).toBe("100")
    expect(el.step).toBe("5")
  })

  it("renders errors and flips the input border to destructive", () => {
    const wrapper = mount(NumberInput, {
      props: { errors: ["Invalid"] },
    })
    expect(wrapper.find("[data-testid='field-frame-errors']").exists()).toBe(true)
    expect(wrapper.find("input").classes()).toContain("border-destructive")
  })

  it("hides the label when hideLabel is true", () => {
    const wrapper = mount(NumberInput, {
      props: { label: "Hidden", hideLabel: true },
    })
    expect(wrapper.find("[data-testid='field-frame-label-sr']").exists()).toBe(true)
    expect(wrapper.find("[data-testid='field-frame-label']").exists()).toBe(false)
  })

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