view
<template>
  <Container
    :scrollX="true"
    :scrollY="false"
    :scroll-into-view="`item-${nowIndex}`"
    @onSafeAreaChange="onSafeAreaChange"
  >
    <template v-for="(item, parindex) in topics.ques" :key="parindex">
      <view
        :id="`item-${parindex}`"
        class="topic-item"
        :style="{
          width: `${safeArea.width}px`,
          height: `${safeArea.height}px`,
          flexShrink: 0, // 解决宽度无效问题
          marginLeft: parindex !== 0 ? `${24}rpx` : `0` 
        }"
      >
        <!-- 头部 -->
        <view class="topic-header">
          <view class="topic-header-left">
            <view class="topic-type">
              {{
                item.mode || (item.anslist?.length > 1 ? "多选题" : "单选题")
              }}
            </view>
            <view class="topic-count">
              第{{ parindex + 1 }}题/共{{ topics.ques.length }}题
            </view>
          </view>
          <view class="star-icon" @tap="handleStar(item)">
            <text
              class="iconfont"
              :class="starIcon === 'star' ? 'icon-star' : 'icon-star-filled'"
            ></text>
          </view>
        </view>

        <!-- 问题内容 -->
        <view class="topic-content">
          <view class="question-text">{{ item.title }}</view>
          <questions
            v-for="(question, index) in item.questions"
            :key="index"
            :answer-list="
              Array.isArray(item.anslist) ? item.anslist : [item.anslist]
            "
            :index="index"
            :select-count="selectIndexList[parindex] || []"
            :question="question"
            :parindex="parindex"
            :mode="mode"
            @select="handleSelect"
            @show-answer="(index) => setShowAnswer(index, parindex)"
          />
        </view>

        <!-- 答案展示 -->
        <view
          v-if="showAnswer[parindex] && mode === 'practice'"
          class="answer-section"
        >
          <view class="answer-content">
            <view class="answer-row">
              <view class="answer-item border-r-primary">
                正确答案:
                <text class="answer-text">{{ getRightAnswer(parindex) }}</text>
              </view>
              <view class="answer-item">
                我的答案:
                <text class="answer-text">{{ getMyAnswer(parindex) }}</text>
              </view>
            </view>
          </view>
        </view>

        <!-- 底部按钮 -->
        <view class="button-group">
          <button
            v-if="parindex >= 1 && parindex < topics.ques.length - 1"
            class="prev-btn"
            @tap="handlePrevPage(item, parindex)"
          >
            上一题
          </button>
          <button
            v-if="parindex < topics.ques.length - 1"
            class="next-btn"
            @tap="handleNextPage(item, parindex)"
          >
            下一题
          </button>
        </view>
      </view>
    </template>
  </Container>
</template>

<script setup>
import { ref, onMounted } from "vue";
import Questions from "./Questions.vue";
import Container from "../Container/Container.vue";

const TopicMapList = ["A", "B", "C", "D", "E"];
const safeArea = ref({});

// Props 定义
const props = defineProps({
  topics: {
    type: Object,
    default: () => ({}),
  },
  onStar: {
    type: Function,
    default: null,
  },
  type: {
    type: String,
    default: "radio",
  },
  mode: {
    type: String,
    default: "practice", // practice: 练习模式, exam: 考试模式
  },
});

// Emits 定义
const emit = defineEmits(["prevPage", "nextPage", "answerChange"]);

// 响应式数据
const nowIndex = ref(0);
const starIcon = ref("star");
const showAnswer = ref([]);
const selectIndexList = ref([]);

// 生命周期钩子
onMounted(() => {
  const systemInfo = uni.getSystemInfoSync();
  selectIndexList.value = Array(props.topics.ques.length)
    .fill()
    .map(() => []);
  showAnswer.value = Array(props.topics.ques.length).fill(false);
});

// 方法
const handleStar = (item) => {
  if (!props.onStar) return;
  props.onStar(item).then((res) => {
    if (!res) return;
    starIcon.value = starIcon.value === "star" ? "star-2" : "star";
  });
};

const handleSelect = (value, parindex) => {
  const arr = selectIndexList.value[parindex];
  const currentTopic = props.topics.ques[parindex];
  const isSingleChoice =
    !Array.isArray(currentTopic.anslist) || currentTopic.anslist.length === 1;

  // 如果点击已选中的选项，则取消选择
  if (arr.includes(value)) {
    selectIndexList.value[parindex] = arr.filter((item) => item !== value);
    emit("answerChange", {
      questionIndex: parindex,
      answers: selectIndexList.value[parindex],
      isSingleChoice,
    });
    return;
  }

  // 如果是考试模式
  if (props.mode === "exam") {
    // 如果是单选题，直接替换
    if (isSingleChoice) {
      selectIndexList.value[parindex] = [value];
    } else {
      // 多选题直接添加
      arr.push(value);
    }
    emit("answerChange", {
      questionIndex: parindex,
      answers: selectIndexList.value[parindex],
      isSingleChoice,
    });
    return;
  }

  // 练习模式逻辑
  const max = Array.isArray(currentTopic.anslist)
    ? currentTopic.anslist.length
    : 1;

  // 如果已达到最大选择数，则不允许继续选择
  if (arr.length >= max) {
    return;
  }

  // 如果是单选题，直接替换
  if (max === 1) {
    selectIndexList.value[parindex] = [value];
  } else {
    // 添加新选择
    arr.push(value);
  }

  // 如果是练习模式，且即将完成所有选择，则显示答案
  if (props.mode === "practice" && max - 1 === arr.length) {
    emit("showAnswer", true);
  }
};

const setShowAnswer = (value, parindex) => {
  showAnswer.value[parindex] = value;
};

const getRightAnswer = (index) => {
  const topic = props.topics.ques[index];
  const answers = Array.isArray(topic.anslist)
    ? topic.anslist
    : [topic.anslist];
  return answers
    .map((value) => {
      const question = topic.questions.find((q) => q.value === value);
      return question ? TopicMapList[topic.questions.indexOf(question)] : "";
    })
    .join("");
};

const getMyAnswer = (parindex) => {
  const topic = props.topics.ques[parindex];
  return (selectIndexList.value[parindex] || [])
    .map((value) => {
      const question = topic.questions.find((q) => q.value === value);
      return question ? TopicMapList[topic.questions.indexOf(question)] : "";
    })
    .join("");
};

const handlePrevPage = (item, index) => {
  nowIndex.value = index - 1;
  emit("prevPage", item, index);
};

const handleNextPage = (item, index) => {
  nowIndex.value = index + 1;
  emit("nextPage", item, index);
};

const onSafeAreaChange = (s) => {
  safeArea.value = s;
};
</script>

<style lang="scss" scoped>
@import "@/uni.scss";

.topic-container {
  width: 100vw;
  overflow: hidden;
  position: relative;
}

.topic-item {
  display: flex;
  flex-direction: column;
  gap: 12px;
  position: relative;
  box-sizing: border-box;
}

.topic-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.topic-header-left {
  display: flex;
  gap: 8px;
  align-items: center;
}

.topic-type {
  border: 1px solid $uni-primary;
  padding: 0 8px;
  border-radius: 6px;
  color: $uni-primary;
  font-weight: 600;
  font-size: 14px;
}

.topic-count {
  color: #333;
  font-size: 14px;
}

.topic-content {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.question-text {
  font-weight: bold;
  font-size: 14px;
  white-space: normal;
}

.answer-section {
  flex: 1;
  border-radius: 16rpx;
  border: 1px solid #ddd;
  padding: 24rpx;
  display: flex;
  flex-direction: column;
  gap: 32rpx;
  overflow: scroll;
}

.answer-row {
  font-size: 14px;
  display: flex;
  align-items: center;
  gap: 12px;
}

.answer-item {
  display: flex;
  gap: 8px;
  align-items: center;
  padding-right: 12px;
}

.border-r-primary {
  border-right: 2px solid $uni-primary;
}

.answer-text {
  color: $uni-primary;
}

.button-group {
  display: flex;
  gap: 8px;
  position: sticky;
  bottom: 0;
  margin-top: auto;
}

.prev-btn {
  flex: 1;
  background-color: $uni-primary-light;
  color: $uni-primary;
}

.next-btn {
  flex: 1;
  background-color: $uni-primary;
  color: #fff;
}
</style>
