<template>
  <div
    class="count-card"
    :class="{
      'is-counting': isCounting,
      'is-settled': isSettled,
    }"
  >
    <div class="count-card-left">
      <div class="count-card-icon" :class="'icon-' + info.icon"></div>
      <div class="count-card-title">
        <div class="title-zh">{{ info.zh }}</div>
        <div v-if="info.en" class="title-en">{{ toUpper(info.en) }}</div>
      </div>
    </div>
    <div class="count-card-right">
      <div class="value" :key="valueRenderKey">
        <mCountTo
          :startVal="0"
          :endVal="info.value"
          :decimals="info.decimals"
          :duration="countDuration"
          separator=""
          :autoplay="true"
          @mountedCallback="handleCountStart"
          @callback="handleCountComplete"
        ></mCountTo>
      </div>
      <div class="unit">{{ info.unit }}</div>
    </div>
  </div>
</template>
<script setup>
import { computed, onBeforeUnmount, ref, watch } from "vue"
import mCountTo from "@/components/mCountTo/index.js"
const props = defineProps({
  info: {
    type: Object,
    default: () => {
      return {
        icon: "xiaoshoujine",
        zh: "2023年销售金额",
        en: "Sales amount in 2023",
        value: 9500,
        unit: "万元",
        decimals: 0,
      }
    },
  },
})
const isCounting = ref(true)
const isSettled = ref(false)
const valueRenderKey = ref(0)
let settledTimer = null

const countDuration = computed(() => props.info.duration || 1800)

watch(
  () => [props.info.value, props.info.zh],
  () => {
    if (settledTimer) window.clearTimeout(settledTimer)
    isCounting.value = true
    isSettled.value = false
    valueRenderKey.value += 1
  },
  { immediate: true },
)

function toUpper(text) {
  return text.toUpperCase()
}

function handleCountStart() {
  isCounting.value = true
  isSettled.value = false
}

function handleCountComplete() {
  isCounting.value = false
  isSettled.value = true
  if (settledTimer) window.clearTimeout(settledTimer)
  settledTimer = window.setTimeout(() => {
    isSettled.value = false
  }, 900)
}

onBeforeUnmount(() => {
  if (settledTimer) window.clearTimeout(settledTimer)
})
</script>
<style lang="scss">
@keyframes countCardLoadIn {
  0% {
    opacity: 0;
    transform: translateY(12px) scale(0.96);
    filter: blur(1px) brightness(0.82);
  }

  58% {
    opacity: 1;
    transform: translateY(-2px) scale(1.02);
    filter: blur(0) brightness(1.26);
  }

  100% {
    opacity: 1;
    transform: translateY(0) scale(1);
    filter: blur(0) brightness(1);
  }
}

@keyframes countCardValueJump {
  0%,
  100% {
    transform: translateY(0) scale(1);
  }

  35% {
    transform: translateY(-3px) scale(1.045);
  }

  68% {
    transform: translateY(1px) scale(0.99);
  }
}

@keyframes countCardValueSettle {
  0% {
    transform: translateY(0) scale(1);
    filter: brightness(1);
    text-shadow: 0 0 18px rgba(255, 255, 255, 0.7);
  }

  36% {
    transform: translateY(-5px) scale(1.08);
    filter: brightness(1.4);
    text-shadow:
      0 0 14px rgba(255, 255, 255, 0.88),
      0 0 26px rgba(48, 220, 255, 0.52);
  }

  100% {
    transform: translateY(0) scale(1);
    filter: brightness(1);
    text-shadow: 0 0 18px rgba(255, 255, 255, 0.7);
  }
}

@keyframes countCardValueSweep {
  0% {
    transform: translateX(-130%);
    opacity: 0;
  }

  16% {
    opacity: 0.68;
  }

  54% {
    opacity: 0.8;
  }

  100% {
    transform: translateX(130%);
    opacity: 0;
  }
}

.count-card {
  position: relative;
  display: flex;
  align-items: center;
  overflow: visible;

  &:before {
    content: "";
    position: absolute;
    left: -8px;
    right: -8px;
    top: -5px;
    bottom: -5px;
    pointer-events: none;
    background: linear-gradient(100deg, transparent 8%, rgba(48, 220, 255, 0.2) 45%, transparent 72%);
    opacity: 0;
    transform: translateX(-120%);
  }

  &.is-counting:before {
    animation: countCardValueSweep 1.45s ease-in-out infinite;
  }

  &-left {
    display: flex;
    align-items: center;
    animation: countCardLoadIn 0.78s cubic-bezier(0.2, 0.78, 0.22, 1) both;
    animation-delay: 0.04s;
  }
  &-right {
    display: flex;
    align-items: center;
    padding-left: 20px;
    animation: countCardLoadIn 0.82s cubic-bezier(0.2, 0.78, 0.22, 1) both;
    animation-delay: 0.12s;
    .value {
      position: relative;
      display: inline-flex;
      align-items: baseline;
      transform-origin: center bottom;
      font-family: D-DIN;
      font-weight: bold;
      font-size: 28px;
      color: #ffffff;
      letter-spacing: 1px;
      margin-right: 10px;
      text-shadow: 0px 0px 18px rgba(255, 255, 255, 0.7);
      white-space: nowrap;

      &:after {
        content: "";
        position: absolute;
        left: -4px;
        right: -4px;
        bottom: 0;
        height: 2px;
        border-radius: 999px;
        background: linear-gradient(90deg, transparent, rgba(48, 220, 255, 0.72), transparent);
        opacity: 0;
        transform: scaleX(0.2);
        transform-origin: left center;
      }
    }
    .unit {
      font-weight: 500;
      font-size: 12px;
      color: #ffffff;
      padding-top: 15px;
      opacity: 0.5;
      white-space: nowrap;
    }
  }
  &-icon {
    position: relative;
    width: 42px;
    height: 42px;
    margin-right: 10px;
    flex: 0 0 42px;
    background-repeat: no-repeat;
    background-position: center center;
    background-size: contain;
    filter: none;

    &::before,
    &::after {
      content: none;
    }

    &.icon-xiaoshoujine {
      background-image: url("~@/assets/images/icon1.png");
    }

    &.icon-zongxiaoliang {
      background-image: url("~@/assets/images/icon2.png");
    }

    &.icon-stack {
      background-image: url("~@/assets/images/top-stat-icons/stack.png");
    }

    &.icon-area {
      background-image: url("~@/assets/images/top-stat-icons/area.png");
    }

    &.icon-grass-basic {
      background-image: url("~@/assets/images/top-stat-icons/grass-basic.png");
    }

    &.icon-grass-general {
      background-image: url("~@/assets/images/top-stat-icons/grass-general.png");
    }

    &.icon-wetland {
      background-image: url("~@/assets/images/top-stat-icons/wetland.png");
    }

    &.icon-forest {
      background-image: url("~@/assets/images/top-stat-icons/forest.png");
    }

    &.icon-town {
      background-image: url("~@/assets/images/top-stat-icons/town.png");
    }

    &.icon-park {
      background-image: url("~@/assets/images/top-stat-icons/park.png");
    }

    &.icon-yield {
      background-image: url("~@/assets/images/top-stat-icons/yield.png");
    }

    &.icon-project {
      background-image: url("~@/assets/images/top-stat-icons/project.png");
    }

    &.icon-length {
      background-image: url("~@/assets/images/top-stat-icons/length.png");
    }

    &.icon-device {
      background-image: url("~@/assets/images/top-stat-icons/device.png");
    }

    &.icon-certificate {
      background-image: url("~@/assets/images/top-stat-icons/certificate.png");
    }

    &.icon-rate {
      background-image: url("~@/assets/images/top-stat-icons/rate.png");
    }

    &.icon-leaf {
      background-image: url("~@/assets/images/top-stat-icons/leaf.png");
    }

    &.icon-risk {
      background-image: url("~@/assets/images/top-stat-icons/risk.png");
    }
  }
  &-title {
    .title-zh {
      font-weight: bold;
      font-size: 18px;
      color: #ffffff;
      white-space: nowrap;
    }
    .title-en {
      font-family: D-DIN;
      font-weight: 400;
      font-size: 12px;
      color: #ffffff;
      opacity: 0.5;
      padding-top: 5px;
      white-space: nowrap;
    }
  }

  &.is-counting {
    .count-card-icon {
      filter: none;
    }

    .count-card-right .value {
      animation: countCardValueJump 0.58s ease-in-out infinite;

      &:after {
        opacity: 0.58;
        transform: scaleX(1);
        transition: transform 1.2s ease, opacity 0.2s ease;
      }
    }
  }

  &.is-settled {
    .count-card-right .value {
      animation: countCardValueSettle 0.72s cubic-bezier(0.16, 0.86, 0.24, 1) both;
    }
  }
}
</style>
