import { beforeEach, describe, expect, it } from "vitest"
import { mount } from "@vue/test-utils"
import { createPinia, setActivePinia } from "pinia"
import { __clearElementCache } from "@/engine/useElementLoader"
import RepeatableBlock from "./RepeatableBlock.vue"

describe("RepeatableBlock", () => {
  beforeEach(() => {
    setActivePinia(createPinia())
    __clearElementCache()
  })

  it("renders with no rows by default", () => {
    const wrapper = mount(RepeatableBlock)
    expect(wrapper.findAll("[data-testid='repeatable-row']").length).toBe(0)
  })

  it("renders the default add button label", () => {
    const wrapper = mount(RepeatableBlock)
    expect(wrapper.find("[data-testid='repeatable-add']").text()).toContain("Add row")
  })

  it("renders a custom add button label", () => {
    const wrapper = mount(RepeatableBlock, {
      props: { addButtonLabel: "Add speaker" },
    })
    expect(wrapper.find("[data-testid='repeatable-add']").text()).toContain("Add speaker")
  })

  it("seeds rows from the modelValue array length", () => {
    const wrapper = mount(RepeatableBlock, {
      props: { modelValue: [{}, {}] },
    })
    expect(wrapper.findAll("[data-testid='repeatable-row']").length).toBe(2)
  })

  it("adds a row when the add button is clicked", async () => {
    const wrapper = mount(RepeatableBlock)
    expect(wrapper.findAll("[data-testid='repeatable-row']").length).toBe(0)
    await wrapper.find("[data-testid='repeatable-add']").trigger("click")
    expect(wrapper.findAll("[data-testid='repeatable-row']").length).toBe(1)
    expect(wrapper.emitted("update:modelValue")).toBeTruthy()
  })

  it("emits update:modelValue when a row is removed", async () => {
    const wrapper = mount(RepeatableBlock, {
      props: { modelValue: [{}, {}] },
    })
    expect(wrapper.findAll("[data-testid='repeatable-row']").length).toBe(2)
    await wrapper.find("button[aria-label='Remove row']").trigger("click")
    expect(wrapper.findAll("[data-testid='repeatable-row']").length).toBe(1)
    const emitted = wrapper.emitted("update:modelValue")
    expect(emitted).toBeTruthy()
    expect((emitted![0] as unknown[])[0]).toHaveLength(1)
  })

  it("collapses a row when the header is clicked", async () => {
    const wrapper = mount(RepeatableBlock, {
      props: { modelValue: [{}], nestedElements: [] },
    })
    const header = wrapper.find("[data-testid='repeatable-row'] div.cursor-pointer")
    await header.trigger("click")
    // After collapse, ChevronRight should be present (collapsed state)
    expect(wrapper.html()).toContain("chevron-right")
  })

  it("starts rows collapsed when collapsedByDefault is true", () => {
    const wrapper = mount(RepeatableBlock, {
      props: { modelValue: [{}], collapsedByDefault: true },
    })
    // ChevronRight indicates collapsed state
    expect(wrapper.html()).toContain("chevron-right")
  })

  it("uses optionLabelFields for row header labels", () => {
    const wrapper = mount(RepeatableBlock, {
      props: {
        label: "Tier",
        modelValue: [{ tier_name: "Gold" }],
        optionLabelFields: ["tier_name"],
      },
    })
    expect(wrapper.text()).toContain("Gold")
  })

  it("falls back to label + index when optionLabelFields is empty", () => {
    const wrapper = mount(RepeatableBlock, {
      props: { label: "Speaker", modelValue: [{}] },
    })
    expect(wrapper.text()).toContain("Speaker 1")
  })
})
