<template>
  <view class="knowledge-tree-node">
    <view class="" @click.stop="handleClick">
      <view class="flex items-center border-0 border-b border-solid border-[#E6E6E6] py-20">
        <view class="flex-1 min-w-1 flex items-center">
          <uv-icon v-if="!nodeData.isLeaf" name="arrow-right" size="14" color="#888"
            :custom-class="['mr-16 transition-transform duration-300', nodeData.isExpanded ? 'rotate-90' : '']" />
          <view>
            <view class="block text-28 text-fore-title font-bold ellipsis-1">{{ nodeData.name }}</view>
            <view class="mt-8 text-24 text-fore-light flex items-center">
              <progress class="w-100 rounded-full overflow-hidden" :percent="getProgressPercent(nodeData)"
                :show-text="false" activeColor="#31a0fc" backgroundColor="#efefef" />
              <text class="ml-10 text-primary">{{ nodeData.finishedCount }}</text>
              <text>/{{ nodeData.questionCount }}道</text>
              <text class="ml-10">正确率</text>
              <text class="ml-10 text-primary font-bold">{{ getCorrectRate(nodeData.finishedRatio) }}%</text>
            </view>
          </view>
        </view>
        <view v-if="nodeData.isLeaf"
          class="px-20 py-8 border border-solid border-primary rounded-full text-24 text-primary"
          @click.stop="handleStartPractice">开始练习</view>
      </view>
    </view>

    <!-- 子节点容器 -->
    <view v-if="nodeData.children && nodeData.children.length > 0" ref="childrenRef" class="knowledge-children"
      :id="`knowledge-children-${nodeData.id}`"
      :class="['ml-80 overflow-hidden transition-[height] duration-300', { 'is-measuring': isMeasuringHeight }]"
      :style="{ height: measuredHeight + 'px' }">
      <knowledge-tree-node v-for="child in nodeData.children" :key="child.name" :node-data="child"
        :parent-data="nodeData" @start-practice="handleChildStartPractice">
      </knowledge-tree-node>
    </view>
  </view>
</template>
<script lang="ts" setup>
import KnowledgeTreeNode from './knowledge-tree-node.vue';
import * as Study from '@/types/study';
import { getCurrentInstance } from 'vue';
const instance = getCurrentInstance();
// 定义 props
const props = defineProps({
  nodeData: {
    type: Object as PropType<Study.KnowledgeNode>,
    required: true
  },
  parentData: {
    type: Object as PropType<Study.KnowledgeNode>,
    default: null
  }
});
const isMeasuringHeight = ref(false);
const childrenRef = ref();
const measuredHeight = ref(0);
// 定义 emits
const emit = defineEmits(['startPractice']);

const getRect = (selector: string) => {
  return new Promise((resolve: (rect: { top: number, height: number }) => void) => {
    const query = uni.createSelectorQuery().in(instance?.proxy);
    query.select(selector).boundingClientRect(function (rect) {
      resolve(rect as { top: number, height: number });
    }).exec();
  });
}

const measureHeight = () => {
  isMeasuringHeight.value = true;
  setTimeout(() => {
    nextTick(() => {
      getRect(`#knowledge-children-${props.nodeData.id}`).then((res: any) => {
        isMeasuringHeight.value = false;
        setTimeout(() => {
          nextTick(() => {
            measuredHeight.value = res?.height ?? 0;
          });
        }, 50);
      });
    });
  }, 50);
}

// 处理节点点击
const handleClick = () => {
  // 切换展开状态
  props.nodeData.isExpanded = !props.nodeData.isExpanded;
  if (props.nodeData.isExpanded) {
    measureHeight();
  } else {
    measuredHeight.value = 0;
  }
};

// 处理开始练习事件
const handleStartPractice = () => {
  emit('startPractice', props.nodeData);
};

// 处理子节点开始练习事件
const handleChildStartPractice = (nodeData: Study.KnowledgeNode) => {
  emit('startPractice', nodeData);
};

const getCorrectRate = (rate: number): number => {
  if (!rate) {
    return 0;
  }
  if (rate > 0 && rate < 0.1) {
    return 0.1;
  }
  return rate;
};

const getProgressPercent = (nodeData: Study.KnowledgeNode): number => {
  const { finishedCount, questionCount } = nodeData;
  if (!finishedCount || !questionCount) {
    return 0;
  }
  return Math.min(finishedCount / questionCount, 1) * 100;
};
</script>

<style lang="scss" scoped>
.is-measuring {
  opacity: 0;
  position: fixed;
  z-index: -1000;
  transform: translateX(0);
  height: auto !important;
}
</style>
