import { describe, it, expect } from "vitest"
import { mount } from "@vue/test-utils"
import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from "."

describe("Card", () => {
  describe("Card root", () => {
    it("renders slot content with base classes", () => {
      const wrapper = mount(Card, { slots: { default: "Card content" } })
      expect(wrapper.text()).toBe("Card content")
      expect(wrapper.classes()).toContain("rounded-lg")
      expect(wrapper.classes()).toContain("bg-card")
      expect(wrapper.classes()).toContain("text-card-foreground")
    })

    it("renders as a div element", () => {
      const wrapper = mount(Card, { slots: { default: "Card" } })
      expect(wrapper.element.tagName).toBe("DIV")
    })

    it.each([
      ["default", ["border", "shadow-sm"]],
      ["bordered", ["border-2"]],
      ["elevated", ["border", "shadow-lg"]],
    ] as const)("renders %s variant with expected classes", (variant, expected) => {
      const wrapper = mount(Card, { props: { variant }, slots: { default: variant } })
      for (const cls of expected) {
        expect(wrapper.classes()).toContain(cls)
      }
    })

    it.each([
      ["sm", ["p-3"]],
      ["lg", ["p-8"]],
    ] as const)("renders %s padding with expected classes", (padding, expected) => {
      const wrapper = mount(Card, { props: { padding }, slots: { default: padding } })
      for (const cls of expected) {
        expect(wrapper.classes()).toContain(cls)
      }
    })

    it("accepts custom class via tailwind-merge", () => {
      const wrapper = mount(Card, {
        props: { class: "custom-card" },
        slots: { default: "Content" },
      })
      expect(wrapper.classes()).toContain("custom-card")
      expect(wrapper.classes()).toContain("rounded-lg")
    })

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

  describe("CardHeader", () => {
    it("renders slot content with header classes", () => {
      const wrapper = mount(CardHeader, { slots: { default: "Header" } })
      expect(wrapper.text()).toBe("Header")
      expect(wrapper.classes()).toContain("flex")
      expect(wrapper.classes()).toContain("flex-col")
      expect(wrapper.classes()).toContain("gap-y-1.5")
      expect(wrapper.classes()).toContain("p-6")
    })

    it("renders as a div element", () => {
      const wrapper = mount(CardHeader, { slots: { default: "Header" } })
      expect(wrapper.element.tagName).toBe("DIV")
    })

    it("accepts custom class", () => {
      const wrapper = mount(CardHeader, {
        props: { class: "custom-header" },
        slots: { default: "Header" },
      })
      expect(wrapper.classes()).toContain("custom-header")
      expect(wrapper.classes()).toContain("flex")
    })
  })

  describe("CardTitle", () => {
    it("renders as h3 with title classes", () => {
      const wrapper = mount(CardTitle, { slots: { default: "Title" } })
      expect(wrapper.text()).toBe("Title")
      expect(wrapper.element.tagName).toBe("H3")
      expect(wrapper.classes()).toContain("text-2xl")
      expect(wrapper.classes()).toContain("font-semibold")
      expect(wrapper.classes()).toContain("leading-none")
      expect(wrapper.classes()).toContain("tracking-tight")
    })

    it("accepts custom class", () => {
      const wrapper = mount(CardTitle, {
        props: { class: "custom-title" },
        slots: { default: "Title" },
      })
      expect(wrapper.classes()).toContain("custom-title")
      expect(wrapper.classes()).toContain("text-2xl")
    })
  })

  describe("CardDescription", () => {
    it("renders as a p element with muted classes", () => {
      const wrapper = mount(CardDescription, { slots: { default: "Description" } })
      expect(wrapper.text()).toBe("Description")
      expect(wrapper.element.tagName).toBe("P")
      expect(wrapper.classes()).toContain("text-sm")
      expect(wrapper.classes()).toContain("text-muted-foreground")
    })

    it("accepts custom class", () => {
      const wrapper = mount(CardDescription, {
        props: { class: "custom-desc" },
        slots: { default: "Desc" },
      })
      expect(wrapper.classes()).toContain("custom-desc")
    })
  })

  describe("CardContent", () => {
    it("renders slot content with content classes", () => {
      const wrapper = mount(CardContent, { slots: { default: "Content" } })
      expect(wrapper.text()).toBe("Content")
      expect(wrapper.classes()).toContain("p-6")
      expect(wrapper.classes()).toContain("pt-0")
    })

    it("renders as a div element", () => {
      const wrapper = mount(CardContent, { slots: { default: "Content" } })
      expect(wrapper.element.tagName).toBe("DIV")
    })

    it("accepts custom class", () => {
      const wrapper = mount(CardContent, {
        props: { class: "custom-content" },
        slots: { default: "Content" },
      })
      expect(wrapper.classes()).toContain("custom-content")
      expect(wrapper.classes()).toContain("p-6")
    })
  })

  describe("CardFooter", () => {
    it("renders slot content with footer classes", () => {
      const wrapper = mount(CardFooter, { slots: { default: "Footer" } })
      expect(wrapper.text()).toBe("Footer")
      expect(wrapper.classes()).toContain("flex")
      expect(wrapper.classes()).toContain("items-center")
      expect(wrapper.classes()).toContain("p-6")
      expect(wrapper.classes()).toContain("pt-0")
    })

    it("renders as a div element", () => {
      const wrapper = mount(CardFooter, { slots: { default: "Footer" } })
      expect(wrapper.element.tagName).toBe("DIV")
    })

    it("accepts custom class", () => {
      const wrapper = mount(CardFooter, {
        props: { class: "custom-footer" },
        slots: { default: "Footer" },
      })
      expect(wrapper.classes()).toContain("custom-footer")
      expect(wrapper.classes()).toContain("flex")
    })
  })

  describe("composition", () => {
    it("renders all sub-components composed together", () => {
      const wrapper = mount({
        components: { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter },
        template: `
          <Card>
            <CardHeader>
              <CardTitle>Title</CardTitle>
              <CardDescription>Description</CardDescription>
            </CardHeader>
            <CardContent>Content</CardContent>
            <CardFooter>Footer</CardFooter>
          </Card>
        `,
      })
      expect(wrapper.find("h3").text()).toBe("Title")
      expect(wrapper.find("p").text()).toBe("Description")
      expect(wrapper.text()).toContain("Content")
      expect(wrapper.text()).toContain("Footer")
    })
  })
})
