<template>
  <div class="p-[20px]">
    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
      <div class="mb-[10px]">
        <el-row :gutter="20">
          <el-col :span="6" v-for="({ title, value, unit }) in info">
            <el-card shadow="hover">
              <div class="title">{{ title }}</div>
              <div class="mt-[10px]">
                <span class="value">{{ value }}</span>
                <span class="unit ml-[10px]">{{ unit }}</span>
              </div>
            </el-card>
          </el-col>
        </el-row>
        <div class="mt-[20px] flex flex-right">
          <el-button-group>
            <el-button :type="activeTime == item ? `primary` : ''" v-for="item in [6, 9, 12]" @click="changeTime(item)">近{{ item }}月</el-button>
          </el-button-group>
        </div>
        <el-row :gutter="20" class="line-space mt-[20px]">
          <el-col :span="8">
            <div class="card-body">
              <div class="chart-title">评价次数统计</div>
              <MyCharts :option="evaluateTimesOptions" />
            </div>
          </el-col>
          <el-col :span="8">
            <div class="card-body">
              <div class="chart-title">评价细则五星率统计</div>
              <div class="level-label label">
                <div>
                  <div>{{ busLevelScoreTotal == 0 ? '0' : ((busLevelScore / busLevelScoreTotal) * 100).toFixed(0) }}</div>
                  <div class="label-value">%</div>
                </div>
              </div>
              <div class="attitude-label label">
                <div>
                  <div>{{ workAttitudeScoreTotal == 0 ? '0' : ((workAttitudeScore / workAttitudeScoreTotal) * 100).toFixed(0) }}</div>
                  <div class="label-value">%</div>
                </div>
              </div>
              <div class="compliance-label label">
                <div>
                  <div>{{ rightApprovalScoreTotal == 0 ? '0' : ((rightApprovalScore / rightApprovalScoreTotal) * 100).toFixed(0) }}</div>
                  <div class="label-value">%</div>
                </div>
              </div>
              <div class="name level-name">业务水平</div>
              <div class="name attitude-name">工作态度</div>
              <div class="name compliance-name">合规评审</div>
              <MyCharts :option="fiveStarOptions" />
            </div>
          </el-col>
          <el-col :span="8">
            <div class="card-body">
              <div class="chart-title">受评专家人数统计</div>
              <MyCharts :option="evaluatedByExpertOptions" />
            </div>
          </el-col>
        </el-row>
        <el-divider />
        <el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="auto">
          <el-form-item label="专家名称" prop="evaluateUser">
            <el-input v-model="queryParams.evaluateUser" placeholder="请输入专家名称" />
          </el-form-item>
          <el-form-item label="工作单位" prop="workUnit">
            <el-input v-model="queryParams.workUnit" placeholder="请输入工作单位" />
          </el-form-item>
          <el-form-item label="最近一次评审时间" prop="reviewTime">
            <el-date-picker
              v-model="queryParams.reviewTime"
              type="datetimerange"
              start-placeholder="开始时间"
              end-placeholder="结束时间"
              style="width: 300px"
              value-format="YYYY-MM-DD HH:mm:ss"
            >
            </el-date-picker>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
            <el-button icon="Refresh" @click="resetQuery">重置</el-button>
            <el-button type="warning" plain icon="Download" @click="handleExport">导出</el-button>
          </el-form-item>
        </el-form>
        <el-table :data="lists" class="mt-[10px]" @sort-change="sortChange">
          <el-table-column label="序号" width="50px" type="index"></el-table-column>
          <el-table-column
            :label="label"
            :align="align || 'center'"
            :min-width="minWidth || '100px'"
            :prop="prop"
            v-for="{ label, prop, align, minWidth, sortable } in headers"
            :key="prop"
            :sortable="sortable"
          >
            <template #default="{ row }">
              <span>{{ row[prop] || '-' }}</span>
            </template>
          </el-table-column>
        </el-table>
        <pagination v-show="page.total > 0" :total="page.total" v-model:page="page.pageNum" v-model:limit="page.pageSize" @pagination="getList" />
      </div>
    </transition>
  </div>
</template>

<script setup lang="ts">
import { getBaseData, getChartData, getListData } from '@/api/evaluate/statistics';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
import * as echarts from 'echarts';
import MyCharts from '@/components/MyCharts.vue';

const infoData = ref({
  nums: 0,
  eachNums: 0,
  greatNums: 0,
  expertNums: 0
});
const info = computed(() => {
  const { nums, eachNums, greatNums, expertNums } = infoData.value;
  return [
    {
      title: '评价总次数',
      value: nums || 0,
      unit: '次'
    },
    {
      title: '专家互评总次数',
      value: eachNums || 0,
      unit: '次'
    },
    {
      title: '全五星好评总数',
      value: greatNums || 0,
      unit: '次'
    },
    {
      title: '受评专家总人数',
      value: expertNums || 0,
      unit: '人'
    }
  ];
});
const evaluateTimesOptions = ref(null);
const evaluatedByExpertOptions = ref(null);
const fiveStarOptions = ref(null);
const activeTime = ref(6);
const changeTime = (time:any) => {
  activeTime.value = time;
  getChart();
};

const customGrid = {
  top: 30,
  left: 16,
  right: 16,
  bottom: 16,
  containLabel: true
};
const barStyle = {
  barWidth: 20,
  itemStyle: {
    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
      { offset: 0, color: '#1978e5' },
      { offset: 1, color: 'rgba(25,120,299, 0)' }
    ])
  }
};
const xStyle = {
  axisLabel: {
    color: '#a4aab5',
    fontSize: 12,
    fontWeight: 400
  },
  axisTick: {
    show: false
  },
  axisLine: {
    lineStyle: {
      color: '#1d314d'
    }
  }
};
const yStyle = {
  type: 'value',
  axisLabel: {
    color: '#a4aab5',
    fontSize: 12,
    fontWeight: 700
  },
  axisLine: {
    show: false
  },
  splitLine: {
    lineStyle: {
      color: '#1d314d'
    }
  },
  nameTextStyle: {
    color: '#fff',
    fontSize: 12,
    align: 'center',
    fontWeight: 400
  }
};
const customLegend = {
  show: true,
  textStyle: {
    color: '#fff'
  },
  itemWidth: 16,
  itemHeight: 16,
  right: 16,
  selectedMode: false
};
const setEvaluateTimes = ({ xline, yline }) => {
  evaluateTimesOptions.value = {
    grid: customGrid,
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'shadow'
      }
    },
    legend: {
      ...customLegend,
      data: ['评价次数']
    },
    xAxis: {
      data: xline,
      type: 'category',
      ...xStyle
    },
    yAxis: {
      name: '单位：次',
      ...yStyle
    },
    series: [
      {
        name: '评价次数',
        data: yline?.map((e:any) => (!e || e == 'null' ? 0 : e)) || [],
        type: 'bar',
        ...barStyle
      }
    ]
  };
};
const setEvaluatedByExpertOptions = ({ xline, yline }) => {
  evaluatedByExpertOptions.value = {
    grid: customGrid,
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'shadow'
      }
    },
    legend: {
      ...customLegend,
      data: ['受评人数']
    },
    xAxis: {
      data: xline,
      type: 'category',
      ...xStyle
    },
    yAxis: {
      name: '单位：人',
      ...yStyle
    },
    series: [
      {
        name: '受评人数',
        data: yline?.map((e:any) => (!e || e == 'null' ? 0 : e)) || [],
        type: 'bar',
        ...barStyle
      }
    ]
  };
};

const pieCustomOption = {
  seriesOption: {
    type: 'pie',
    radius: ['30%', '40%'],
    avoidLabelOverlap: false,
    hoverAnimation: false,
    label: {
      normal: {
        show: false,
        position: 'center'
      },
      emphasis: {
        show: false
      }
    },
    labelLine: {
      normal: {
        show: false
      }
    }
  },
  dataOption: [
    {
      selected: false
    },
    {
      name: '',
      itemStyle: {
        color: '#113761'
      },
      label: {
        normal: {
          show: false
        }
      }
    }
  ]
};
const busLevelScore = ref(0);
const busLevelScoreOther = ref(0);
const busLevelScoreTotal = computed(() => busLevelScore.value + busLevelScoreOther.value);
const workAttitudeScore = ref(0);
const workAttitudeScoreOther = ref(0);
const workAttitudeScoreTotal = computed(() => workAttitudeScore.value + workAttitudeScoreOther.value);
const rightApprovalScore = ref(0);
const rightApprovalScoreOther = ref(0);
const rightApprovalScoreTotal = computed(() => rightApprovalScore.value + rightApprovalScoreOther.value);
const setApprovalOverview = (res?: any) => {
  busLevelScore.value = res?.busLevelScore?.fiveNums || 0;
  busLevelScoreOther.value = res?.busLevelScore?.otherNums || 0;
  workAttitudeScore.value = res?.workAttitudeScore?.fiveNums || 0;
  workAttitudeScoreOther.value = res?.workAttitudeScore?.otherNums || 0;
  rightApprovalScore.value = res?.rightApprovalScore?.fiveNums || 0;
  rightApprovalScoreOther.value = res?.rightApprovalScore?.otherNums || 0;
  fiveStarOptions.value = {
    grid: customGrid,
    series: [
      {
        name: '业务水平',
        ...pieCustomOption.seriesOption,
        center: ['20%', '40%'],
        data: [
          {
            value: busLevelScore.value,
            name: '业务水平',
            ...pieCustomOption.dataOption[0],
            itemStyle: {
              color: '#f56c6c'
            }
          },
          {
            value: busLevelScoreOther.value,
            ...pieCustomOption.dataOption[1]
          }
        ]
      },
      {
        name: '工作态度',
        ...pieCustomOption.seriesOption,
        center: ['50%', '40%'],
        data: [
          {
            value: workAttitudeScore.value,
            name: '工作态度',
            ...pieCustomOption.dataOption[0],
            itemStyle: {
              color: '#1978e5'
            }
          },
          {
            value: workAttitudeScoreOther.value,
            ...pieCustomOption.dataOption[1]
          }
        ]
      },
      {
        name: '合规评审',
        ...pieCustomOption.seriesOption,
        center: ['80%', '40%'],
        data: [
          {
            value: rightApprovalScore.value,
            name: '合规评审',
            ...pieCustomOption.dataOption[0],
            itemStyle: {
              color: '#67c23a'
            }
          },
          {
            value: rightApprovalScoreOther.value,
            ...pieCustomOption.dataOption[1]
          }
        ]
      }
    ]
  };
};
const lists = ref([]);
interface Header {
  label: string;
  prop: string;
  align?: 'center' | 'left' | 'right';
  minWidth?: string | number;
  sortable?: any
}
const headers = ref<Header[]>([
  {
    label: '专家名称',
    prop: 'expertName'
  },
  {
    label: '工作单位',
    prop: 'workUnit'
  },
  {
    label: '职务',
    prop: 'duty'
  },
  {
    label: '专家入库时间',
    prop: 'approvalTime'
  },
  {
    label: '参与评审项目数',
    prop: 'joinProNums'
  },
  {
    label: '最近一次评审时间',
    prop: 'closeTime'
  },
  {
    label: '星级总分',
    prop: 'scoreSum',
    sortable: 'custom'
  },
  {
    label: '星级均分',
    prop: 'scoreAvg',
    sortable: 'custom'
  },
  {
    label: '评价等级',
    prop: 'evaRank'
  }
]);

const page = ref({
  pageNum: 1,
  pageSize: 10,
  total: 0
});

const getChart = async () => {
  let res = await getChartData(activeTime.value);
  if (res.code != 200) {
    ElNotification({
      title: '提示',
      message: res.msg,
      type: 'error'
    });
    return;
  }
  const { numsSts, starSts, persSts } = res.data;
  setEvaluateTimes(numsSts || {});
  setEvaluatedByExpertOptions(persSts || {});
  setApprovalOverview(starSts || {});
};
const queryParams = ref<any>({
  evaluateUser: '',
  workUnit: '',
  reviewTime: []
});
const getList = async (sortParams = {}) => {
  const params = { ...queryParams.value, ...page.value, ...sortParams };
  params.startDate = params.reviewTime?.[0] || '';
  params.endDate = params.reviewTime?.[1] || '';
  delete params.reviewTime;

  const res = await getListData(params);
  lists.value = res.rows;
  page.value.total = res.total;
};

/** 搜索按钮操作 */
const handleQuery = () => {
  page.value.pageNum = 1;
  getList();
};

const queryFormRef = ref<ElFormInstance>();
/** 重置按钮操作 */
const resetQuery = () => {
  queryFormRef.value?.resetFields();
  handleQuery();
};
const sortChange = ({ prop, order }) => {
  if (order == null) {
    getList();
    return;
  }
  const orderByColumn = prop;
  const isAsc = order == 'ascending' ? 'asc' : 'desc';
  getList({ orderByColumn, isAsc });
};
const getData = async () => {
  let res = await getBaseData();
  if (res.code != 200) {
    ElNotification({
      title: '提示',
      message: res.msg,
      type: 'error'
    });
  }
  infoData.value = res.data || {};
  await getChart();
  await getList();
};

/** 导出按钮操作 */
const handleExport = () => {
  const params = { ...queryParams.value };
  params.startDate = params.reviewTime?.[0] || '';
  params.endDate = params.reviewTime?.[1] || '';
  delete params.reviewTime;

  proxy?.download('/zjk-api/evaluate/export', params, `评价统计_${new Date().getTime()}.xlsx`);
};
onMounted(() => {
  getData();
});
</script>
<style lang="scss" scoped>
.title {
  font-size: 16px;
  font-weight: bold;
}
.value {
  font-size: 32px;
  font-weight: bold;
}
.unit {
  font-size: 16px;
}
.line-space {
  row-gap: 20px;
}
.card-body {
  background-color: #0c2139;
  padding-top: 40px;
  border: 1px solid var(--el-border-color-light);
  border-radius: 6px;
  transition: var(--el-transition-duration);
  position: relative;
  box-sizing: border-box;
  height: 300px;
  &:hover {
    box-shadow: 0 0 20px rgba(0, 0, 0, 0.25);
  }
  .chart-title {
    position: absolute;
    top: 10px;
    left: 10px;
    color: #fff;
    font-weight: bold;
    line-height: 20px;
  }
  .chart-box {
    width: 100%;
    height: 100%;
    overflow: hidden;
    border-radius: 0 0 4px 4px;
    z-index: 0;
    position: relative;
  }
}
.flex-right {
  justify-content: flex-end;
}
.label {
  position: absolute;
  top: calc(40% + 25px);
  font-size: 24px;
  font-weight: 500;
  color: #fff;
  transform: translateY(-50%);
  width: 20%;
  aspect-ratio: 1/1;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  &.level-label {
    left: 10%;
  }
  &.attitude-label {
    left: 50%;
    transform: translate(-50%, -50%);
  }
  &.compliance-label {
    right: 10%;
  }
  .label-value {
    font-size: 14px;
    color: #858982;
  }
}
.name {
  position: absolute;
  bottom: 20%;
  font-size: 16px;
  font-weight: 500;
  color: #fff;
  width: 20%;
  text-align: center;
  &.level-name {
    left: 10%;
  }
  &.attitude-name {
    left: 50%;
    transform: translateX(-50%);
  }
  &.compliance-name {
    right: 10%;
  }
}
</style>
