<template>
  <view class="knowledge-tree-node">
    <view class="min-h-[68px]" @click.stop="handleClick">
      <view class="flex items-center border-0 border-b border-solid border-[#E6E6E6] py-26">
        <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-4 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>
        <slot>
          <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>
        </slot>
      </view>
    </view>

    <!-- 子节点容器 -->
    <view v-if="nodeData.children && nodeData.children.length > 0"
      :class="['ml-40 overflow-hidden transition-all duration-300 h-0']"
      :style="{ height: nodeData.actualHeight + 'px' }">
      <knowledge-tree-node v-for="child in nodeData.children" :key="child.name" :node-data="child"
        :parent-data="nodeData" @node-click="handleNodeClick" @update-height="handleUpdateHeight"
        @start-practice="handleChildStartPractice">
        <template #default>
          <slot></slot>
        </template>
      </knowledge-tree-node>
    </view>
  </view>
</template>

<script lang="ts" setup>
import * as Study from '@/types/study';

// 定义 props
const props = defineProps({
  nodeData: {
    type: Object as PropType<Study.KnowledgeNode>,
    required: true
  },
  parentData: {
    type: Object as PropType<Study.KnowledgeNode>,
    default: null
  }
});

// 定义 emits
const emit = defineEmits(['nodeClick', 'updateHeight', 'startPractice']);

// 计算子节点高度
const calculateChildrenHeight = (node: Study.KnowledgeNode): number => {
  if (!node.children || node.children.length === 0) {
    return 0;
  }

  let height = 0;
  node.children.forEach(child => {
    // 每个子节点的基础高度
    height += 68;

    // 如果子节点已展开，递归计算其子节点高度
    if (child.isExpanded && child.children && child.children.length > 0) {
      height += calculateChildrenHeight(child);
    }
  });

  return height;
};

// 处理节点点击
const handleClick = () => {

  // 切换展开状态
  props.nodeData.isExpanded = !props.nodeData.isExpanded;

  // 计算并设置实际高度
  if (props.nodeData.isExpanded) {
    props.nodeData.actualHeight = calculateChildrenHeight(props.nodeData);
  } else {
    props.nodeData.actualHeight = 0;
  }

  // 通知父组件节点被点击
  emit('nodeClick', {
    node: props.nodeData,
    parent: props.parentData
  });

  // 如果有父节点，通知父节点更新高度
  if (props.parentData) {
    emit('updateHeight', props.parentData);
  }
};

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

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

// 处理子节点点击事件
const handleNodeClick = (eventData: { node: Study.KnowledgeNode; parent: Study.KnowledgeNode }) => {
  // 向上传递点击事件
  emit('nodeClick', eventData);
};

// 处理高度更新事件
const handleUpdateHeight = (parentNode: Study.KnowledgeNode) => {

  // 重新计算父节点高度
  if (parentNode.isExpanded) {
    parentNode.actualHeight = calculateChildrenHeight(parentNode);
  }

  // 继续向上传递高度更新事件
  if (props.parentData) {
    emit('updateHeight', props.parentData);
  }
};

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);
};
</script>

<style lang="scss" scoped></style>
