<template>
  <div class="nv-badge" :class="[
      { 'nv-badge--inline': inline },
      { 'nv-badge--rounded': rounded },
      { 'nv-badge--tile': tile },
      { 'nv-badge--bordered': bordered },
      !customSize ? sizeableClasses : undefined
      ]">
    <div class="nv-badge__wrapper">
      <slot/>
      <!-- ToDo: добавить Transition -->
      <div v-show="modelValue" class="nv-badge__badge" :class="badgeClasses"
           :style="{...locationStyles, minWidth: customSize, height: customSize}">
        <template v-if="$slots.badge">{{ $slots.badge?.() }}</template>
        <template v-else-if="icon">
          <NvIcon :icon="icon" size="1em"/>
        </template>
        <template v-else><span class="v-badge__content">{{ displayedContent }}</span></template>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import {computed} from 'vue'
import useSize, {useSizeProps} from "../../composables/sizeable";
import {convertToUnit} from './../../utils/helpers'
import {log} from "util";

export default {
  props: {
    content: [String, Number],
    inline: Boolean,
    rounded: Boolean,
    tile: Boolean,
    bordered: Boolean,
    floating: Boolean,
    icon: String,
    location: {
      type: String,
      default: 'top-right',
      validator: (value: string) => {
        const [vertical, horizontal] = (value ?? '').split('-')

        return (
            ['top', 'bottom'].includes(vertical) &&
            ['left', 'right'].includes(horizontal)
        )
      },
    },
    max: [Number, String],
    modelValue: {
      type: Boolean,
      default: true,
    },
    offsetX: [Number, String],
    offsetY: [Number, String],
    badgeClasses: [String, Array, Object],
    ...useSizeProps,
  },

  setup(props: any) {
    const {sizeableClasses, customSize} = useSize(props);

    const displayedContent = computed(() => {
      const value = Number(props.content)

      return (!props.max || isNaN(value)) ? props.content
          : value <= props.max ? value
              : `${props.max}+`
    })


    const position = computed(() => {
      return props.floating ? '100%' : '0em'
    })

    function calculatePosition(offset?: number | string) {
      return `calc(${convertToUnit(offset) || '0px'} + ${position.value})`
    }

    const locationStyles = computed(() => {
      const [vertical, horizontal] = (props.location ?? '').split('-')

      const styles = {
        bottom: 'auto',
        left: 'auto',
        right: 'auto',
        top: 'auto',
      }
      if (!props.inline) {
        if (horizontal === 'left') {
          styles[props.floating ? 'right' : 'left'] = calculatePosition(props.offsetX)
        } else {
          styles[props.floating ? 'left' : 'right'] = calculatePosition(props.offsetX)
        }

        if (vertical === 'top') {
          styles[props.floating ? 'bottom' : 'top'] = calculatePosition(props.offsetY)
        } else {
          styles[props.floating ? 'top' : 'bottom'] = calculatePosition(props.offsetY)
        }
      }

      return styles
    })

    return {
      sizeableClasses,
      customSize,
      locationStyles,
      displayedContent
    }
  }
};
</script>
