<template>
  <view class="badge" :class="customClass">
    <slot></slot>
    <view
      v-show="showBadge"
      class="badge__content"
      :class="[
        {
          'badge__content--dot': isDot,
          'badge__content--fixed': !$slots.default,
        },
        customContentClass,
      ]"
      :style="badgeStyle"
    >
      <block v-if="!isDot">{{ finalContent }}</block>
    </view>
  </view>
</template>

<script lang="ts" setup>
import { computed } from 'vue'

const props = defineProps({
  value: {
    type: [String, Number],
    default: '',
  },
  max: {
    type: Number,
    default: 99,
  },
  isDot: {
    type: Boolean,
    default: false,
  },
  hidden: {
    type: Boolean,
    default: false,
  },
  bgColor: {
    type: String,
    default: '#ff4d4f',
  },
  color: {
    type: String,
    default: '#fff',
  },
  customClass: {
    type: String,
    default: '',
  },
  customContentClass: {
    type: String,
    default: '',
  },
})

// 是否显示徽标
const showBadge = computed(() => {
  return !props.hidden && (props.isDot || content.value)
})

// 是否有内容需要显示
const content = computed(() => {
  return props.value !== '' && props.value !== undefined && props.value !== null
})

// 计算最终显示的内容
const finalContent = computed(() => {
  if (!content.value) return ''

  if (typeof props.value === 'number' || !isNaN(Number(props.value))) {
    const value = Number(props.value)
    const result = value > props.max ? `${props.max}+` : value

    return result
  }

  return String(props.value)
})

// 计算徽标样式
const badgeStyle = computed(() => {
  const style: Record<string, string> = {
    backgroundColor: props.bgColor,
    color: props.color,
  }
  return style
})
</script>

<style lang="scss" scoped>
.badge {
  position: relative;
  display: inline-flex;
  vertical-align: middle;
  // 定义默认变量
  --badge-size: 32rpx;
  --badge-font-size: 20rpx;
  --badge-dot-size: 16rpx;

  &__content {
    position: absolute;
    top: 8rpx;
    right: 8rpx;
    transform: translate(50%, -50%);
    transform-origin: 100% 0%;
    z-index: 10;
    min-width: var(--badge-size);
    height: var(--badge-size);
    padding: 0 8rpx;
    color: #fff;
    font-size: var(--badge-font-size);
    line-height: var(--badge-size);
    white-space: nowrap;
    text-align: center;
    background-color: #ff4d4f;
    border-radius: calc(var(--badge-size) / 2);
    box-shadow: 0 0 0 2rpx #fff;

    &--dot {
      width: var(--badge-dot-size);
      height: var(--badge-dot-size);
      padding: 0;
      min-width: auto;
      border-radius: 50%;
    }

    &--fixed {
      position: relative;
      transform: none;
    }
  }
}
</style>
