<script setup lang="ts">
/**
 * Props-driven `element-list` card. Renders a vertical stack of
 * resolved CardElements via `ElementRenderer`.
 *
 * Self-contained — directly mountable in any Vue app:
 *
 *   <ElementListCard
 *     title="Personal details"
 *     :elements="[firstName, lastName]"
 *     :item="{ first_name: 'Jane' }"
 *   />
 *
 * The JSON-driven engine reaches this composition via `CardRenderer`,
 * which is responsible for resolving the card's `elementList: string[]`
 * IDs against the page-level `elements` map and forwarding the
 * resolved CardElement array as the `elements` prop here.
 */
import { computed } from "vue"
import type { CardElement } from "@/definitions/elements"
import ElementRenderer from "@/engine/ElementRenderer.vue"
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card"

export interface ElementListCardProps {
  title?: string
  subtitle?: string
  showCard?: boolean
  gutterY?: string
  gutterX?: string
  classList?: string[] | string
  /** Resolved child elements (NOT IDs). */
  elements?: CardElement[]
  /** Page-level data model passed through to child renderers. */
  item?: Record<string, unknown>
}

const props = withDefaults(defineProps<ElementListCardProps>(), {
  showCard: true,
  gutterY: "1rem",
  gutterX: "1rem",
  elements: () => [],
  item: () => ({}),
})

const showChrome = computed<boolean>(() => props.showCard !== false)

const hasHeader = computed<boolean>(
  () => Boolean(props.title) || Boolean(props.subtitle),
)

const bodyStyle = computed(() => ({
  rowGap: props.gutterY,
  columnGap: props.gutterX,
}))
</script>

<template>
  <Card v-if="showChrome" class="flex flex-col">
    <CardHeader v-if="hasHeader">
      <CardTitle v-if="title">{{ title }}</CardTitle>
      <CardDescription v-if="subtitle">
        {{ subtitle }}
      </CardDescription>
    </CardHeader>
    <CardContent
      class="flex flex-col"
      :class="[hasHeader ? '' : 'pt-6']"
      :style="bodyStyle"
    >
      <ElementRenderer
        v-for="element in elements"
        :key="element.id"
        :element="element"
        :item="item"
      />
    </CardContent>
  </Card>
  <section
    v-else
    class="flex flex-col"
    :style="bodyStyle"
    data-testid="element-list-bare"
  >
    <header v-if="hasHeader" class="mb-3 flex flex-col gap-0.5">
      <h3 v-if="title" class="text-base font-semibold">
        {{ title }}
      </h3>
      <p v-if="subtitle" class="text-sm text-muted-foreground">
        {{ subtitle }}
      </p>
    </header>
    <ElementRenderer
      v-for="element in elements"
      :key="element.id"
      :element="element"
      :item="item"
    />
  </section>
</template>
