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

describe("Progress", () => {
  describe("default rendering", () => {
    it("renders without errors", () => {
      const wrapper = mount(Progress)
      expect(wrapper.exists()).toBe(true)
    })

    it("renders with role=progressbar (reka)", () => {
      const wrapper = mount(Progress, { props: { value: 50 } })
      const role = wrapper.find('[role="progressbar"]')
      expect(role.exists()).toBe(true)
    })

    it("has base root classes", () => {
      const wrapper = mount(Progress)
      const classes = wrapper.classes()
      for (const cls of [
        "relative",
        "w-full",
        "overflow-hidden",
        "rounded-full",
        "bg-secondary",
      ]) {
        expect(classes).toContain(cls)
      }
    })

    it("uses default size when not provided", () => {
      const wrapper = mount(Progress)
      expect(wrapper.classes()).toContain("h-4")
    })
  })

  describe("values", () => {
    it.each([0, 25, 50, 75, 100])("renders value %i with correct transform", (value) => {
      const wrapper = mount(Progress, { props: { value } })
      const indicator = wrapper.find('[role="progressbar"] > *')
      expect(indicator.exists()).toBe(true)
      const style = indicator.attributes("style") ?? ""
      expect(style).toContain(`translateX(-${100 - value}%)`)
    })

    it("clamps values above 100", () => {
      const wrapper = mount(Progress, { props: { value: 150 } })
      const indicator = wrapper.find('[role="progressbar"] > *')
      const style = indicator.attributes("style") ?? ""
      expect(style).toContain("translateX(-0%)")
    })

    it("clamps values below 0", () => {
      const wrapper = mount(Progress, { props: { value: -50 } })
      const indicator = wrapper.find('[role="progressbar"] > *')
      const style = indicator.attributes("style") ?? ""
      expect(style).toContain("translateX(-100%)")
    })

    it("supports custom max", () => {
      const wrapper = mount(Progress, { props: { value: 50, max: 200 } })
      const indicator = wrapper.find('[role="progressbar"] > *')
      const style = indicator.attributes("style") ?? ""
      // 50/200 = 25%, so translateX(-75%)
      expect(style).toContain("translateX(-75%)")
    })
  })

  describe("variants", () => {
    it.each([
      ["default", "bg-primary"],
      ["success", "bg-success"],
      ["destructive", "bg-destructive"],
    ] as const)("renders %s variant with %s", (variant, expected) => {
      const wrapper = mount(Progress, { props: { variant, value: 50 } })
      const indicator = wrapper.find('[role="progressbar"] > *')
      expect(indicator.classes()).toContain(expected)
    })
  })

  describe("sizes", () => {
    it.each([
      ["sm", "h-2"],
      ["default", "h-4"],
      ["lg", "h-6"],
    ] as const)("renders %s size with %s", (size, expected) => {
      const wrapper = mount(Progress, { props: { size, value: 50 } })
      expect(wrapper.classes()).toContain(expected)
    })
  })

  describe("indeterminate", () => {
    it("renders indeterminate state when value is null", () => {
      const wrapper = mount(Progress, { props: { value: null } })
      const indicator = wrapper.find('[role="progressbar"] > *')
      expect(indicator.classes()).toContain("animate-pulse")
    })

    it("does not animate-pulse when a value is provided", () => {
      const wrapper = mount(Progress, { props: { value: 50 } })
      const indicator = wrapper.find('[role="progressbar"] > *')
      expect(indicator.classes()).not.toContain("animate-pulse")
    })
  })

  describe("custom class", () => {
    it("merges custom class with default classes", () => {
      const wrapper = mount(Progress, { props: { class: "my-progress" } })
      expect(wrapper.classes()).toContain("my-progress")
      expect(wrapper.classes()).toContain("rounded-full")
    })

    it("allows overriding rounded via custom class", () => {
      const wrapper = mount(Progress, { props: { class: "rounded-none" } })
      expect(wrapper.classes()).toContain("rounded-none")
      expect(wrapper.classes()).not.toContain("rounded-full")
    })
  })
})
