<script setup lang="ts">
import type { KbxAsyncState } from '@kbx/contracts'
import KbxButton from './KbxButton.vue'

const props = withDefaults(defineProps<{
  state: Exclude<KbxAsyncState, 'ready'>
  title?: string
  detail?: string
  actionLabel?: string
  compact?: boolean
}>(), { title:'', detail:'', actionLabel:'', compact:false })

const emit = defineEmits<{ action:[] }>()

const defaults = {
  idle: { title:'조회 전입니다.', detail:'조회조건을 확인한 후 조회하세요.' },
  loading: { title:'조회 중...', detail:'잠시 후 결과를 표시합니다.' },
  empty: { title:'조회된 데이터가 없습니다.', detail:'조회조건을 변경하거나 다시 조회하세요.' },
  error: { title:'데이터를 불러오지 못했습니다.', detail:'네트워크 연결과 조회조건을 확인한 후 다시 시도하세요.' },
} as const
</script>

<template>
  <section class="kbx-data-state" :class="{compact}" :data-state="state" :aria-busy="state==='loading'" :role="state==='error'?'alert':'status'">
    <div class="kbx-data-state__mark" aria-hidden="true">{{ state==='loading' ? '…' : state==='empty' ? '—' : state==='idle' ? '○' : '!' }}</div>
    <div class="kbx-data-state__body">
      <strong>{{ title || defaults[state].title }}</strong>
      <span v-if="detail || defaults[state].detail">{{ detail || defaults[state].detail }}</span>
    </div>
    <KbxButton v-if="actionLabel" :label="actionLabel" variant="secondary" @click="emit('action')" />
  </section>
</template>

<style scoped>
.kbx-data-state{min-height:var(--kbx-data-state-min-height);display:flex;align-items:center;justify-content:center;gap:var(--kbx-space-3);padding:var(--kbx-space-5);border:var(--kbx-border-width) solid var(--kbx-color-border);background:var(--kbx-color-surface);text-align:left}.kbx-data-state.compact{min-height:var(--kbx-control-lg);justify-content:flex-start;padding:var(--kbx-space-2) var(--kbx-space-3)}.kbx-data-state__mark{width:var(--kbx-control-sm);height:var(--kbx-control-sm);display:grid;place-items:center;border-radius:var(--kbx-radius-pill);background:var(--kbx-color-surface-muted);font-weight:700;color:var(--kbx-color-text-muted)}.kbx-data-state[data-state="idle"] .kbx-data-state__mark,.kbx-data-state[data-state="loading"] .kbx-data-state__mark{background:var(--kbx-color-info-surface);color:var(--kbx-color-primary)}.kbx-data-state[data-state="error"] .kbx-data-state__mark{background:var(--kbx-color-danger-surface);color:var(--kbx-color-danger)}.kbx-data-state__body{display:flex;flex-direction:column;gap:var(--kbx-space-1);min-width:0}.kbx-data-state__body strong{font-size:var(--kbx-font-md)}.kbx-data-state__body span{font-size:var(--kbx-font-sm);color:var(--kbx-color-text-muted)}.kbx-data-state.compact .kbx-data-state__body span{display:none}
</style>
