<template>
  <ReportAssistant
    :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="loadingSvgIcon"
        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>
  </ReportAssistant>
  <ReportAssistant
    ref="reportModuleRef"
    :titleList="['2、分数段表']"
    tableOrChart="table"
    :showPrintBtn="false"
    :showDescribe="false"
    :currentPage="state.scoreSegmentData.pageNum"
    :pageSize="state.scoreSegmentData.pageSize"
    :total="state.scoreSegmentData.total"
    @ChangePageSize="ChangePageSize"
    @ChangeCurrentPage="ChangeCurrentPage"
    @ExportExcel="ExportExcel"
  >
    <template #module_table_chart>
      <el-table :data="scoreRangeTableData" border stripe>
        <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] != '-'
                      "
                      @click="
                        OpenStudentDialog(
                          '分数段',
                          scope.row.name,
                          header.name,
                          detailItem,
                          0,
                        )
                      "
                    >
                      {{ 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>
  </ReportAssistant>
  <StudentList
    :showDialog.sync="state.dialogData.showDialog"
    :title="state.dialogData.title"
    :tableTitle="state.dialogData.tableTitle"
    apiName="horizontalDistributionStudentInfo"
    :studentParam="{
      examId: state.dialogData.examId,
      selectType: state.dialogData.selectType,
      condition: state.dialogData.condition,
      selectSchoolLevel: state.dialogData.selectSchoolLevel,
      selectSchoolName: state.dialogData.selectSchoolName,
      selectClassLevel: state.dialogData.selectClassLevel,
      selectClassName: state.dialogData.selectClassName,
    }"
    @CloseDialog="CloseDialog"
  >
  </StudentList>
</template>

<script lang="ts" setup>
import ReportAssistant from "@/components/ReportModule.vue";
import BarLineChart from "@/components/echarts/barLineChart.vue"; //柱状图折线图组件
import LineBarChart from "@/components/echarts/lineBarChart.vue"; //折线图柱状图组件
import StudentList from "@/components/studentList.vue"; //学生列表弹窗组件
import { useAnalysisStore } from "@/store/analysis";
import {loadingSvgIcon} from "@/utils/common";
import { onMounted, reactive, computed, watch, ref } from "vue";
import { scoreSegment, publicExport } from "@/api/analysis";
import { downloadExcel, GetExcelFileName } from "@/utils/exportExcel";

// --- 类型定义 ---

interface MarkLineItem {
  name: string;
  value?: number;
  color?: string;
  xAxis?: number;
}

interface TooltipItem {
  name: string;
  value: string;
}

interface TableHeaderChild {
  value: string;
  prop: string;
}

interface TableHeader {
  name: string;
  prop?: string;
  child?: TableHeaderChild[];
}

interface TableRowDetail {
  schoolName: string;
  [key: string]: any;
}

interface TableRow {
  detailList: TableRowDetail[];
  [key: string]: any;
}

interface ScoreSegmentData {
  exportLoading: boolean;
  datax: string[];
  datay: number[][];
  fullScore: number;
  markLine: MarkLineItem[];
  tooltipData: TooltipItem[];
  title: string[];
  color: string[];
  unit: string;
  tooltipTitle: string;
  tableData: TableRow[];
  headerData: TableHeader[];
  pageSize: number;
  total: number;
  pageNum: number;
}

interface ScoreSegmentClassData {
  datax: string[];
  datay: number[][];
  title: string[];
  legendList: string[];
  tooltipData: string[][];
}
interface DialogData {
  showDialog: boolean;
  examId: string;
  title: string;
  tableTitle: string;
  selectType: string;
  condition: string;
  selectSchoolLevel: string;
  selectSchoolName: string;
  selectClassLevel: string;
  selectClassName: string;
}
interface State {
  sectionScore: string;
  sortRangeScore: string[];
  radioRangeScore: number;
  scoreSegmentData: ScoreSegmentData;
  tableLoading: boolean;
  loadingText: string;
  scoreSegmentClassData: ScoreSegmentClassData;
  dialogData: DialogData;
}

// API 返回数据的简易接口定义 (根据实际后端返回调整)
interface ApiChartDataTotalItem {
  name: string;
  doubleOnlineNum: number;
  doubleOnlineRate: string;
  studentUserName: string[];
}

interface ApiChartDataSingleItem {
  name: string;
  detailList: {
    doubleOnlineNum: number;
    doubleOnlineRate: string;
  }[];
}

interface ApiChartData {
  groupSchoolData: ApiChartDataTotalItem[];
  oneSchoolData: ApiChartDataSingleItem[];
  average: string;
  standard: string;
  twoStandard: string;
  negativeOneStandard: string;
  negativeTwoStandard: string;
  fullScore: string;
}

interface ApiResponse {
  code: number;
  data?: {
    chartData: ApiChartData;
    rowData: TableRow[];
    titleData: TableHeader[];
  };
}

// --- 业务逻辑 ---

const analysisStore = useAnalysisStore();
const reportModuleRef = ref<any>(null);
const getExamName = computed(() => {
  return analysisStore.analysisExamInfo.examName || "";
});
const scoreRangeTableData = computed(() => {
  const { tableData, pageSize, pageNum } = state.scoreSegmentData;
  const start = (pageNum - 1) * pageSize;
  const end = start + pageSize;
  return tableData.slice(start, end);
});
const state = reactive<State>({
  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: [], //悬浮弹窗的数据
  }, //分数段 按班级分析数据
  // 学生列表弹窗数据
  dialogData: {
    showDialog: false,
    examId: "",
    title: "",
    tableTitle: "",
    selectType: "",
    condition: "",
    selectSchoolLevel: "",
    selectSchoolName: "",
    selectClassLevel: "",
    selectClassName: "",
  },
});
//分数段
const GetScoreSegment = async () => {
  state.tableLoading = true;
  try {
    const res = (await scoreSegment({
      ...analysisStore.filterObject,
      scoreSegmentNum: state.sectionScore,
    })) as unknown as ApiResponse;

    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: string[] = []; // 分数段x轴数据
      let datay: number[][] = []; // 联校/年级分数段y轴数据
      let count: number[] = []; // 联校/年级数据
      let tooltipData: TooltipItem[] = []; // 联校/年级悬浮弹窗数据
      let markLine: MarkLineItem[] = []; // 辅助线数据

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

      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: ApiChartDataTotalItem, index: number) => {
        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 || [];

      // 修复点：确保赋值对象包含所有必需属性，特别是 exportLoading
      state.scoreSegmentData = {
        exportLoading: false,
        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: ApiChartDataSingleItem) => {
        classTitle.push(item.name);
        let singleItem: number[] = [];
        let tootlipItem: string[] = [];
        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 {
      // 修复点：确保赋值对象包含所有必需属性，特别是 exportLoading
      state.scoreSegmentData = {
        exportLoading: false,
        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: [], //悬浮弹窗的数据
      }; //分数段 按班级分析数据
    }
  } catch (error) {
    console.error("获取分数段数据失败:", error);
  } finally {
    state.tableLoading = false;
  }
};

//分数段切换
const TagClick = (item: string) => {
  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 ChangeCurrentPage = (val: number) => {
  state.scoreSegmentData.pageNum = val;
};

const ChangePageSize = (val: number) => {
  state.scoreSegmentData.pageSize = val;
  state.scoreSegmentData.pageNum = 1;
};
// 打开学生列表弹窗
const OpenStudentDialog = (
  str: string,
  title: string,
  tableTitle: string,
  list: any,
  selectType: string,
) => {
  state.dialogData.title = str + " " + title;
  state.dialogData.tableTitle = tableTitle;
  ((state.dialogData.selectType = selectType), //选择类型;0-分数段 1-名次段 2-N%段 3-等级分布（学业等级分布） 4-赋分分布
    (state.dialogData.condition =
      str == "一分段" ? `[${title}-${Number(title) - 1})` : title), //查询条件 分数段-[100-90] 名次段-前10、后200 N%-前5%名、后10%名 等级分布-等级名称 赋分分布-赋分等级
    (state.dialogData.selectSchoolLevel = list.schoolLevel)); //当前选择的学校级别：0-联考 1-学校分组 2-具体学校
  state.dialogData.selectClassLevel = list.classLevel; //当前选择的班级级别：0-年级 1-组合班级 2-具体班级
  state.dialogData.examId = analysisStore.filterObject.examId;
  if (analysisStore.filterObject.schoolLevel == 2) {
    if (list.schoolLevel == 2) {
      state.dialogData.selectSchoolName = analysisStore.filterObject.schoolName; //当前选择的学校名称：联校 组合学校 单校名称
      state.dialogData.selectClassName = list.schoolName; //当前选择的班级名称：年级 组合班级 单班
    } else {
      state.dialogData.selectSchoolName = list.schoolName; //当前选择的学校名称：联校 组合学校 单校名称
      state.dialogData.selectClassName =
        analysisStore.filterObject.classGroupName; //当前选择的班级名称：年级 组合班级 单班
    }
  } else {
    state.dialogData.selectSchoolName = list.schoolName; //当前选择的学校名称：联校 组合学校 单校名称
    state.dialogData.selectClassName =
      analysisStore.filterObject.classGroupName; //当前选择的班级名称：年级 组合班级 单班
  }
  state.dialogData.showDialog = true;
};
// 关闭学生列表弹窗
const CloseDialog = (val: boolean) => {
  state.dialogData.showDialog = val;
};
// 导出Excel
const ExportExcel = () => {
  // 1. 设置加载状态
  reportModuleRef.value?.SetExportLoading?.(true);
  // 2. 参数
  const examName = getExamName.value;
  let staticHeaderData: {
      label: string;
      prop: string | undefined;
      display: boolean;
    }[] = [],
    dynamicsHeaderData: {
      label: string;
      prop: string | undefined;
      display: boolean;
    }[] = [],
    childHeaderData: { label: string; prop: string; display: boolean }[] = [],
    dataList: any[][] = [];
  state.scoreSegmentData.headerData.forEach((item) => {
    if (item.child && item.child.length > 0) {
      dynamicsHeaderData.push({
        label: item.name,
        prop: item.prop,
        display: true,
      });
      if (childHeaderData.length == 0) {
        item.child.forEach((child) => {
          childHeaderData.push({
            label: child.value,
            prop: child.prop,
            display: true,
          });
        });
      }
    } else {
      staticHeaderData.push({
        label: item.name,
        prop: item.prop,
        display: true,
      });
    }
  });

  state.scoreSegmentData.tableData.forEach((item) => {
    const rowData: any[] = [];
    staticHeaderData.forEach((header) => {
      rowData.push(item[header.prop]);
    });
    if (item.detailList && item?.detailList.length > 0) {
      item.detailList.forEach((detail) => {
        childHeaderData.forEach((child) => {
          rowData.push(detail[child.prop]);
        });
      });
    }
    dataList.push(rowData);
  });
  const params = {
    fileName: `${GetExcelFileName(examName, analysisStore.filterObject, "分数段表")}`,
    examName: examName, //考试名称
    sheetName: "分数段表", //sheet页名称
    staticHeaderData: staticHeaderData, //静态表头
    dynamicsHeaderData: dynamicsHeaderData, //动态表头的一级表头
    childHeaderData: childHeaderData, //二级表头
    dataList: dataList, //数据
  };
  // 3. 调用通用下载方法，并在完成后重置加载状态
  downloadExcel(publicExport, params).finally(() => {
    reportModuleRef.value?.SetExportLoading?.(false);
  });
};
// 初始化
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;
  display: flex;
  align-items: center;

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

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

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