<template>
  <div
    :class="containerClass"
    role="alert"
    aria-live="assertive"
    aria-atomic="true"
  >
    <div
      class="vc-toast-message-content"
      :class="message.contentStyleClass"
    >
      <span
        :class="iconClass"
        class="icon-2r"
      />
      <div class="vc-toast-message-text">
        <template v-if="!message.component">
          <span class="vc-toast-summary">
            {{ message.title }}
          </span>
          <div class="vc-toast-detail">
            {{ message.message }}
          </div>
        </template>
        <component
          :is="message.component"
          v-else
          :message="message"
          v-bind="message.componentAttrs"
          @close="onCloseClick"
        />
      </div>
      <button
        v-if="isClosable"
        class="vc-toast-icon-close"
        type="button"
        @click="onCloseClick"
      >
        <span class="vc-icon-close icon-base" />
      </button>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent, PropType } from 'vue'
import { ToastMessageOptions } from './VcNotification.types'

const DEFAULT_DURATION = 4500

export default defineComponent({
  name: 'VcNotificationMessage',
  props: {
    message: {
      type: Object as PropType<ToastMessageOptions> | null | undefined,
      default: null
    }
  },
  emits: ['close'],
  data () {
    return {
      closeTimeout: null as number | null
    }
  },
  computed: {
    containerClass (): ({[key: string]: boolean} | string)[] {
      return [
        'vc-toast-message', this.message?.styleClass || '',
        {
          'vc-toast-message-info': this.message.type === 'info',
          'vc-toast-message-warn': this.message.type === 'warning',
          'vc-toast-message-error': this.message.type === 'error',
          'vc-toast-message-success': this.message.type === 'success'
        }
      ]
    },
    iconClass () {
      return ['vc-toast-message-icon',
        {
          'vc-icon-info': this.message.type === 'info',
          'vc-icon-alert': this.message.type === 'warning',
          'vc-icon-cross': this.message.type === 'error',
          'vc-icon-checkmark': this.message.type === 'success'
        }
      ]
    },
    isClosable () {
      return this.message?.closable !== false || this.message?.duration === 0
    }
  },
  mounted () {
    const duration = this.message?.duration === undefined ? DEFAULT_DURATION : this.message?.duration
    if (duration) {
      this.closeTimeout = window.setTimeout(() => {
        this.close()
      }, duration)
    }
  },
  beforeUnmount () {
    this.clearCloseTimeout()
  },
  methods: {
    onCloseClick (): void {
      this.clearCloseTimeout()
      this.close()
    },
    close () {
      this.$emit('close', this.message)
    },
    clearCloseTimeout () {
      if (this.closeTimeout) {
        clearTimeout(this.closeTimeout)
        this.closeTimeout = null
      }
    }
  }
})
</script>
