<template>
  <div
    :class="[
      cn.b(),
      cn.m(type),
      cn.m(size),
      cn.has('title', hasTitle),
      cn.has('action', hasAction),
    ]"
  >
    <div :class="[cn.e('content')]">
      <div
        v-if="$slots.title || title"
        :class="[cn.e('title')]"
      >
        <slot name="title">
          {{ title }}
        </slot>
      </div>

      <div :class="[cn.e('text')]">
        <slot>{{ text }}</slot>
      </div>

      <slot name="action" />
    </div>

    <div :class="cn.e('icon')">
      <slot name="icon">
        <Component :is="resolveComponent(`ui-icon-${TYPE_ICON_MAPPING[type]}`)" />
      </slot>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed } from 'vue'
import useClassname from '../../composables/use-classname'
import type { AlertProps, AlertType } from './types'
import type { UiIcon } from '#build/types/ui/icons'

defineOptions({
  name: 'UiAlert',
})

const props = withDefaults(defineProps<AlertProps>(), {
  type: 'neutral',
  size: 'normal',
})

const slots = defineSlots<{
  default(props: NonNullable<unknown>): never
  title(props: NonNullable<unknown>): never
  action(props: NonNullable<unknown>): never
}>()

const TYPE_ICON_MAPPING: Record<AlertType, UiIcon> = {
  neutral: 'exclamation-filled',
  positive: 'confirmed-filled',
  warning: 'danger-filled',
  negative: 'cancel-filled',
  marketing: 'ask-for-discount-filled',
}

const cn = useClassname('ui-alert')

const hasTitle = computed(() => !!props.title || slots.title)
const hasAction = computed(() => slots.action)
</script>

<style lang="scss">
@use 'styles';
</style>
