<script setup lang="ts" generic="T extends AnyObject">
import { UnwrapRef } from 'vue'

const props = withDefaults(
  defineProps<{
    request?: (query: Partial<T>) => Promise<IResData<T[]>>
    items?: T[]
    query?: Partial<T>
    automatic?: boolean
    mockList?: Partial<T>[]
    contentClass?: string
  }>(),
  {
    automatic: true,
    query: () => ({}),
    contentClass: 'flex flex-col',
  },
)
const slot = defineSlots<{
  default(props: { item: UnwrapRef<T>; index: number; isLast: boolean }): any
}>()
const request = computed(() => {
  if (props.request) {
    return props.request
  } else {
    return async () => {
      return { code: 0, msg: '', data: props.items }
    }
  }
})
const { data, run: setData } = useRequest(() => request.value({ ...props.query }), {
  immediate: false,
})
onMounted(async () => {
  if (props.mockList) {
    data.value = props.mockList as T[]
    return
  }
  if (props.automatic) {
    await setData()
  }
})
watch(
  () => props.query,
  async () => {
    if (props.mockList) {
      data.value = props.mockList as T[]
      return
    }
    await setData()
  },
)
defineExpose({
  reload: async () => {
    await setData()
  },
})
</script>

<template>
  <div class="flex-grow relative flex flex-col">
    <div :class="contentClass">
      <template v-for="(it, index) in data" :key="index">
        <slot
          :item="it as UnwrapRef<T>"
          :index="index"
          :isLast="index == (data?.length ?? 0) - 1"
        ></slot>
      </template>
    </div>
    <div
      v-if="mockList"
      class="construction-dashed absolute top-0 right-0 left-0 bottom-0 bg-red/20 flex items-center justify-center pointer-events-none"
    >
      <div class="text-16 text-black/30">Debug</div>
    </div>
  </div>
</template>

<style scoped lang="scss">
//@layer utilities {
.construction-dashed {
  @apply border-4 border-black/50 border-dashed; /* 基础虚线样式 */
  animation: dashed-move 2s linear infinite; /* 虚线移动动画 */
}
//}
@keyframes dashed-move {
  from {
    border-spacing: 0;
  }
  to {
    border-spacing: 10px;
  }
}
</style>