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

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

  it("hides the visible label when hideLabel is true", () => {
    const wrapper = mount(TextInput, {
      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("forwards modelValue to the input element", () => {
    const wrapper = mount(TextInput, {
      props: { modelValue: "Stephen" },
    })
    expect((wrapper.find("input").element as HTMLInputElement).value).toBe(
      "Stephen",
    )
  })

  it("emits update:modelValue when the user types", async () => {
    const wrapper = mount(TextInput, { props: { modelValue: "" } })
    await wrapper.find("input").setValue("typed")
    const emitted = wrapper.emitted("update:modelValue")
    expect(emitted).toBeTruthy()
    expect(emitted![0]).toEqual(["typed"])
  })

  it("applies disabled / readonly / required / placeholder / id / name", () => {
    const wrapper = mount(TextInput, {
      props: {
        id: "user-name",
        name: "user_name",
        placeholder: "Enter name",
        disabled: true,
        readonly: true,
        required: true,
      },
    })
    const el = wrapper.find("input").element as HTMLInputElement
    expect(el.id).toBe("user-name")
    expect(el.name).toBe("user_name")
    expect(el.placeholder).toBe("Enter name")
    expect(el.disabled).toBe(true)
    expect(el.readOnly).toBe(true)
    expect(el.required).toBe(true)
  })

  it("renders help text below the input", () => {
    const wrapper = mount(TextInput, {
      props: { label: "X", helpText: "Helpful hint" },
    })
    expect(wrapper.find("[data-testid='field-frame-help']").text()).toBe(
      "Helpful hint",
    )
  })

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

  it("forwards maxlength / minlength", () => {
    const wrapper = mount(TextInput, {
      props: { maxlength: 10, minlength: 2 },
    })
    const el = wrapper.find("input").element as HTMLInputElement
    expect(el.maxLength).toBe(10)
    expect(el.minLength).toBe(2)
  })

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