<template>
  <div
    class="absolute w-686px h-615px cursor-pointer scale-75"
    :style="{ left: x + 'px', top: y + 'px' }"
    v-bind="$attrs"
  >
    <img
      v-if="type === 'Park'"
      src="@/assets/images/park-hotspot.svg"
      class="absolute bottom-16px left-1/2 translate-x--1/2"
      :class="parkCode ? '' : 'breath-animation'"
      alt=""
    />
    <img
      v-else
      src="@/assets/images/hotel-hotspot.svg"
      class="absolute bottom-16px left-1/2 translate-x--1/2"
      :class="parkCode ? '' : 'breath-animation'"
      alt=""
    />
    <div class="text-center leading-34px flex justify-center gap-16px">
      <span class="flex-1 text-right" :style="{ color: colors[0] }">
        <span class="text-20px">Yest</span>
        <span class="text-24px">{{ dataSource?.gssYesterday ?? 'N/A' }}</span>
      </span>
      <span class="flex-1 text-left" :style="{ color: colors[1] }">
        <span class="text-20px">Yest</span>
        <span class="text-24px">{{ dataSource?.npsYesterday ?? 'N/A' }}</span>
      </span>
    </div>
    <div class="text-center leading-42px flex justify-center gap-16px">
      <span class="flex-1 text-right" :style="{ color: colors[0] }">
        <span class="text-24px">GSS</span>
        <span class="text-30px">{{ dataSource?.gss ?? 'N/A' }}</span>
      </span>
      <span class="flex-1 text-left" :style="{ color: colors[1] }">
        <span class="text-24px">NPS</span>
        <span class="text-30px">{{ dataSource?.nps ?? 'N/A' }}</span>
      </span>
    </div>
    <div class="flex flex justify-center gap-16px">
      <div class="bar-track" :style="{ borderColor: colors[0] }">
        <div
          class="inner-bar"
          :style="{
            height: '50%',
            background: `linear-gradient(to top , ${colors[0] + '00'} 0%, ${colors[0]} 100%)`,
          }"
        ></div>
      </div>
      <div class="bar-track" :style="{ borderColor: colors[1] }">
        <div
          class="inner-bar"
          :style="{
            height: '50%',
            background: `linear-gradient(to top , ${colors[1] + '00'} 0%, ${colors[1]} 100%)`,
          }"
        ></div>
      </div>
    </div>

    <div class="absolute top-359px left-381px">
      <div class="text-24px leading-34px">Attendance</div>
      <div v-if="type === 'Park'" class="text-22px leading-31px" :style="{ color: colors[0] }">
        Visitors in park: {{ dataSource?.visitorInPark ?? 0 }}
      </div>
      <div v-else class="text-22px leading-31px" :style="{ color: colors[0] }">
        Check in: {{ dataSource?.checkIn ?? 'N/A' }}
      </div>
    </div>

    <div class="absolute top-449px left-381px">
      <div v-if="type === 'Park'" class="text-22px leading-31px" :style="{ color: colors[1] }">
        Total attendance: {{ dataSource?.totalAttendance ?? 0 }}
      </div>
      <div v-else class="text-22px leading-31px" :style="{ color: colors[1] }">
        Booking:{{ dataSource?.booking ?? 'N/A' }}
      </div>
    </div>

    <div class="absolute bottom-12px left-1/2 translate-x--1/2 text-32px leading-45px">
      {{ code }}
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, defineProps, withDefaults, inject, ref } from 'vue';
import { Receiver } from '@/utils/sseReceiver';
import { getIDBData } from '@/utils/database';

interface IHotelData {
  booking: number;
  checkIn: number;
  datetime: string;
  gss: number;
  gssYesterday: number;
  hotelCode: string;
  id: number;
  nps: number;
  npsYesterday: number;
  syncTraceId: string;
  synchTime: string;
  visitorInPark: number;
  totalAttendance: number
}

const props = withDefaults(
  defineProps<{
    type: 'Park' | 'Hotel';
    code: string;
    x: number;
    y: number;
  }>(),
  {
    type: 'Park',
    value: 0,
  },
);

const parkCode = inject('parkCode');
const dataSource = ref<IHotelData>();

const colors = computed(() => {
  return props.type === 'Park' ? ['#69FEAD', '#79F3FF'] : ['#FFBE44', '#E6F89A'];
});

// 获取数据
const setData = (module?: string) => {
  if(module === `${props.type} map chart style${props.code}` || !module) {
    getIDBData(`${props.type} map chart style${props.code}`).then((res) => {
      dataSource.value = res?.value;
    });
  }
};

setData();
// 获取websoket
const ws = Receiver.getInstance(import.meta.env.VITE_APP_SOCKET_SERVER + '/kpi/ws/data');
ws.onMessage(async (message) => {
  setData(message.module);
});
</script>

<style lang="less" scoped>
* {
  font-family: PingFangSC-Medium, sans-serif;
}
.bar-track {
  position: relative;
  width: 24px;
  height: 360px;
  border-radius: 24px 24px 0 0;
  border: 2px solid;
  border-bottom: none;
  box-sizing: border-box;
  -webkit-mask-image: linear-gradient(to bottom, black 50%, transparent);
  mask-image: linear-gradient(to bottom, black 50%, transparent);

  .inner-bar {
    width: 100%;
    height: 0%;
    position: absolute;
    bottom: 0;
    left: 0;
    border-radius: 24px 24px 0 0;
  }
}

// 图片呼吸效果
@keyframes breath {
  0% {
    transform: scale(1) translateX(-50%);
  }
  50% {
    transform: scale(1.1) translateX(-45%);
  }
  100% {
    transform: scale(1) translateX(-50%);
  }
}

.breath-animation {
  animation: breath 3s infinite ease-in-out;
}
</style>
