<template>
  <div class="async-state">
    <!-- Loading -->
    <div v-if="loading" class="async-state__skeleton">
      <div v-for="n in skeletonRows" :key="n" class="async-state__skeleton-row" :style="{ width: skeletonWidths[(n - 1) % skeletonWidths.length] }"></div>
    </div>

    <!-- Error -->
    <div v-else-if="error" class="async-state__error">
      <div class="async-state__error-icon">
        <svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
          <circle cx="12" cy="12" r="10"/>
          <line x1="12" y1="8" x2="12" y2="12"/>
          <line x1="12" y1="16" x2="12.01" y2="16"/>
        </svg>
      </div>
      <p class="async-state__error-text">{{ errorMessage || '加载失败' }}</p>
      <el-button v-if="retryable" size="small" @click="$emit('retry')">重试</el-button>
    </div>

    <!-- Empty -->
    <div v-else-if="empty" class="async-state__empty">
      <p class="async-state__empty-text">{{ emptyMessage || '暂无数据' }}</p>
      <p v-if="emptyHint" class="async-state__empty-hint">{{ emptyHint }}</p>
    </div>

    <!-- Content -->
    <slot v-else />
  </div>
</template>

<script setup>
defineProps({
  loading: { type: Boolean, default: false },
  error: { type: Boolean, default: false },
  empty: { type: Boolean, default: false },
  errorMessage: { type: String, default: '' },
  emptyMessage: { type: String, default: '' },
  emptyHint: { type: String, default: '' },
  retryable: { type: Boolean, default: true },
  skeletonRows: { type: Number, default: 4 }
})

defineEmits(['retry'])

const skeletonWidths = ['100%', '75%', '90%', '60%']
</script>

<style scoped>
.async-state__skeleton { padding: 16px; }
.async-state__skeleton-row {
  height: 14px;
  background: var(--color-surface-muted, #f3f6f9);
  border-radius: 4px;
  margin-bottom: 10px;
  animation: async-pulse 1.5s ease-in-out infinite;
}
@keyframes async-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.4; }
}
.async-state__error,
.async-state__empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 48px 16px;
  text-align: center;
}
.async-state__error-icon { color: var(--color-text-muted, #8a97a8); margin-bottom: 12px; }
.async-state__error-text { color: var(--color-text-secondary, #5f6b7a); font-size: 13px; margin: 0 0 12px; }
.async-state__empty-text { color: var(--color-text-muted, #8a97a8); font-size: 13px; margin: 0; }
.async-state__empty-hint { color: var(--color-text-muted, #8a97a8); font-size: 11px; margin: 6px 0 0; }
</style>
