<template>
  <ReportModule :titleList="['1、分数段图']" tableOrChart="chart" :showPrintBtn="false" :showExportBtn="false">
    <template #title_right>
      <div :class="['right_item', { item_active: state.sectionScore == item }]" v-for="item in state.sortRangeScore"
        :key="item" @click="TagClick(item)">
        {{ item }}分段
      </div>
      <div class="right_set">
        <span>设置分数段</span>
        <el-input v-model="state.sectionScore" maxlength="3" style="width: 54px" @input="HandleInput"
          @change="BlurSectionScore" />
        <span>分/段</span>
      </div>
      <div class="right_radio">
        <el-select v-model="state.radioRangeScore" v-if="analysisStore?.filterObject?.classLevel != 2">
          <el-option :value="0" label="按年级"></el-option>
          <el-option :value="1" label="按班级"></el-option>
        </el-select>
      </div>
    </template>
    <template #module_table_chart>
      <template v-if="state.scoreSegmentData.datay.length">
        <template v-if="state.radioRangeScore == 0">
          <BarLineChart :datax="state.scoreSegmentData.datax" :datay="state.scoreSegmentData.datay"
            :fullScore="state.scoreSegmentData.fullScore" :markLine="state.scoreSegmentData.markLine"
            :color="state.scoreSegmentData.color" :title="state.scoreSegmentData.title"
            :tooltipData="state.scoreSegmentData.tooltipData" :unit="state.scoreSegmentData.unit"
            :tooltipTitle="state.scoreSegmentData.tooltipTitle">
          </BarLineChart>
        </template>
        <!-- 按班级 -->
        <template v-if="state.radioRangeScore == 1">
          <LineBarChart :datax="state.scoreSegmentClassData.datax" :datay="state.scoreSegmentClassData.datay"
            :showBackground="false" :legendList="state.scoreSegmentClassData.legendList"
            :title="state.scoreSegmentClassData.title" :tooltipData="state.scoreSegmentClassData.tooltipData"
            :hideOverlap="true"></LineBarChart>
        </template>
      </template>
      <div v-else class="no_content_data" v-loading="state.tableLoading" :element-loading-text="state.loadingText"
        element-loading-spinner="el-icon-loading" element-loading-background="#ffffff">
        <span>暂无数据</span>
      </div>
    </template>
    <template #module_describe>
      说明：信度是反应考试一致性或可靠性的指标，信度高，表示考试成绩较为准确，误差较小；
      信度低，表明误差大；信度低的考试无法正确评价考生的知识水平与智能素质。
      效度是指测验的有效性或正确性，即测验能否准确测量出其所要测量的内容。效度高的测验能够确保测验内容与测验目的的一致性，反映测验的正确性和准确性。
      分析试题的难度和区分度可以确保试题的质量和有效性，从而更好地评估学生的知识掌握程度和区分不同水平的学生。
      难度指试题的难易程度，通常用P值表示。计算方式为P=X/M（P为难度，X为试题平均得分，M为试题满分）。P值在0到1之间，值越大表示试题越简单，试题通常分为容易题（P≥0.7）、中等题（0.4至0.7之间）和难题（P≤0.4）。
      区分度是衡量试题对不同水平考生的区分能力，通常用D值表示。通过计算高分组和低分组在某一试题上的通过率之差，得到试题区分度。区分度高的试题能将不同水平的考生区分开来，水平高的学生得高分，水平低的学生得低分。D值的取值范围介于-1至1之间，D值越高，区分的效果越好。D≥0.4表明此题的区分度很好，属于优秀；0.3≤D＜0.4表明此题的区分度较好，属于良好；0.2≤D＜0.4表明此题的区分度一般；D＜0.2表明此题的区分度较低。
      图中展示了各科的命题分析明细，点击科目的柱可在下方查看该科所有小题的命题分析。
    </template>
  </ReportModule>
  <ReportModule :titleList="['2、分数段表']" tableOrChart="table" :showPrintBtn="false" :showDescribe="false"
    :currentPage="state.scoreSegmentData.pageNum" :pageSize="state.scoreSegmentData.pageSize"
    :total="state.scoreSegmentData.total" @update:pageSize="handleSizeChange" @update:currentPage="handleCurrentChange">
    <template #module_table_chart>
      <el-table :data="scoreRangeTableData" border>
        <template v-for="(header, headerIndex) in state.scoreSegmentData.headerData">
          <el-table-column align="center" :label="header.name" v-if="header.child && header.child.length"
            :key="`child_${headerIndex}`">
            <el-table-column v-for="(child, childIndex) in header.child" align="center" :label="child.value"
              :prop="child.prop" :key="`${headerIndex}_${childIndex}`" show-overflow-tooltip>
              <template #default="scope">
                <template v-for="(detailItem, detailKey) in scope.row.detailList">
                  <span v-if="header.name == detailItem.schoolName" :key="`${headerIndex}_${childIndex}_${detailKey}`">
                    <span :class="child.prop == 'doubleOnlineNum' ? 'table_row_blue' : ''"
                      v-if="child.prop == 'doubleOnlineNum' && detailItem[child.prop] != 0 && detailItem[child.prop] != '-'">
                      {{ detailItem[child.prop] }}
                    </span>
                    <span v-else>
                      {{ detailItem[child.prop] }}
                    </span>
                  </span>
                </template>
              </template>
            </el-table-column>
          </el-table-column>
          <el-table-column v-else align="center" width="100" :label="header.name" :prop="header.prop" :key="headerIndex"
            fixed="left" show-overflow-tooltip>
            <template #default="scope">
              {{ scope.row[header.prop] }}
            </template>
          </el-table-column>
        </template>
      </el-table>
    </template>
  </ReportModule>
</template>
<script lang="ts" setup>
import ReportModule from "@/components/ReportModule.vue";
import BarLineChart from "@/components/echarts/barLineChart.vue";//柱状图折线图组件
import LineBarChart from "@/components/echarts/lineBarChart.vue";//折线图柱状图组件
import { useAnalysisStore } from "@/store/analysis";
import { onMounted, reactive, computed, watch } from "vue";
import { scoreSegment } from "@/api/analysis";
const analysisStore = useAnalysisStore();
const state = reactive({
  sectionScore: '', // 设置分数段输入框
  sortRangeScore: ['5', '10'], // 设置分数段
  radioRangeScore: 0, // 0按年级, 1按班级
  scoreSegmentData: {
    exportLoading: false,
    datax: [],
    datay: [],
    fullScore: 100, //满分值
    markLine: [], //辅助线
    tooltipData: [], //悬浮弹窗的数据
    title: ["年级", "年级"],
    color: ["#995FB3", "#5470C6"],
    unit: "人",
    tooltipTitle: "及格率",
    tableData: [],
    headerData: [],
    pageSize: 10, //每页显示数据
    total: 0, //总数
    pageNum: 1, //当前页
  }, //分数段图数据
  tableLoading: true,
  loadingText: "加载中……",
  scoreSegmentClassData: {
    datax: [],
    datay: [],
    title: [],
    legendList: [],
    tooltipData: [],//悬浮弹窗的数据
  }//分数段 按班级分析数据
});
const scoreRangeTableData = computed(() => {
  const { tableData, pageSize, pageNum } = state.scoreSegmentData;
  const start = (pageNum - 1) * pageSize;
  const end = start + pageSize;
  return tableData.slice(start, end);
})
//分数段
const GetScoreSegment = async () => {
  state.tableLoading = true;
  const res = await scoreSegment({
    ...analysisStore.filterObject,
    scoreSegmentNum: state.sectionScore,
  });
  if (res.code === 200 && res.data && res.data.rowData && res.data.rowData.length) {
    let chartData = res.data.chartData
    let chartDataTotal = res.data.chartData.groupSchoolData // 联校/年级数据
    let chartDataSingle = res.data.chartData.oneSchoolData // 单校/班级数据

    let datax = []; // 分数段x轴数据
    let datay = []; // 联校/年级分数段y轴数据
    let count = []; // 联校/年级数据
    let tooltipData = []; // 联校/年级悬浮弹窗数据
    let markLine = []; // 辅助线数据

    let classTooltipData = []; //班级悬浮弹窗数据
    let classDatay = []; //分数段按班级y轴数据
    let classTitle = []; //分数段按班级图例数据

    let average = parseFloat(res.data.chartData.average); // 平均分
    let averageIndex = 0;//平均分的索引
    let standard = parseFloat(res.data.chartData.standard);//标准差
    let standardIndex = 0;//标准差索引
    let twoStandard = parseFloat(res.data.chartData.twoStandard);//2倍标准差
    let twoStandardIndex = 0;//2倍标准差索引
    let negativeOneStandard = parseFloat(res.data.chartData.negativeOneStandard);//-1倍标准差
    let negativeOneStandardIndex = 0;//-1倍标准差索引
    let negativeTwoStandard = parseFloat(res.data.chartData.negativeTwoStandard);//-2倍标准差
    let negativeTwoStandardIndex = 0;//-2倍标准差索引

    chartDataTotal.forEach((item, index) => {
      let list = item.name.split('-');
      let num1 = parseInt(list[0].replace(/[\[\]()]/g, ''));
      let num2 = parseInt(list[1].replace(/[\[\]()]/g, ''));

      if (num2 < average && average < num1) { // 平均分
        averageIndex = index
      }
      if (num2 < standard && standard < num1) { // 标准差
        standardIndex = index
      }
      if (num2 < twoStandard && twoStandard < num1) { // 2倍标准差
        twoStandardIndex = index
      }
      if (num2 < negativeOneStandard && negativeOneStandard < num1) { // -1倍标准差
        negativeOneStandardIndex = index
      }
      if (num2 < negativeTwoStandard && negativeTwoStandard < num1) { // -2倍标准差
        negativeTwoStandardIndex = index
      }

      datax.push(item.name)
      count.push(item.doubleOnlineNum)
      tooltipData.push({
        name: '',
        value: `${item.doubleOnlineNum}人，占比${item.doubleOnlineRate} ${item.studentUserName.length ? `(${item.studentUserName.join('、')})` : ''}`
      })
    });
    datay.push(count, count)

    markLine.push({
      name: '平均分',
      value: average,
      color: '#FAC858',
      xAxis: averageIndex,
    });
    markLine.push({
      name: '标准差',
      color: '#3BA272',
      value: standard,
      xAxis: standardIndex,
    });

    markLine.push({
      name: '-标准差',
      color: '#EE6666',
      value: negativeOneStandard,
      xAxis: negativeOneStandardIndex,
    });
    markLine.push({
      name: '-2倍标准差',
      color: '#EE6666',
      value: negativeTwoStandard,
      xAxis: negativeTwoStandardIndex,
    });
    markLine.push({
      name: '2倍标准差',
      color: '#3BA272',
      value: twoStandard,
      xAxis: twoStandardIndex,
    });
    //判断人数是否可点击
    const rowData = res.data.rowData || [];
    state.scoreSegmentData = {
      datax: datax,
      datay: datay,
      fullScore: parseFloat(chartData.fullScore),
      markLine: markLine,//辅助线数据
      tooltipData: tooltipData,//悬浮弹窗数据
      title: ["年级", "1班"],
      color: ["#995FB3", "#5470C6"],
      unit: '人',
      tooltipTitle: '及格率',
      tableData: rowData,
      headerData: res.data.titleData || [],
      pageSize: 10,//每页显示数据
      total: rowData.length,//总数
      pageNum: 1,//当前页
    };//分数段图数据

    // 单校/班级图表数据处理
    chartDataSingle.forEach(item => {
      classTitle.push(item.name)
      let singleItem = []
      let tootlipItem = []
      item.detailList.forEach(scoreItem => {
        singleItem.push(scoreItem.doubleOnlineNum)
        tootlipItem.push(`${scoreItem.doubleOnlineNum}人，占比${scoreItem.doubleOnlineRate}`);
      })
      classDatay.push(singleItem)
      classTooltipData.push(tootlipItem)
    })
    state.scoreSegmentClassData = {
      datax: datax,
      datay: classDatay,
      title: classTitle,//不会修改原数组
      legendList: classTitle.slice(0, 3),//默认显示全部
      tooltipData: classTooltipData,
    };
  } else {
    state.scoreSegmentData = {
      datax: [],
      datay: [],
      fullScore: 100,//满分值
      markLine: [],//辅助线
      tooltipData: [],//悬浮弹窗的数据
      title: ["年级", "年级"],
      color: ["#995FB3", "#5470C6"],
      unit: '人',
      tooltipTitle: '及格率',
      tableData: [],
      headerData: [],
      pageSize: 10,//每页显示数据
      total: 0,//总数
      pageNum: 1,//当前页
    };//分数段图数据

    state.scoreSegmentClassData = {
      datax: [],
      datay: [],
      title: [],
      legendList: [],
      tooltipData: [],//悬浮弹窗的数据
    };//分数段 按班级分析数据
  }
  state.tableLoading = false;
};
//分数段切换
const TagClick = (item) => {
  state.sectionScore = item;
  GetScoreSegment();//获取分数段数据
}
const HandleInput = (value: string) => {
  state.sectionScore = value.replace(/[^\d]/g, '');
}
// 设置分数段失去焦点
const BlurSectionScore = (value: string) => {
  if (value == '0') {
    state.sectionScore = '';
  }
  GetScoreSegment();//获取分数段数据
}
// 分页
const handleCurrentChange = (val: number) => {
  state.scoreSegmentData.pageNum = val;
}

const handleSizeChange = (val: number) => {
  state.scoreSegmentData.pageSize = val;
  state.scoreSegmentData.pageNum = 1;
}
// 初始化
const pageInit = () => {
  GetScoreSegment();
};
// 监听筛选条件
watch(
  () => analysisStore.filterObject,
  async () => {
    state.sectionScore = '';
    pageInit();
  },
  { deep: true },
);

onMounted(() => {
  pageInit();
});
</script>

<style lang="scss" scoped>
.el-input__inner {
  height: 36px;
}

.el-input__suffix {
  line-height: 36px;
}

.right_item {
  font-size: 14px;
  color: #999;
  font-weight: 400;
  cursor: pointer;
  margin-right: 5px;
  border-bottom: 2px solid #ffffff;

  &.item_active {
    font-size: 14px;
    color: #2e64fa;
    font-weight: 500;
    cursor: pointer;
    border-bottom: 2px solid #2e64fa;
  }
}

.right_set {
  font-weight: 400;
  font-size: 14px;
  color: #333333;

  :deep(.el-input) {
    padding: 0 5px;
    margin: 0 2px;

    .el-input__inner {
      text-align: center;
    }
  }
}

.right_radio {
  :deep(.el-select) {
    width: 100px;
  }
}
</style>
