<template>
  <el-card class="dtp-card" shadow="never">
    <template #header>
      <div class="dtp-header">
        <span class="dtp-title">{{ title }}</span>
        <div class="dtp-actions">
          <el-input v-if="searchable" v-model="kw" :placeholder="searchPlaceholder" clearable size="small" style="width: 220px" />
          <slot name="actions" />
        </div>
      </div>
    </template>
    <el-table :data="filtered" stripe size="small" :max-height="maxHeight" border>
      <el-table-column v-for="c in columns" :key="c.prop" :prop="c.prop" :label="c.label" :width="c.width" :min-width="c.minWidth">
        <template #default="scope">
          <slot :name="`col-${c.prop}`" :row="scope.row">
            {{ scope.row[c.prop] }}
          </slot>
        </template>
      </el-table-column>
      <slot name="extra-columns" />
    </el-table>
  </el-card>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue'

interface Column { prop: string; label: string; width?: number | string; minWidth?: number | string }

const props = defineProps<{
  title: string
  data: Array<Record<string, unknown>>
  columns: Column[]
  searchable?: boolean
  searchPlaceholder?: string
  maxHeight?: number | string
}>()

const kw = ref('')

const filtered = computed(() => {
  if (!props.searchable || !kw.value) return props.data
  const q = kw.value.trim().toLowerCase()
  return props.data.filter((row) =>
    Object.values(row).some((v) => String(v ?? '').toLowerCase().includes(q))
  )
})
</script>

<style scoped>
.dtp-header { display: flex; justify-content: space-between; align-items: center; }
.dtp-title { font-weight: 600; }
.dtp-actions { display: flex; gap: 8px; align-items: center; }
</style>
