<template>
  <div class="q-px-xs">
    <div v-if="!isLoaded" class="spinner flex flex-center">
      <q-spinner color="primary" size="3em" />
    </div>
    <q-table v-else class="app-table" :selection="type" row-key="id" v-model:selected="selected" flat bordered
      virtual-scroll :columns="columns" :rows="rows" :pagination="pagination" :rows-per-page-options="[0]"
      :filter="filter" style="max-height: 65vh;" @update:selected="emitSelected">

      <template v-for="col in columns" :key="col.name" v-slot:[`body-cell-${col.name}`]="props">
        <q-td :props="props">
          <!-- 使用动态插槽名称 -->
          <slot v-if="col.name !== detailField" :name="`body-cell-${col.name}`" :row="props.row" :column="props.col">
            <!-- 默认内容 -->
            <span>{{ props.row[col.name] }}</span>
          </slot>
          <q-scroll-area v-else class="description-cell">
            <div v-html="props.row[detailField]"></div>
          </q-scroll-area>
        </q-td>
      </template>

    </q-table>
  </div>
</template>

<script lang="ts">
import { ref, onMounted, reactive, PropType } from 'vue'

interface IRow {
  [key: string]: any;
}

export default {
  name: 'DetailFieldTable',
  props: {
    name: String,
    type: String,
    filter: String,
    detailField: {
      type: String,
      required: true
    },
    columns: {
      type: Array as PropType<any[]>,
      required: true
    },
    fetchData: {
      type: Function as PropType<() => Promise<IRow[]>>,
      required: true
    },
    sortBy: {
      type: String,
      required: false
    },
    sortDesc: {
      type: Boolean,
      required: false
    }
  },
  emits: ['update:selected'],
  setup(props, { emit }) {
    const isLoaded = ref(false);
    const rows = reactive<IRow[]>([]);
    const selected = ref([]);

    onMounted(async () => {
      const data = await props.fetchData();
      rows.push(...data);
      isLoaded.value = true;
    });

    const emitSelected = (selectedItems: any[]) => {
      emit('update:selected', selectedItems);
    };

    return {
      rows,
      selected,
      isLoaded,
      pagination: ref({
        sortBy: props.sortBy || undefined,
        descending: props.sortDesc || undefined,
        rowsPerPage: 10
      }),
      emitSelected
    };
  }
};
</script>

<style lang="scss">
.description-cell {
  height: 60px;
  width: 300px;
  max-height: 60px;
  max-width: 300px;
  white-space: break-spaces;
}

.spinner {
  min-height: 300px;
  min-width: 400px;
}
</style>