<script setup lang="ts">
import type { NdmNvrDiagInfo } from '@/apis';
import { NCard, NDescriptions, NDescriptionsItem, NFlex, NPopover, NProgress, NTag, useThemeVars, type ProgressProps, type TagProps } from 'naive-ui';
import { computed, toRefs } from 'vue';

const props = defineProps<{
  diskHealth: NonNullable<NdmNvrDiagInfo['info']>['diskHealth'];
  diskArray: NonNullable<NdmNvrDiagInfo['info']>['groupInfoList'];
}>();

const themeVars = useThemeVars();

const { diskHealth, diskArray } = toRefs(props);

const hasDiskHealth = computed(() => !!diskHealth.value && diskHealth.value.length > 0);
const hasDiskArray = computed(() => !!diskArray.value && diskArray.value.length > 0);
const showCard = computed(() => hasDiskHealth.value || hasDiskArray.value);

const healthList = computed(() => diskHealth.value ?? []);
const arrayList = computed(() => diskArray.value ?? []);

const getDiskHealthClassName = (health: number) => {
  if (health === 0) return 'disk-healthy';
  if (health === 1) return 'disk-warning';
  return 'disk-error';
};

const getDiskHealthText = (health: number) => {
  if (health === 0) return '正常';
  if (health === 1) return '警告';
  return '故障';
};

const getArrayTagType = (state?: number): TagProps['type'] => {
  if (state === 1) return 'success';
  return 'error';
};

const formatArraySize = (megabytes: number): string => {
  const units = ['MB', 'GB', 'TB'];
  let index = 0;
  while (megabytes >= 1024 && index < units.length - 1) {
    megabytes /= 1024;
    index++;
  }
  return `${megabytes.toFixed(2)} ${units[index]}`;
};

const getArrayUsagePercentage = (freeSize: number, totalSize: number) => {
  if (totalSize === 0) return 0;
  return Math.round(((totalSize - freeSize) / totalSize) * 100);
};

const getArrayProgressStatus = (percentage: number): ProgressProps['status'] => {
  if (percentage >= 90) return 'error';
  if (percentage >= 70) return 'warning';
  return 'success';
};
</script>

<template>
  <NCard v-if="showCard" hoverable size="small">
    <template #header>
      <span>磁盘状态</span>
    </template>
    <template #default>
      <NFlex vertical>
        <NCard v-if="hasDiskHealth" size="small">
          <template #header>
            <div style="font-size: small">磁盘健康状态（{{ healthList.length }}个硬盘槽位）</div>
          </template>
          <template #default>
            <div style="display: grid; grid-template-rows: repeat(3, auto)" :style="{ 'grid-template-columns': `repeat(${Math.max(healthList.length / 3, 12)}, 1fr)` }">
              <template v-for="(health, index) in healthList" :key="index">
                <NPopover :delay="300">
                  <template #trigger>
                    <!-- 最外层div宽度100% -->
                    <div class="disk-health" style="height: 40px; box-sizing: border-box; display: flex; cursor: pointer" :class="getDiskHealthClassName(health)">
                      <!-- 将磁盘号和状态指示器包裹起来 用于居中布局 -->
                      <div style="margin: auto; display: flex; flex-direction: column; align-items: center">
                        <div style="font-size: xx-small">{{ index + 1 }}</div>
                        <div class="indicator" style="width: 8px; height: 8px; border-radius: 50%" :class="getDiskHealthClassName(health)"></div>
                      </div>
                    </div>
                  </template>
                  <template #default>
                    <NDescriptions bordered size="small" label-placement="left" :column="1">
                      <NDescriptionsItem label="硬盘槽位">{{ index + 1 }}</NDescriptionsItem>
                      <NDescriptionsItem label="状态">{{ getDiskHealthText(health) }}</NDescriptionsItem>
                    </NDescriptions>
                  </template>
                </NPopover>
              </template>
            </div>
          </template>
        </NCard>
        <NCard v-if="hasDiskArray" size="small">
          <template #header>
            <div style="font-size: small">磁盘阵列状态（{{ arrayList.length }}个阵列）</div>
          </template>
          <template #default>
            <template v-for="({ state, stateValue, freeSize, totalSize }, index) in arrayList" :key="index">
              <NFlex vertical>
                <NFlex align="center">
                  <div>磁盘阵列{{ index + 1 }}</div>
                  <NTag round size="small" :bordered="false" :type="getArrayTagType(state)">{{ stateValue }}</NTag>
                </NFlex>
                <NFlex align="center" :wrap="false">
                  <div style="word-break: keep-all">存储使用率</div>
                  <NProgress :percentage="getArrayUsagePercentage(freeSize ?? 0, totalSize ?? 0)" :status="getArrayProgressStatus(getArrayUsagePercentage(freeSize ?? 0, totalSize ?? 0))">
                    {{ getArrayUsagePercentage(freeSize ?? 0, totalSize ?? 0) }}%
                  </NProgress>
                </NFlex>
                <NFlex>
                  <span>总容量：{{ formatArraySize(totalSize ?? 0) }}</span>
                  <span>已用：{{ formatArraySize((totalSize ?? 0) - (freeSize ?? 0)) }}</span>
                  <span>可用：{{ formatArraySize(freeSize ?? 0) }}</span>
                </NFlex>
              </NFlex>
            </template>
          </template>
        </NCard>
      </NFlex>
    </template>
  </NCard>
</template>

<style scoped lang="scss">
.disk-health {
  &.disk-healthy {
    &:hover {
      background-color: #18a05816;
    }
  }

  &.disk-warning {
    &:hover {
      background-color: #d0305016;
    }
  }

  &.disk-error {
    &:hover {
      background-color: #f0a02016;
    }
  }

  &:hover {
    transform: translateY(-2px);
    transition: transform 0.2s ease-in-out;
    box-shadow: v-bind('themeVars.boxShadow1');
  }

  .indicator {
    &.disk-healthy {
      background-color: #18a058;
    }

    &.disk-warning {
      background-color: #d03050;
    }

    &.disk-error {
      background-color: #f0a020;
    }
  }
}
</style>
