import { beforeEach, describe, expect, it } from "vitest"
import { defineComponent, h, Suspense } from "vue"
import { flushPromises, mount } from "@vue/test-utils"
import { createPinia, setActivePinia } from "pinia"
import type { CardElement } from "@/definitions/elements"
import type { InputElement } from "@/definitions/elements/InputElement"
import ElementDisplayCard from "./ElementDisplayCard.vue"
import {
  __clearElementCache,
  preloadElement,
} from "@/engine/useElementLoader"

function makeInput(
  id: string,
  overrides: Partial<InputElement> = {},
): InputElement {
  return {
    id,
    type: "input.text",
    name: id,
    label: `Label for ${id}`,
    ...overrides,
  } as InputElement
}

function mountWithSuspense(props: Record<string, unknown>) {
  const Host = defineComponent({
    setup() {
      return () =>
        h(Suspense, null, {
          default: () =>
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            h(ElementDisplayCard as any, props),
        })
    },
  })
  return mount(Host)
}

describe("ElementDisplayCard", () => {
  beforeEach(async () => {
    setActivePinia(createPinia())
    __clearElementCache()
    await preloadElement("input.text")
  })

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

  it("renders nothing when no element is provided", () => {
    const wrapper = mount(ElementDisplayCard, { props: {} })
    expect(wrapper.find("[data-element-id]").exists()).toBe(false)
  })

  it("renders the provided element with no chrome by default", async () => {
    const element: CardElement = makeInput("widget", { label: "Widget label" })
    const wrapper = mountWithSuspense({ element })
    await flushPromises()
    expect(wrapper.text()).toContain("Widget label")
    expect(wrapper.find("input").exists()).toBe(true)
    // No Card chrome → no h3 card title.
    expect(wrapper.find("h3").exists()).toBe(false)
  })

  it("wraps the element in Card chrome when showCard is true", async () => {
    const element: CardElement = makeInput("widget", { label: "Widget label" })
    const wrapper = mountWithSuspense({
      element,
      showCard: true,
      title: "Wrapped widget",
    })
    await flushPromises()
    expect(wrapper.text()).toContain("Wrapped widget")
    expect(wrapper.text()).toContain("Widget label")
  })

  it("renders nothing when showCard is true but no element is provided", () => {
    const wrapper = mount(ElementDisplayCard, {
      props: {
        showCard: true,
        title: "Should not appear",
      },
    })
    expect(wrapper.text()).not.toContain("Should not appear")
  })
})
