<template>
    <!-- 桌面端：表格视图 -->
    <table v-if="!isMobile" class="data">
        <thead>
            <tr>
                <th v-if="$slots.checkbox" class="check-col"></th>
                <th v-for="col in columns" :key="col.key" :class="col.thClass">
                    {{ col.label }}
                </th>
                <th v-if="$slots.actions" class="actions-col"></th>
            </tr>
        </thead>
        <tbody>
            <tr
                v-for="(row, idx) in rows"
                :key="rowKey ? row[rowKey] : idx"
                :class="[rowClass, { selected: isSelected?.(row) }]"
                @click="onRowClick(row, $event)"
            >
                <td v-if="$slots.checkbox" class="check-col" @click.stop>
                    <slot name="checkbox" :row="row" />
                </td>
                <td v-for="col in columns" :key="col.key" :class="col.tdClass" @click="onCellClick(row, col, $event)">
                    <slot :name="`cell-${col.key}`" :row="row" :col="col">
                        {{ col.formatter ? col.formatter(row[col.key], row) : row[col.key] }}
                    </slot>
                </td>
                <td v-if="$slots.actions" class="row-actions" @click.stop>
                    <slot name="actions" :row="row" />
                </td>
            </tr>
            <tr v-if="!rows.length">
                <td :colspan="columns.length + (($slots.checkbox ? 1 : 0) + ($slots.actions ? 1 : 0))" class="text-mute" style="text-align:center; padding:32px">
                    <slot name="empty">{{ emptyText }}</slot>
                </td>
            </tr>
        </tbody>
    </table>

    <!-- 移动端：卡片视图 -->
    <div v-else class="card-list">
        <div
            v-for="(row, idx) in rows"
            :key="rowKey ? row[rowKey] : idx"
            class="card-item"
            :class="{ selected: isSelected?.(row), 'with-actions': $slots.actions }"
            @click="onRowClick(row, $event)"
        >
            <div v-if="$slots.checkbox" class="card-check" @click.stop>
                <slot name="checkbox" :row="row" />
            </div>
            <div class="card-body">
                <!-- 主标题行（按 columns 第一个作为主） -->
                <div v-for="(col, ci) in columns" :key="col.key" class="card-row" :class="col.key === primaryKey ? 'primary' : 'secondary'">
                    <span v-if="ci === 0 || col.key === primaryKey || col.alwaysShow" class="card-label">{{ col.label }}</span>
                    <span class="card-value">
                        <slot :name="`cell-${col.key}`" :row="row" :col="col">
                            {{ col.formatter ? col.formatter(row[col.key], row) : row[col.key] }}
                        </slot>
                    </span>
                </div>
            </div>
            <div v-if="$slots.actions" class="card-actions" @click.stop>
                <slot name="actions" :row="row" />
            </div>
        </div>
        <div v-if="!rows.length" class="card-empty text-mute">
            <slot name="empty">{{ emptyText }}</slot>
        </div>
    </div>
</template>

<script setup>
/**
 * MobileCardList — 桌面端表格 / 移动端卡片 自动切换
 *
 * props:
 *   columns: Array<{ key, label, thClass?, tdClass?, formatter?, alwaysShow? }>
 *     - key: 字段名
 *     - label: 列头 / 卡片小标签
 *     - formatter: (value, row) => string
 *     - alwaysShow: 卡片里也显示（默认 primary 显示，其余 hidden 防信息过载）
 *   rows: Array
 *   rowKey: 主键字段（默认用 index）
 *   rowClass: 行 class
 *   emptyText: 空状态文字
 *   primaryKey: 卡片主行（默认第一列）
 *   isSelected: (row) => boolean
 *
 * slots:
 *   cell-{key}: 自定义单元格渲染
 *   checkbox: 行内复选框（行首）
 *   actions: 行内操作（行末）
 *   empty: 空状态
 */
import { ref, onMounted, onBeforeUnmount, computed } from 'vue';

const props = defineProps({
    columns: { type: Array, required: true },
    rows: { type: Array, required: true },
    rowKey: { type: String, default: '' },
    rowClass: { type: String, default: '' },
    emptyText: { type: String, default: '暂无数据' },
    primaryKey: { type: String, default: '' },
    isSelected: { type: Function, default: null },
    clickable: { type: Boolean, default: true },
});

const emit = defineEmits(['row-click', 'cell-click']);

const windowWidth = ref(typeof window !== 'undefined' ? window.innerWidth : 1440);
const isMobile = computed(() => windowWidth.value < 768);

function onResize() {
    windowWidth.value = window.innerWidth;
}
onMounted(() => {
    window.addEventListener('resize', onResize, { passive: true });
});
onBeforeUnmount(() => {
    window.removeEventListener('resize', onResize);
});

function onRowClick(row, e) {
    if (!props.clickable) return;
    // 避免在 checkbox / actions 区域触发
    if (e.target.closest('.check-col, .row-actions, .card-check, .card-actions, a, button')) return;
    emit('row-click', row);
}
function onCellClick(row, col, e) {
    emit('cell-click', { row, col, event: e });
}
</script>

<style scoped>
table.data { width: 100%; border-collapse: collapse; font-size: 14px; }
table.data th, table.data td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--line); }
table.data th { font-weight: 500; color: var(--text-soft); font-size: 12px; text-transform: uppercase; letter-spacing: .04em; }
table.data tr:hover td { background: var(--bg-soft); }
table.data tr:last-child td { border-bottom: 0; }
.check-col { width: 36px; padding-left: 16px; padding-right: 0; }
.row-actions { display: flex; align-items: center; gap: 12px; white-space: nowrap; }

/* === 移动端：卡片 === */
.card-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.card-item {
    background: var(--card);
    border-radius: var(--radius);
    box-shadow: var(--card-shadow);
    padding: 14px 14px 12px;
    display: flex;
    align-items: flex-start;
    gap: 10px;
    transition: box-shadow .15s, transform .1s;
    position: relative;
}
.card-item:active { transform: scale(0.99); }
.card-item.selected {
    background: linear-gradient(0deg, var(--bg-soft), var(--bg-soft)), var(--card);
    box-shadow: 0 0 0 2px var(--brand-soft), var(--card-shadow);
}
.card-check {
    padding-top: 2px;
    flex-shrink: 0;
}
.card-body {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.card-row {
    display: flex;
    align-items: baseline;
    gap: 8px;
    font-size: 13px;
    min-width: 0;
}
.card-row.primary {
    font-size: 15px;
    font-weight: 600;
    color: var(--text);
}
.card-row.primary .card-label {
    display: none; /* 主行只显值，节省空间 */
}
.card-row.secondary {
    color: var(--text-soft);
    font-size: 13px;
}
.card-label {
    color: var(--text-mute);
    font-size: 12px;
    font-weight: 500;
    flex-shrink: 0;
    min-width: 56px;
}
.card-value {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    word-break: break-word;
}
.card-actions {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 4px;
    align-self: center;
}
.card-empty {
    text-align: center;
    padding: 48px 16px;
    background: var(--card);
    border-radius: var(--radius);
    box-shadow: var(--card-shadow);
}

/* === 响应式 === */
@media (max-width: 767px) {
    /* 卡片样式下，按钮变得更易点 */
    .card-actions :deep(.btn) {
        padding: 6px 10px;
        font-size: 13px;
    }
    .card-actions :deep(.btn-link) {
        padding: 6px 8px;
        min-width: 32px;
        min-height: 32px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }
}
</style>
