<template>
  <div
    class="vc-skeleton-loader w-full h-full animation-block"
    :style="styles"
    v-bind="$attrs"
  >
    <component
      :is="loaderType"
      :row-height="heightRows"
      :cols="colsCount"
      v-bind="additionalAttrs"
    />
  </div>
</template>

<script lang="ts">
import { defineComponent, PropType } from 'vue'
import Card from '@/components/VcSkeletonLoader/Loaders/Card.vue'
import Row from '@/components/VcSkeletonLoader/Loaders/Row.vue'
import Square from '@/components/VcSkeletonLoader/Loaders/Square.vue'
import Text from '@/components/VcSkeletonLoader/Loaders/Text.vue'
import Circle from '@/components/VcSkeletonLoader/Loaders/Circle.vue'
import { convertToUnit } from '@/utils/helpers'
import { LoaderType } from '@/components/VcSkeletonLoader/VcSkeletonLoader.types'

type NumberOrNumberString = PropType<string | number | undefined>

const DEFAULT_TYPE = 'row'
const DEFAULT_HEIGHT = '1.5rem'

export default defineComponent({
  name: 'VcSkeletonLoader',
  components: {
    Card,
    Row,
    Square,
    Text,
    Circle
  },
  props: {
    height: {
      type: [Number, String] as NumberOrNumberString,
      default: undefined
    },
    width: {
      type: [Number, String] as NumberOrNumberString,
      default: undefined
    },
    maxWidth: {
      type: [Number, String] as NumberOrNumberString,
      default: undefined
    },
    maxHeight: {
      type: [Number, String] as NumberOrNumberString,
      default: undefined
    },
    type: {
      type: String,
      default: DEFAULT_TYPE
    },
    rowHeight: {
      type: [Number, String] as NumberOrNumberString,
      default: DEFAULT_HEIGHT
    },
    textLoading: {
      type: String,
      default: ''
    }
  },
  computed: {
    styles () {
      const styles: Record<string, string> = {}

      const height = convertToUnit(this.height)
      const width = convertToUnit(this.width)
      const maxHeight = convertToUnit(this.maxHeight)
      const maxWidth = convertToUnit(this.maxWidth)

      if (height) styles.height = height
      if (maxHeight) styles.maxHeight = maxHeight
      if (maxWidth) styles.maxWidth = maxWidth
      if (width) styles.width = width

      return styles
    },
    heightRows () {
      return convertToUnit(this.rowHeight)
    },
    loaderType () {
      const [type] = this.type.split('@') as [LoaderType, number]
      return type
    },
    colsCount () {
      const [type, len] = this.type.split('@') as [LoaderType, number]
      if (type === 'square' || type === 'circle') {
        return +len || 1
      }
      return undefined
    },
    additionalAttrs () {
      if (this.type === 'text') {
        return {
          text: this.textLoading
        }
      }
      return {}
    }
  }
})
</script>
