<script setup lang="ts">
/**
 * Alert — contextual inline alert strip.
 * Tones: info | warn | danger | online | accent | neutral.
 * Pass `title` for a bold heading, default slot for body text, `actions` slot
 * for inline action buttons. Set `dismissible` to show an × ghost button that
 * emits `dismiss`.
 */
import Icon from '@/components/ds/core/Icon.vue'

type Tone = 'info' | 'warn' | 'danger' | 'online' | 'accent' | 'neutral'

const ICONS: Record<Tone, string> = {
  info: 'info',
  warn: 'triangle-alert',
  danger: 'octagon-alert',
  online: 'circle-check',
  accent: 'sparkles',
  neutral: 'info',
}

const props = withDefaults(
  defineProps<{
    tone?: Tone
    title?: string
    dismissible?: boolean
    icon?: string
  }>(),
  { tone: 'info', dismissible: false },
)

defineEmits<{ dismiss: [] }>()
</script>

<template>
  <div
    :class="['cc-alert', 'cc-alert--' + tone]"
    role="status"
  >
    <span class="cc-alert__icon">
      <Icon :name="icon ?? ICONS[tone]" :size="17" :stroke-width="2" />
    </span>
    <div class="cc-alert__main">
      <div v-if="title" class="cc-alert__title">{{ title }}</div>
      <div v-if="$slots.default" class="cc-alert__body"><slot /></div>
      <div v-if="$slots.actions" class="cc-alert__actions"><slot name="actions" /></div>
    </div>
    <button
      v-if="dismissible"
      class="cc-alert__dismiss"
      type="button"
      aria-label="Dismiss"
      @click="$emit('dismiss')"
    >
      <Icon name="x" :size="15" :stroke-width="2.25" />
    </button>
  </div>
</template>

<style>
.cc-alert { display:flex; gap:11px; padding:12px 13px; border-radius:var(--radius-md); background:var(--surface-raised); box-shadow:var(--ring-default); }
.cc-alert__icon { flex:none; margin-top:1px; }
.cc-alert__main { flex:1; min-width:0; display:flex; flex-direction:column; gap:3px; }
.cc-alert__title { font-size:var(--text-sm); font-weight:600; color:var(--text-primary); }
.cc-alert__body { font-size:var(--text-xs); color:var(--text-secondary); line-height:1.5; }
.cc-alert__actions { display:flex; gap:8px; margin-top:8px; }
.cc-alert--info { background:var(--status-info-soft); box-shadow: inset 0 0 0 1px var(--status-info-border); }
.cc-alert--info .cc-alert__icon { color:var(--status-info); }
.cc-alert--warn { background:var(--status-warn-soft); box-shadow: inset 0 0 0 1px var(--status-warn-border); }
.cc-alert--warn .cc-alert__icon { color:var(--status-warn); }
.cc-alert--danger { background:var(--status-offline-soft); box-shadow: inset 0 0 0 1px var(--status-offline-border); }
.cc-alert--danger .cc-alert__icon { color:var(--status-offline); }
.cc-alert--online { background:var(--status-online-soft); box-shadow: inset 0 0 0 1px var(--status-online-border); }
.cc-alert--online .cc-alert__icon { color:var(--status-online); }
.cc-alert--accent { background:var(--accent-soft); box-shadow: inset 0 0 0 1px var(--accent-border); }
.cc-alert--accent .cc-alert__icon { color:var(--accent-text); }
.cc-alert__dismiss {
  flex: none; display:inline-flex; align-items:center; justify-content:center;
  width:26px; height:26px; border-radius:var(--radius-sm); border:none; cursor:pointer;
  background:transparent; color:var(--text-secondary);
  transition: var(--transition-colors);
  margin-top:-3px; margin-right:-3px;
}
.cc-alert__dismiss:hover { background:var(--surface-hover); color:var(--text-primary); }
.cc-alert__dismiss:focus-visible { outline:none; box-shadow:var(--focus-ring); }
</style>
