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

describe("Checkbox", () => {
  describe("default rendering", () => {
    it("renders as a button with role=checkbox", () => {
      const wrapper = mount(Checkbox)
      expect(wrapper.element.tagName).toBe("BUTTON")
      expect(wrapper.attributes("role")).toBe("checkbox")
    })

    it("has base layout classes", () => {
      const wrapper = mount(Checkbox)
      const classes = wrapper.classes()
      for (const cls of [
        "peer",
        "h-4",
        "w-4",
        "shrink-0",
        "rounded-sm",
        "border",
        "border-primary",
      ]) {
        expect(classes).toContain(cls)
      }
    })

    it("has focus-visible classes", () => {
      const wrapper = mount(Checkbox)
      const classes = wrapper.classes()
      for (const cls of [
        "focus-visible:outline-none",
        "focus-visible:ring-2",
        "focus-visible:ring-ring",
        "focus-visible:ring-offset-2",
      ]) {
        expect(classes).toContain(cls)
      }
    })

    it("has disabled classes", () => {
      const wrapper = mount(Checkbox)
      expect(wrapper.classes()).toContain("disabled:cursor-not-allowed")
      expect(wrapper.classes()).toContain("disabled:opacity-50")
    })

    it("has data-state=unchecked by default", () => {
      const wrapper = mount(Checkbox)
      expect(wrapper.attributes("data-state")).toBe("unchecked")
    })
  })

  describe("state via defaultValue", () => {
    it("is checked when defaultValue=true", () => {
      const wrapper = mount(Checkbox, { props: { defaultValue: true } })
      expect(wrapper.attributes("data-state")).toBe("checked")
    })

    it("is indeterminate when defaultValue='indeterminate'", () => {
      const wrapper = mount(Checkbox, { props: { defaultValue: "indeterminate" } })
      expect(wrapper.attributes("data-state")).toBe("indeterminate")
    })

    it("is unchecked when defaultValue=false", () => {
      const wrapper = mount(Checkbox, { props: { defaultValue: false } })
      expect(wrapper.attributes("data-state")).toBe("unchecked")
    })
  })

  describe("v-model / modelValue", () => {
    it("reflects controlled modelValue=true", () => {
      const wrapper = mount(Checkbox, { props: { modelValue: true } })
      expect(wrapper.attributes("data-state")).toBe("checked")
    })

    it("reflects controlled modelValue=false", () => {
      const wrapper = mount(Checkbox, { props: { modelValue: false } })
      expect(wrapper.attributes("data-state")).toBe("unchecked")
    })

    it("reflects controlled modelValue='indeterminate'", () => {
      const wrapper = mount(Checkbox, { props: { modelValue: "indeterminate" } })
      expect(wrapper.attributes("data-state")).toBe("indeterminate")
    })

    it("emits update:modelValue when clicked", async () => {
      const wrapper = mount(Checkbox, { props: { modelValue: false } })
      await wrapper.trigger("click")
      expect(wrapper.emitted("update:modelValue")).toBeTruthy()
      expect(wrapper.emitted("update:modelValue")![0]).toEqual([true])
    })

    it("updates rendered state when modelValue prop changes", async () => {
      const wrapper = mount(Checkbox, { props: { modelValue: false } })
      expect(wrapper.attributes("data-state")).toBe("unchecked")
      await wrapper.setProps({ modelValue: true })
      expect(wrapper.attributes("data-state")).toBe("checked")
    })
  })

  describe("disabled", () => {
    it("forwards disabled attribute", () => {
      const wrapper = mount(Checkbox, { props: { disabled: true } })
      expect(wrapper.attributes("disabled")).toBe("")
    })

    it("has data-disabled when disabled", () => {
      const wrapper = mount(Checkbox, { props: { disabled: true } })
      expect(wrapper.attributes("data-disabled")).toBeDefined()
    })
  })

  describe("custom class", () => {
    it("merges custom class with base classes", () => {
      const wrapper = mount(Checkbox, { props: { class: "my-custom" } })
      expect(wrapper.classes()).toContain("my-custom")
      expect(wrapper.classes()).toContain("peer")
    })

    it("allows overriding sizing via tailwind-merge", () => {
      const wrapper = mount(Checkbox, { props: { class: "h-6 w-6" } })
      expect(wrapper.classes()).toContain("h-6")
      expect(wrapper.classes()).toContain("w-6")
      expect(wrapper.classes()).not.toContain("h-4")
      expect(wrapper.classes()).not.toContain("w-4")
    })
  })

  describe("a11y", () => {
    it("forwards aria-label", () => {
      const wrapper = mount(Checkbox, { attrs: { "aria-label": "Accept" } })
      expect(wrapper.attributes("aria-label")).toBe("Accept")
    })

    it("forwards id", () => {
      const wrapper = mount(Checkbox, { attrs: { id: "terms-cb" } })
      expect(wrapper.attributes("id")).toBe("terms-cb")
    })
  })
})
