<template>
  <div class="p-2">
    <transition :enter-active-class="proxy?.animate.searchAnimate.enter"
                :leave-active-class="proxy?.animate.searchAnimate.leave">
      <div class="mb-[10px]">
        <el-card v-if="roles.includes('expert')" shadow="hover">
          <div class="card-content flex gap-[20px]">
            <div class="flex-1">
              <div class="flex justify-between flex-1 gap-[20px]">
                <div class="flex items-start flex-grow-[6] expert-info">
                  <div class="avatar">
                    <img :src="expertInfo.avatar" alt="" class="h-[100%] w-auto" />
                  </div>
                  <div class="info lh-[24px]">
                    <div class="flex items-center flex-wrap lh-[59px]">
                      <div class="flex-1 flex items-center border-right">
                        <div class="info-label">姓名：</div>
                        <div class="info-value">{{ expertInfo.name || '-' }}</div>
                      </div>
                      <div class="flex-1 flex items-center">
                        <div class="info-label">性别：</div>
                        <div class="info-value">{{ sexObj[expertInfo.sex] || '-' }}</div>
                      </div>
                    </div>
                    <div class="lh-[59px]">
                      <div class="info-label">生日：</div>
                      <div class="info-value">{{ expertInfo.birthDate || '-' }}</div>
                    </div>
                  </div>
                  <div class="tag lh-[59px]">
                    <div class="flex items-center flex-wrap">
                      <div class="info-label">领域：</div>
                      <div v-if="expertInfo.performWorkId.length > 0" class="info-value flex gap-[10px]">
                        <el-tag v-for="item in expertInfo.performWorkId">{{ performWorkTypeObj[item] || '-' }}</el-tag>
                      </div>
                      <div v-else class="info-value">
                        <el-tag>-</el-tag>
                      </div>
                    </div>
                    <div class="flex items-center flex-wrap">
                      <div class="info-label">标签：</div>
                      <div v-if="expertInfo.tag.length > 0" class="info-value flex gap-[10px]">
                        <el-tag v-for="item in expertInfo.tag" type="danger">{{ item }}</el-tag>
                      </div>
                      <div v-else class="info-value">
                        <el-tag type="danger">-</el-tag>
                      </div>
                    </div>
                  </div>
                </div>
                <div class="flex items-start justify-end gap-[20px] info-right">
                  <div>当前排名：{{ expertInfo.rank || '-' }}</div>
                  <div class="cursor-pointer position-relative" @click="gotoDetail(expertInfo.id)">
                    <div>当前积分：{{ expertInfo.score }}</div>
                    <div class="tip">点击查看积分详情</div>
                    <el-tooltip :content="tipJson[expertInfo.scoreStatus]" effect="light" placement="top-end">
                      <span v-if="[3, 1].includes(expertInfo.scoreStatus)"
                            class="score-status position-absolute top-[-10px] right-[-10px]">
                        <el-icon><WarningFilled /></el-icon>
                      </span>
                    </el-tooltip>
                  </div>
                </div>
              </div>

              <div class="other-info flex mt-[20px] expert-base-info">
                <div v-for="(value) in otherInfo" class="flex-1 flex items-start base-info-item">
                  <div class="font-bold base-info-label">{{ value.label }}：</div>
                  <div class="base-info-value">
                    <div v-if="Array.isArray(value.value)">
                      <div v-for="item in value.value">
                        {{ item }}
                      </div>
                      <div v-if="value.value.length == 0">-</div>
                    </div>
                    <div v-else>{{ value.value || '-' }}</div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </el-card>
        <el-card class="mt-[10px]" shadow="hover">
          <div class="model-title">专家积分榜</div>
          <div class="points-info flex gap-[20px] h-[530px]">
            <el-row :gutter="20" class="flex-1 h-[100%]">
              <el-col :span="15" class="h-[100%]">
                <el-table :data="expertList" class="rank-table">
                  <el-table-column
                    v-for="{ label, prop, align, minWidth } in headers"
                    :key="prop"
                    :align="align || 'center'"
                    :label="label"
                    :min-width="minWidth || '100px'"
                    prop="expertName"
                  >
                    <template #default="{ row }">
                      <span v-if="prop == 'points'">{{ +row.points }}</span>
                      <span v-else>{{ row[prop] || '-' }}</span>
                    </template>
                  </el-table-column>
                </el-table>
                <pagination
                  v-show="page.total > 0"
                  v-model:limit="page.pageSize"
                  v-model:page="page.pageNum"
                  :total="page.total"
                  @pagination="getList"
                />
              </el-col>
              <el-col :span="9" class="h-[100%]">
                <div class="card-body h-[100%]">
                  <div class="chart-title flex justify-between items-center">
                    <div>专家排行榜</div>
                    <el-button-group size="small">
                      <el-button v-for="item in [30, 60, 90]" :type="activeDays == item ? `primary` : ''"
                                 @click="changeDays(item)"
                      >近{{ item }}天
                      </el-button
                      >
                    </el-button-group>
                  </div>
                  <MyCharts :option="options" />
                </div>
              </el-col>
            </el-row>
          </div>
        </el-card>
      </div>
    </transition>
  </div>
</template>

<script lang="ts" setup>
import { getPointBase, getChartData } from '@/api/points/standings';
import { getTableList } from '@/api/points/expertPointManage';
import * as echarts from 'echarts';
import MyCharts from '@/components/MyCharts.vue';
import useUserStore from '@/store/modules/user';

const userStore = useUserStore();
const roles = ref(userStore.roles);
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const defaultAvatar = new URL('@/assets/images/avatar.png', import.meta.url).href;
const { perform_work_type } = toRefs<any>(proxy?.useDict('perform_work_type'));
const { sys_user_sex } = toRefs<any>(proxy?.useDict('sys_user_sex'));
const performWorkType = computed(() => perform_work_type.value);
const performWorkTypeObj = computed(() => {
  let obj: any = {};
  performWorkType.value.forEach((item: any) => {
    obj[item.value] = item.label;
  });
  return obj;
});
const sysUserSex = computed(() => sys_user_sex.value);
let sexObj = computed(() => {
  let obj = {};
  sysUserSex.value.forEach((item: any) => {
    obj[item.value] = item.label;
  });
  return obj;
});
const expertInfo = ref({
  id: '',
  avatar: defaultAvatar,
  name: '',
  sex: '',
  birthDate: '',
  performWorkId: [],
  tag: [],
  rank: 0,
  score: 0,
  scoreStatus: null
});
const tipJson = {
  3: '积分异常，待管理员复核。',
  1: '经复核，账号积分存在问题，暂时冻结。'
};
const otherInfo = ref({
  contact: {
    label: '联系方式',
    value: ''
  },
  workUnit: {
    label: '工作单位',
    value: ''
  },
  duty: {
    label: '职务',
    value: ''
  },
  school: {
    label: '毕业院校',
    value: ''
  },
  email: {
    label: '邮箱',
    value: ''
  }
});
const getExpertInfo = async () => {
  if (!roles.value.includes('expert')) return;
  let res = await getPointBase();
  if (res.code != 200) {
    ElNotification({
      title: '提示',
      message: res.msg,
      type: 'error'
    });
    return;
  }
  expertInfo.value = {
    id: res.data.expertId,
    avatar: res.data.photograph || defaultAvatar,
    name: res.data.expertName,
    sex: res.data.sex,
    birthDate: res.data.birthDate.split(' ')[0],
    performWorkId: res.data.performWorkId?.replace(/\r/, '').split(',') || [],
    tag: res.data.rewardTitle || [],
    rank: res.data.rank,
    score: +res.data.points,
    scoreStatus: res.data.checkStatus
  };
  otherInfo.value.contact.value = res.data.contact;
  otherInfo.value.workUnit.value = res.data.workUnit;
  otherInfo.value.duty.value = res.data.duty;
  otherInfo.value.school.value = res.data.graduateSchool;
  otherInfo.value.email.value = res.data.email;
};

interface Header {
  label: string;
  prop: string;
  align?: 'center' | 'left' | 'right';
  minWidth?: string | number;
}

const headers = ref<Header[]>([
  {
    label: '排名',
    prop: 'rank'
  },
  {
    label: '专家姓名',
    prop: 'expertName'
  },
  {
    label: '联系方式',
    prop: 'contact'
  },
  {
    label: '职务',
    prop: 'expertPost'
  },
  {
    label: '工作单位',
    prop: 'workUnit'
  },
  {
    label: '积分',
    prop: 'points'
  }
]);
const expertList = ref([]);
const getList = async () => {
  let res = await getTableList(page.value);
  expertList.value = res.rows;
  page.value.total = res.total;
};
const page = ref({
  pageNum: 1,
  pageSize: 15,
  total: 0
});
const options = ref(null);
const setExpertLeaveTopFive = (data: any, xData: any) => {
  options.value = {
    grid: {
      top: 30,
      left: 16,
      right: 16,
      bottom: 16,
      containLabel: true
    },
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'shadow'
      }
    },
    legend: {
      show: true,
      textStyle: {
        color: '#fff'
      },
      itemWidth: 16,
      itemHeight: 16,
      right: 16,
      selectedMode: false,
      data: ['积分']
    },
    xAxis: {
      axisLabel: {
        color: '#a4aab5',
        fontSize: 12,
        fontWeight: 400
      },
      axisTick: {
        show: false
      },
      axisLine: {
        lineStyle: {
          color: '#1d314d'
        }
      },
      splitLine: {
        lineStyle: {
          color: '#1d314d'
        }
      },
      type: 'value'
    },
    yAxis: {
      data: xData.map((e: any) => e || '-'),
      inverse: true,
      axisLabel: {
        color: '#a4aab5',
        fontSize: 12,
        fontWeight: 700
      },
      axisLine: {
        show: false
      },
      axisTick: {
        show: false
      },
      splitLine: {
        lineStyle: {
          color: '#1d314d'
        }
      },
      type: 'category'
    },
    series: [
      {
        realtimeSort: true,
        name: '积分',
        data: data,
        type: 'bar',
        barMaxWith: '20%',
        barWidth: 15,
        itemStyle: {
          color: new echarts.graphic.LinearGradient(1, 0, 0, 0, [
            { offset: 0, color: '#1978e5' },
            { offset: 1, color: 'rgba(25,120,299, 0)' }
          ])
        }
      }
    ],
    animationDuration: 0,
    animationDurationUpdate: 3000,
    animationEasing: 'linear',
    animationEasingUpdate: 'linear'
  };
};
const activeDays = ref(30);
const changeDays = (time: any) => {
  activeDays.value = time;
};
const getChart = async (day: any) => {
  let res = await getChartData({ rangeDay: day });
  if (res.code != 200) {
    ElNotification({
      title: '提示',
      message: res.msg,
      type: 'error'
    });
    return;
  }
  setExpertLeaveTopFive(res.data.pointX, res.data.nameY);
};
watch(
  activeDays,
  async (n) => {
    await proxy?.$nextTick();
    await getChart(n);
  },
  {
    deep: true,
    immediate: true
  }
);
const gotoDetail = (id: any) => {
  proxy?.$router.push({
    path: '/points/detail',
    query: { id, type: 'detail' }
  });
};
onMounted(() => {
  getExpertInfo();
  getList();
});
</script>

<style lang="scss" scoped>
.info-right {
  width: calc(20% - 20px);
  font-size: 20px;
  color: var(--el-color-primary);

  .score-status {
    color: var(--el-color-danger);
  }
}

.rank-table {
  height: calc(100% - 75px);
}

.model-title {
  margin-bottom: 24px;
  font-size: 20px;
  font-weight: bold;
}

.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: 100%;

  &:hover {
    box-shadow: var(--el-box-shadow-light);
  }

  .chart-title {
    position: absolute;
    top: 10px;
    left: 10px;
    color: #fff;
    font-weight: bold;
    line-height: 20px;
    width: calc(100% - 20px);
  }
}

.card-title {
  position: absolute;
  top: 10px;
  left: 20px;
  font-weight: bold;
  font-size: 20px;
  line-height: 20px;
  width: calc(100% - 20px);
}

.card-content {
  display: flex;
  align-items: center;
  position: relative;
  font-size: 14px;

  .card-title {
    font-size: 16px;
  }
}

.expert-base-info {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  border-top: 1px solid #ddd;
  border-left: 1px solid #ddd;
  font-size: 14px;

  .base-info-item {
    border-bottom: 1px solid #ddd;
    border-right: 1px solid #ddd;
    min-height: 40px;
    line-height: 38px;
    display: flex;
    justify-content: center;
    align-items: center;
    .base-info-label {
      width: 120px;
      padding: 0 5px;
      height: 100%;
      display: flex;
      align-items: center;
      justify-content: center;
      border-right: 1px solid #ddd;
      background-color: #f9f9f9;
    }

    .base-info-value {
      flex: 1;
      padding: 0 5px;
    }
  }
}

.expert-info {
  border-top: 1px solid #ddd;
  border-left: 1px solid #ddd;
  box-sizing: border-box;

  & > div {
    border-right: 1px solid #ddd;
    height: 120px;

    &.avatar {
      width: 120px;
      padding: 10px;
      border-bottom: 1px solid #ddd;
      display: flex;
      align-items: center;
      justify-content: center;

      img {
        width: auto;
        height: auto;
        max-width: 100%;
        max-height: 100%;
      }
    }

    &.info {
      width: 25%;
      line-height: 39px;

      & > div {
        display: flex;
        align-items: center;
        border-bottom: 1px solid #ddd;

        .info-label {
          width: 80px;
          padding: 0 10px;
          border-right: 1px solid #ddd;
          font-weight: bold;
          background-color: #f9f9f9;
          text-align: center;
        }

        .info-value {
          flex: 1;
          padding: 0 10px;
        }
      }
    }

    &.tag {
      flex: 1;
      line-height: 59px;

      & > div {
        border-bottom: 1px solid #ddd;

        .info-label {
          width: 100px;
          padding: 0 10px;
          border-right: 1px solid #ddd;
          font-weight: bold;
          background-color: #f9f9f9;
          text-align: center;
        }

        .info-value {
          flex: 1;
          padding: 0 10px;
        }
      }
    }
  }
}

.border-right {
  border-right: 1px solid #ddd;
}

.color-click {
  color: var(--el-color-primary);
  cursor: pointer;
}

.tip {
  color: #999;
  font-size: 12px;
  margin-top: 8px;
}
</style>
