import { beforeEach, describe, expect, it } from "vitest"
import { flushPromises, mount } from "@vue/test-utils"
import { createPinia, setActivePinia } from "pinia"
import { nextTick } from "vue"
import type { DisplayCard } from "@/definitions/cards"
import TabListCard from "./TabListCard.vue"
import { preloadCard } from "@/engine/useCardLoader"

function makeChild(id: string, title: string): DisplayCard {
  return {
    id,
    cardType: "element-list",
    elementList: [],
    title,
  } as unknown as DisplayCard
}

describe("TabListCard", () => {
  beforeEach(async () => {
    setActivePinia(createPinia())
    await preloadCard("element-list")
  })

  it("mounts without error", () => {
    const wrapper = mount(TabListCard, { props: {} })
    expect(wrapper.exists()).toBe(true)
  })

  it("renders an empty state when no tabs are passed", () => {
    const wrapper = mount(TabListCard, { props: {} })
    expect(wrapper.find("[data-testid='tab-list-empty']").exists()).toBe(true)
  })

  it("renders one trigger per tab and uses the tab's title as the label", () => {
    const wrapper = mount(TabListCard, {
      props: {
        tabs: [
          makeChild("t1", "General"),
          makeChild("t2", "Advanced"),
        ],
      },
    })
    const triggers = wrapper.findAll('[role="tab"]')
    expect(triggers).toHaveLength(2)
    expect(triggers[0].text()).toContain("General")
    expect(triggers[1].text()).toContain("Advanced")
  })

  it("defaults to the first tab being active", async () => {
    const wrapper = mount(TabListCard, {
      props: {
        tabs: [
          makeChild("t1", "General"),
          makeChild("t2", "Advanced"),
        ],
      },
    })
    await flushPromises()
    const active = wrapper.find('[role="tabpanel"][data-state="active"]')
    expect(active.attributes("data-tab-panel-id")).toBe("t1")
  })

  it("switches the active panel when another trigger is clicked", async () => {
    const wrapper = mount(TabListCard, {
      props: {
        tabs: [
          makeChild("t1", "General"),
          makeChild("t2", "Advanced"),
        ],
      },
    })
    await flushPromises()
    const triggers = wrapper.findAll('[role="tab"]')
    // reka-ui activates on mousedown, not click.
    await triggers[1].trigger("mousedown", { button: 0 })
    await nextTick()
    await nextTick()
    const active = wrapper.find('[role="tabpanel"][data-state="active"]')
    expect(active.attributes("data-tab-panel-id")).toBe("t2")
  })

  it("hides the nav when hideNav is true", () => {
    const wrapper = mount(TabListCard, {
      props: {
        tabs: [makeChild("t1", "Only")],
        hideNav: true,
      },
    })
    expect(wrapper.findAll('[role="tab"]')).toHaveLength(0)
  })

  it("falls back to the tab id as the label when the child has no title", () => {
    const wrapper = mount(TabListCard, {
      props: {
        tabs: [makeChild("only-tab", "")],
      },
    })
    const trigger = wrapper.find('[role="tab"]')
    expect(trigger.text()).toContain("only-tab")
  })
})
