<script setup lang="ts">
/**
 * `card.info` element composition.
 *
 * Wraps the cards/InfoCard composition as an element-tier component.
 * Renders a read-only summary tile: optional icon/image header, title,
 * subtitle, and a list of label/value display rows.
 */
import { computed } from "vue"
import {
  Card,
  CardContent,
  CardHeader,
  CardTitle,
  CardDescription,
} from "@/components/ui/card"
import { cn } from "@/lib/utils"

interface InfoField {
  label: string
  value: string
  icon?: string
  format?: string
  prepend?: string
  append?: string
}

export interface InfoCardProps {
  label?: string
  title?: string
  subtitle?: string
  showCard?: boolean
  icon?: string
  iconColor?: string
  headerImage?: string
  headerRatio?: string
  lessPadding?: boolean
  fields?: InfoField[]
  item?: Record<string, unknown>
  classList?: string[] | string
}

const props = withDefaults(defineProps<InfoCardProps>(), {
  showCard: true,
  lessPadding: false,
  fields: () => [],
  item: () => ({}),
})

const heading = computed(() => props.title ?? props.label)

/** Resolve a dot-path string against the item object. */
function resolvePath(path: string, item: Record<string, unknown>): unknown {
  return path.split(".").reduce<unknown>((acc, key) => {
    if (acc && typeof acc === "object" && key in (acc as Record<string, unknown>)) {
      return (acc as Record<string, unknown>)[key]
    }
    return undefined
  }, item)
}

function formatValue(field: InfoField): string {
  const raw = resolvePath(field.value, props.item)
  const str = raw !== undefined && raw !== null ? String(raw) : field.value
  return `${field.prepend ?? ""}${str}${field.append ?? ""}`
}
</script>

<template>
  <Card v-if="props.showCard !== false" :class="cn(props.classList)">
    <!-- Header image -->
    <div
      v-if="props.headerImage"
      class="overflow-hidden rounded-t-lg bg-muted"
      :style="props.headerRatio ? { aspectRatio: props.headerRatio } : { height: '10rem' }"
    >
      <img
        :src="props.headerImage"
        :alt="heading ?? 'Info card header'"
        class="h-full w-full object-cover"
      />
    </div>

    <CardHeader v-if="heading || props.subtitle || props.icon" :class="props.lessPadding ? 'py-2' : ''">
      <div class="flex items-center gap-2">
        <span v-if="props.icon" :class="['lucide text-lg', props.iconColor ?? 'text-muted-foreground']">
          {{ props.icon }}
        </span>
        <div>
          <CardTitle v-if="heading">{{ heading }}</CardTitle>
          <CardDescription v-if="props.subtitle">{{ props.subtitle }}</CardDescription>
        </div>
      </div>
    </CardHeader>

    <CardContent :class="props.lessPadding ? 'py-2' : ''">
      <dl
        v-if="props.fields.length"
        class="grid grid-cols-[auto_1fr] gap-x-4 gap-y-1.5 text-sm"
      >
        <template v-for="field in props.fields" :key="field.label + field.value">
          <dt class="font-medium text-muted-foreground">{{ field.label }}</dt>
          <dd>{{ formatValue(field) }}</dd>
        </template>
      </dl>
      <p v-else class="text-sm text-muted-foreground">No fields configured.</p>
    </CardContent>
  </Card>

  <!-- Chromeless variant -->
  <div v-else :class="cn(props.classList)">
    <dl
      v-if="props.fields.length"
      class="grid grid-cols-[auto_1fr] gap-x-4 gap-y-1.5 text-sm"
    >
      <template v-for="field in props.fields" :key="field.label + field.value">
        <dt class="font-medium text-muted-foreground">{{ field.label }}</dt>
        <dd>{{ formatValue(field) }}</dd>
      </template>
    </dl>
  </div>
</template>
