<script setup>
import Table from "@/components/Table/index.vue";
import SituationDia from "./SituationDia/index";
import { getJobStuList, getJobInfoById, getJobAnswerStatistics } from "@/api";
import {
  NumToChineseNumerals,
  formatTitleToPaper,
  getScoreColor,
} from "@/utils";
import Question from "@/components/Question";
import BatchCorrectionDia from "./BatchCorrectionDia";
import Filter from "@/components/Filter/index.vue";
import * as echarts from "echarts";
import { onMounted, watch } from "vue";
import anime from "animejs/lib/anime.es.js";

const props = defineProps({
  jobId: {
    type: String,
    default: "",
  },
  submission: {
    type: Array,
    default: () => [0, 0, 0, 0],
  },
  answerData: {
    type: Array,
    default: () => [],
  },
  levelData: {
    type: Array,
    default: () => [],
  },
  avgData: {
    type: Object,
    default: () => {},
  },
  classList: {
    type: Array,
    default: () => [],
  },
});
const emits = defineEmits(["refresh"]);

const filterData = ref({}); //过滤
const filterConfig = computed(() => [
  {
    comName: "el-select",
    label: "班级",
    prop: "classId",
    clearable: true,
    options: props.classList,
    showAll: props.classList.length > 1,
    selectConfig: {
      label: "className",
      value: "id",
    },
  },
]);
watch(
  () => props.classList,
  (newVal) => {
    if (newVal.length === 1) {
      filterData.value.classId = newVal[0].id;
    }
  }
);
function handleFilterData(type) {
  switch (type.value) {
    case "search":
      initInfo();
      emits("refresh", filterData.value);
      break;
    case "reset":
      initInfo();
      emits("refresh", {});
      break;
  }
}

const xbTable = ref({
  loading: false,
  columns: [
    { slot: "titleNo", prop: "titleNo", label: "题目序号", sortable: true },
    { slot: "fullScoreStuNum", label: "满分人数" },
    { slot: "totalStuNum", label: "非满分人数" },
    {
      prop: "scoreRate",
      slot: "scoreRate",
      label: "得分率",
      sortable: true,
    },
    { slot: "unMarkStuNum", label: "未批改人数" },
  ],
  tableData: [],
  pagination: {
    total: 0,
    pageNum: 1,
    pageSize: 70,
  },
});
watch(
  () => props.answerData,
  (newVal) => {
    xbTable.value.tableData = newVal;
    console.log(newVal);
  }
);

const dia = reactive({
  show: false,
  data: [],
});

async function handleClick(status) {
  dia.data = [];
  const res = await getJobStuList({
    jobId: props.jobId,
    status,
    pageSize: 10000,
  });
  dia.show = true;
  dia.data = res.rows;
}

const stuData = ref({});
async function handleStuClick(type = 0, data) {
  stuData.value = data;
  dia.data = [];
  const res = await getJobAnswerStatistics({
    jobId: props.jobId,
    titleId: data.id || data.titleId,
    markFlag: type,
    ...filterData.value,
  });
  dia.show = true;
  dia.data = res.rows;
}

const navActive = ref(0);

const paper = ref({});
async function initInfo() {
  const { data: res } = await getJobInfoById({
    jobId: props.jobId,
    ...filterData.value,
  });
  paper.value = {
    id: res.id,
    name: res.name,
    updateTime: res.updateTime,
    type: res.typeName,
    lookNum: res.lookNum,
    total: res.titleCount,
    difficulty: res.paperDifficulty,
    stagePid: res.stagePid,
    subjectId: res.subjectId,
    collectFlag: res.collectFlag,
    content: res.contentDetails.map((i) => ({
      id: i.contentId,
      type: i.contentName,
      score: i.contentScore,
      children: formatTitleToPaper(i.titleList),
    })),
  };
}

initInfo();

const batchCorrectionDia = reactive({
  show: false,
  data: {},
});
function onCorrection() {
  batchCorrectionDia.show = true;
  batchCorrectionDia.data = paper.value;
}

const nameToType = {
  未提交: 0,
  超时提交: 1,
  未批改: 2,
  已批改: 3,
};
const chart1Ref = ref();
const chart1Instance = ref();
watch(
  () => props.submission,
  (newVal) => {
    if (!newVal.length) return;
    chart1Instance.value?.setOption({
      series: [
        {
          data: [
            { value: newVal[0], name: "未提交" },
            { value: newVal[1], name: "超时提交" },
            { value: newVal[2], name: "未批改" },
            { value: newVal[3], name: "已批改" },
          ],
        },
      ],
    });
  },
  {
    immediate: true,
  }
);
function initChart1() {
  chart1Instance.value = echarts.init(chart1Ref.value);
  chart1Instance.value.setOption({
    title: {
      text: "提交情况",
      left: "center",
      top: "40px",
    },
    // tooltip: {
    //   trigger: "item",
    // },
    color: ["#f56c6c", "#f56c6c", "#409eff", "#67c23a"],
    series: [
      {
        type: "pie",
        radius: "50%",
        data: [],
        emphasis: {
          scale: false,
        },
        label: {
          formatter: "{b}\n({c} / {d}%)",
          overflow: "break",
          fontSize: 16,
        },
      },
    ],
  });
  chart1Instance.value.on("click", (params) => {
    handleClick(nameToType[params.name]);
  });
}

const levelType = {
  0: "不及格",
  1: "及格",
  2: "良好",
  3: "优秀",
};
const chart2Ref = ref();
const chart2Instance = ref();
const showChart2 = ref(false);
watch(
  () => props.levelData,
  async (newVal) => {
    if (!newVal.length) return (showChart2.value = false);
    showChart2.value = true;
    await nextTick();
    if (!chart2Instance.value) initChart2();
    chart2Instance.value?.setOption({
      series: [
        {
          data: newVal.map((i) => ({
            value: i.stuCount,
            name: levelType[i.level],
            stuList: i.stuList,
          })),
        },
      ],
    });
  },
  {
    immediate: true,
  }
);
function initChart2() {
  chart2Instance.value = echarts.init(chart2Ref.value);
  chart2Instance.value.setOption({
    title: {
      text: "作答水平",
      left: "center",
      top: "40px",
    },
    // tooltip: {
    //   trigger: "item",
    // },
    color: ["#f56c6c", "#E6A23C", "#409eff", "#67c23a"],
    series: [
      {
        type: "pie",
        radius: "50%",
        data: [],
        emphasis: {
          scale: false,
        },
        label: {
          formatter: "{b}\n({c} / {d}%)",
          overflow: "break",
          fontSize: 16,
        },
      },
    ],
  });
  chart2Instance.value.on("click", (params) => {
    dia.show = true;
    dia.data = params.data.stuList;
  });
}

async function handleJump(row) {
  navActive.value = 1;
  await nextTick();
  scrollToElementWithOffset(row.titleId, 0);
}

function scrollToElementWithOffset(elementId, offset = 0) {
  const targetElement = document.getElementById(elementId)?.parentElement;
  if (targetElement) {
    const top =
      targetElement.getBoundingClientRect().top + window.scrollY - offset;
    window.scrollTo({
      top: top,
      behavior: "smooth", // 平滑滚动
    });

    setTimeout(() => {
      anime({
        targets: targetElement,
        keyframes: [
          { borderColor: "#409EFF", opacity: 0.5, duration: 200 },
          { borderColor: "transparent", opacity: 1, duration: 200 },
          { borderColor: "#409EFF", opacity: 0.5, duration: 200 },
          { borderColor: "transparent", opacity: 1, duration: 200 },
        ],
        easing: "easeInOutSine",
        duration: 800,
        complete: () => {
          // 恢复默认样式
          targetElement.style.borderColor = "transparent";
        },
      });
    }, 500);
  }
}

// 关闭批改弹窗
function onClose() {
  emits("refresh");
  initInfo();
}

onMounted(() => {
  initChart1();
  if (props.classList.length === 1) {
    filterData.value.classId = props.classList[0].id;
  }
});
</script>
<template>
  <div class="whole app-container">
    <Filter
      v-model="filterData"
      :config="filterConfig"
      @handleAction="handleFilterData"
    />
    <div class="chart">
      <div ref="chart1Ref" class="chart-item"></div>
      <div v-if="showChart2" ref="chart2Ref" class="chart-item"></div>
      <div v-if="avgData.avgScore" class="chart-item">
        <el-progress
          type="circle"
          :percentage="avgData.avgScoreRate"
          :stroke-width="20"
          :width="200"
        >
          <template #default="{ percentage }">
            <div style="font-size: 16px">得分率：{{ percentage }}%</div>
            <div style="font-size: 16px; margin-top: 8px">
              平均分：{{ avgData.avgScore }}
            </div>
          </template>
        </el-progress>
      </div>
    </div>
    <div class="whole-title">
      作答情况
      <el-radio-group v-model="navActive">
        <el-radio-button label="表格" :value="0" />
        <el-radio-button label="试卷详情" :value="1" />
      </el-radio-group>
    </div>
    <template v-if="navActive === 0">
      <Table
        :xbTable="xbTable"
        :autoScroll="false"
        :default-sort="{
          prop: 'scoreRate',
          order: 'descending',
        }"
        row-key="titleId"
      >
        <template #titleNo="{ row }">
          <span style="cursor: pointer" @click="handleJump(row)">
            {{ row.titleNo }}
          </span>
        </template>
        <template #fullScoreStuNum="{ row }">
          <div
            style="width: 100%; cursor: pointer; color: #67c23a"
            @click="handleStuClick(1, row)"
          >
            {{ row.fullScoreStuNum }}
          </div>
        </template>
        <template #totalStuNum="{ row }">
          <div
            style="width: 100%; cursor: pointer; color: #f56c6c"
            @click="handleStuClick(0, row)"
          >
            {{ row.totalStuNum - row.fullScoreStuNum }}
          </div>
        </template>
        <template #scoreRate="{ row }">
          <div
            :style="{
              color: getScoreColor(row.scoreRate),
              cursor: 'pointer',
              width: '100%',
            }"
            @click="handleJump(row)"
          >
            {{ row.scoreRate / 100 }}%
          </div>
        </template>
        <template #unMarkStuNum="{ row }">
          <div
            :style="{
              cursor: 'pointer',
              color: row.unMarkStuNum > 0 ? '#409EFF' : '',
            }"
            @click="onCorrection"
          >
            {{ row.unMarkStuNum }}
          </div>
        </template>
      </Table>
      <el-empty v-if="!answerData.length" description="暂无数据" />
    </template>
    <div v-if="navActive === 1" class="box paper-content">
      <div
        class="paper-groups"
        v-for="(item, idx) in paper.content"
        :key="item.id"
      >
        <div class="paper-group-title">
          <div>
            {{ NumToChineseNumerals[idx] }}、
            <span v-html="item.type"></span>
          </div>
        </div>
        <div class="paper-group-questions">
          <div
            class="paper-group-questions-item"
            v-for="(q, qIdx) in item.children"
            :key="q.id"
          >
            <table border="1">
              <thead>
                <tr>
                  <th v-if="q.answerStatistics.children?.length">题号</th>
                  <th>满分人数</th>
                  <th>非满分人数</th>
                  <th>得分率</th>
                </tr>
              </thead>
              <tbody>
                <tr>
                  <td v-if="q.answerStatistics.children?.length">
                    {{ q.qNo }}
                  </td>
                  <td
                    style="cursor: pointer; color: #67c23a"
                    @click="handleStuClick(1, q)"
                  >
                    {{ q.answerStatistics.fullScoreStuNum }}
                  </td>
                  <td
                    style="cursor: pointer; color: #f56c6c"
                    @click="handleStuClick(0, q)"
                  >
                    {{
                      q.answerStatistics.totalStuNum -
                      q.answerStatistics.fullScoreStuNum
                    }}
                  </td>
                  <td
                    :style="{
                      color: getScoreColor(q.answerStatistics.scoreRate),
                    }"
                  >
                    {{ q.answerStatistics.scoreRate / 100 }}%
                  </td>
                </tr>
                <template v-if="q.answerStatistics.children?.length">
                  <tr v-for="i in q.answerStatistics.children">
                    <td>{{ q.qNo }}-{{ i.titleNo }}</td>
                    <td style="color: #67c23a">
                      {{ i.fullScoreStuNum }}
                    </td>
                    <td style="color: #f56c6c">
                      {{ i.totalStuNum - i.fullScoreStuNum }}
                    </td>
                    <td :style="{ color: getScoreColor(i.scoreRate) }">
                      {{ i.scoreRate / 100 }}%
                    </td>
                  </tr>
                </template>
              </tbody>
            </table>
            <Question :data="q" :index="q.qNo" :showMore="false" />
          </div>
        </div>
      </div>
      <el-backtop :right="100" :bottom="100" />
    </div>
  </div>
  <SituationDia
    v-model="dia.show"
    :data="dia.data"
    :stuData="stuData"
  ></SituationDia>
  <BatchCorrectionDia
    v-model="batchCorrectionDia.show"
    :jobId="jobId"
    :data="batchCorrectionDia.data"
    @close="onClose"
  ></BatchCorrectionDia>
</template>
<style scoped lang="scss">
.whole-title {
  text-align: center;
  font-weight: bold;
  margin: 16px 0;
  position: relative;
  :deep(.el-radio-group) {
    position: absolute;
    right: 0;
  }
}
table {
  border-collapse: collapse;
  text-align: center;
  width: 100%;
  tr {
    height: 35px;
  }
}

.chart {
  width: 100%;
  height: 400px;
  display: flex;
  .chart-item {
    width: 30%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
  }
}

.paper {
  &-title {
    min-height: 134px;
    text-align: center;
    &-info {
      color: #73767a;
      font-size: 14px;
      display: flex;
      justify-content: space-around;
      margin-top: 30px;
    }
    &-main {
      margin-top: 12px;
      text-align: center;
      font-weight: bold;
      font-size: 20px;
      div {
        width: 80%;
        margin: 0 auto;
      }
    }
  }
  &-groups {
    .paper-group-title {
      padding-bottom: 16px;
      font-weight: bold;
      font-size: 18px;
      display: flex;
      justify-content: space-between;
    }
    .paper-group-questions {
      cursor: pointer;
      &-item {
        border: 1px solid transparent;
        background: #fff;
        margin-bottom: 40px;
        padding: 16px;
        position: relative;
        transition: border 0.3s linear;
        &:hover {
          border: 1px solid var(--el-color-primary);
          border-radius: 4px;
          .tool {
            opacity: 1;
            visibility: visible;
          }
        }

        :deep(.questions-item-content) {
          margin-top: 0;
        }

        table {
          width: 50%;
          margin-bottom: 32px;
        }

        .tool {
          position: absolute;
          top: calc(100% + 8px);
          right: 0;
          opacity: 0;
          visibility: hidden;
          transition: all 0.3s linear;
        }
      }
    }
  }
}
</style>
