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

const props = withDefaults(defineProps<{
  problem: KbxProblem
  allowedActionIds?: readonly string[]
  dismissible?: boolean
}>(), {
  allowedActionIds: () => [],
  dismissible: true,
})

const emit = defineEmits<{ action:[string]; retry:[]; dismiss:[] }>()

const kindLabel: Record<KbxProblem['type'], string> = {
  validation: '입력 오류',
  'business-rule': '업무 규칙',
  conflict: '동시 수정',
  permission: '권한',
  'not-found': '데이터',
  integration: '외부 연계',
  system: '시스템',
}

const tone = computed(() => {
  if (props.problem.type === 'permission' || props.problem.type === 'system') return 'danger'
  if (props.problem.type === 'integration') return props.problem.retryable ? 'warning' : 'danger'
  if (props.problem.type === 'business-rule' || props.problem.type === 'conflict') return 'warning'
  return 'info'
})
const retryable = computed(() => (props.problem.type === 'integration' || props.problem.type === 'system') && props.problem.retryable === true)
const allowed = computed(() => new Set(props.allowedActionIds))
const actions = computed(() => props.problem.type === 'business-rule'
  ? (props.problem.actions ?? []).filter(action => allowed.value.has(action.id))
  : [])
</script>

<template>
  <section class="kbx-problem-feedback" :data-tone="tone" :data-problem-type="problem.type" role="alert" aria-live="assertive">
    <div class="kbx-problem-feedback__copy">
      <div class="kbx-problem-feedback__heading">
        <span class="kbx-problem-feedback__kind">{{ kindLabel[problem.type] }}</span>
        <strong>{{ problem.title }}</strong>
      </div>
      <p v-if="problem.detail">{{ problem.detail }}</p>
      <ul v-if="problem.type === 'validation' && problem.errors.length" class="kbx-problem-feedback__validation">
        <li v-for="error in problem.errors.slice(0,3)" :key="`${error.rowKey ?? ''}:${error.field ?? ''}:${error.code}`">{{ error.message }}</li>
        <li v-if="problem.errors.length > 3">외 {{ problem.errors.length - 3 }}건의 입력 오류가 있습니다.</li>
      </ul>
      <small v-if="problem.correlationId">참조번호 {{ problem.correlationId }}</small>
    </div>
    <div class="kbx-problem-feedback__actions">
      <KbxButton v-for="action in actions" :key="action.id" :label="action.label" variant="secondary" @click="emit('action', action.id)" />
      <KbxButton v-if="retryable" label="다시 시도" variant="secondary" @click="emit('retry')" />
      <KbxButton v-if="dismissible" label="닫기" variant="ghost" @click="emit('dismiss')" />
    </div>
  </section>
</template>

<style scoped>
.kbx-problem-feedback{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--kbx-space-3);padding:var(--kbx-space-3);border:var(--kbx-border-width) solid var(--kbx-color-info-border);border-left:var(--kbx-accent-border-width) solid var(--kbx-color-primary);background:var(--kbx-color-info-surface)}
.kbx-problem-feedback[data-tone="warning"]{border-color:var(--kbx-color-warning-border);border-left-color:var(--kbx-color-warning);background:var(--kbx-color-warning-surface)}
.kbx-problem-feedback[data-tone="danger"]{border-color:var(--kbx-color-danger-border);border-left-color:var(--kbx-color-danger);background:var(--kbx-color-danger-surface)}
.kbx-problem-feedback__copy{min-width:0;display:grid;gap:var(--kbx-space-1)}
.kbx-problem-feedback__heading{display:flex;align-items:center;flex-wrap:wrap;gap:var(--kbx-space-2)}
.kbx-problem-feedback__kind{font-size:var(--kbx-font-xs);font-weight:600;color:var(--kbx-color-text-muted)}
.kbx-problem-feedback p,.kbx-problem-feedback small{margin:0;color:var(--kbx-color-text-muted);font-size:var(--kbx-font-sm);line-height:1.5}.kbx-problem-feedback__validation{margin:var(--kbx-space-1) 0 0;padding-left:var(--kbx-space-5);color:var(--kbx-color-text);font-size:var(--kbx-font-sm)}
.kbx-problem-feedback__actions{display:flex;align-items:center;justify-content:flex-end;flex-wrap:wrap;gap:var(--kbx-space-1)}
@media(max-width:48rem){.kbx-problem-feedback{flex-direction:column}.kbx-problem-feedback__actions{width:100%;justify-content:flex-start}}
</style>
