<template>
  <div class="radar-screen">
    <!-- 顶部标题栏 -->
    <div class="screen-header">
      <el-select v-model="selectedTeam" placeholder="请选择班组" class="team-select"
                 @change="loadData" size="large">
        <el-option v-for="t in teamList" :key="t" :label="t" :value="t" />
      </el-select>
      <div class="screen-title">班组成员画像大屏</div>
      <div class="header-right">
        <el-button
          v-hasPermi="['ledger:sync:all']"
          size="small" type="primary" plain
          :loading="syncing"
          class="sync-btn"
          @click="handleSync">
          同步台账
        </el-button>
      </div>
    </div>

    <!-- 主内容区 -->
    <div v-loading="loading" element-loading-background="rgba(0,0,0,0.6)" class="screen-body">
      <div class="member-grid">

        <!-- 对比分析卡（双行高，始终在第一位） -->
        <div class="member-card compare-card">
          <div class="card-title-bar">对比分析</div>
          <div ref="compareChartRef" class="compare-radar"></div>
          <div class="compare-selector">
            <span class="selector-label">选择对比者</span>
            <el-tag
              v-for="name in compareNames" :key="name"
              closable effect="dark" type="warning"
              class="compare-tag"
              @close="removeCompare(name)">{{ name }}</el-tag>
            <el-select v-if="compareNames.length < 2" v-model="addingName"
                       placeholder="+请选择" size="small" class="add-select"
                       @change="addCompare">
              <el-option v-for="m in memberList" :key="m.personName"
                         :label="m.personName" :value="m.personName" />
            </el-select>
          </div>
          <!-- 对比数据表 -->
          <table v-if="compareNames.length > 0" class="compare-table">
            <thead>
              <tr>
                <th>维度</th>
                <th v-for="name in compareNames" :key="name" class="col-person">{{ name }}</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="(dim, i) in dimensionNames" :key="i">
                <td>{{ dim }}</td>
                <td v-for="name in compareNames" :key="name"
                    :class="getScoreClass(getContribution(name, i))">
                  {{ getContribution(name, i) }}
                </td>
              </tr>
            </tbody>
          </table>
        </div>

        <!-- 成员卡片 -->
        <div
          v-for="member in memberList" :key="member.personName"
          class="member-card clickable-card"
          :class="getMemberBorderClass(member.totalScore)"
          @click="goToPortrait(member.personName)">
          <div class="card-name" :class="getNameClass(member.totalScore)">
            {{ member.personName }}（{{ member.totalScore }}分）
          </div>
          <div :ref="el => setChartRef(el, member.personName)" class="member-radar"></div>
        </div>

      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, onBeforeUnmount, nextTick, computed, watch } from 'vue'
import { ElMessage } from 'element-plus'
import * as echarts from 'echarts'
import { useRouter } from 'vue-router'
import { radarTeamList, radarMemberScores, syncLedgerAll } from '@/api/score/index'

defineOptions({ name: 'ScoreRadar' })

const router = useRouter()

function goToPortrait(personName) {
  const target = router.getRoutes().find(r => /[/]employeeProfile$/.test(r.path))
  if (target) {
    router.push({ path: target.path, query: { personName } })
  } else {
    ElMessage.warning('未找到员工画像页面，请确认菜单中已配置该页面')
  }
}

// ── 状态 ──────────────────────────────────────────────
const loading = ref(false)
const syncing = ref(false)
const teamList = ref([])
const selectedTeam = ref('')
const memberList = ref([])

// 对比
const compareNames = ref([])
const addingName = ref('')

// ECharts 实例 map: personName → instance
const chartMap = reactive({})
// 对比图
const compareChartRef = ref(null)
let compareChart = null

// member card refs: personName → DOM el
const cardRefs = reactive({})

// ── 计算属性 ──────────────────────────────────────────
const dimensionNames = computed(() => {
  if (!memberList.value.length) return []
  return (memberList.value[0].dimensions || []).map(d => d.dimensionName)
})

// ── 颜色规范 ──────────────────────────────────────────
function getMemberBorderClass(score) {
  if (score >= 85) return 'border-green'
  if (score < 75)  return 'border-red'
  return 'border-normal'
}
function getNameClass(score) {
  if (score >= 85) return 'name-green'
  if (score < 75)  return 'name-red'
  return ''
}
function getScoreClass(val) {
  if (val == null) return ''
  if (val >= 15) return 'score-green'
  if (val < 10)  return 'score-red'
  return ''
}

// ── 对比操作 ──────────────────────────────────────────
function addCompare(name) {
  if (!name || compareNames.value.includes(name)) return
  if (compareNames.value.length >= 2) return
  compareNames.value.push(name)
  addingName.value = ''
  nextTick(renderCompareChart)
}
function removeCompare(name) {
  compareNames.value = compareNames.value.filter(n => n !== name)
  nextTick(renderCompareChart)
}

function getContribution(personName, dimIndex) {
  const m = memberList.value.find(x => x.personName === personName)
  if (!m || !m.dimensions[dimIndex]) return '-'
  return Number(m.dimensions[dimIndex].contribution)
}

// ── 台账同步 ──────────────────────────────────────────
async function handleSync() {
  syncing.value = true
  try {
    const r = await syncLedgerAll()
    const d = r.data || {}
    ElMessage.success(`同步完成：新增 ${d.inserted ?? 0} 条，跳过 ${d.skipped ?? 0} 条`)
    if (selectedTeam.value) loadData()
  } catch (e) {
    ElMessage.error('同步失败，请查看后端日志')
  } finally {
    syncing.value = false
  }
}

// ── 数据加载 ──────────────────────────────────────────
async function loadTeams() {
  const r = await radarTeamList()
  teamList.value = r.data || []
  if (teamList.value.length) {
    selectedTeam.value = teamList.value[0]
    loadData()
  }
}

async function loadData() {
  if (!selectedTeam.value) return
  loading.value = true
  compareNames.value = []
  // 销毁旧图
  Object.values(chartMap).forEach(c => c && c.dispose())
  Object.keys(chartMap).forEach(k => delete chartMap[k])
  if (compareChart) { compareChart.dispose(); compareChart = null }

  const r = await radarMemberScores(selectedTeam.value).finally(() => loading.value = false)
  memberList.value = r.data || []
  await nextTick()
  memberList.value.forEach(m => renderMemberChart(m))
}

// ── ECharts 渲染 ──────────────────────────────────────
function setChartRef(el, name) {
  if (el) cardRefs[name] = el
}

function buildRadarIndicators(member) {
  return (member.dimensions || []).map(d => ({
    name: d.dimensionName,
    max: 40
  }))
}

function renderMemberChart(member) {
  const el = cardRefs[member.personName]
  if (!el) return
  const chart = echarts.init(el)
  chartMap[member.personName] = chart
  const values = (member.dimensions || []).map(d => Number(d.contribution))
  const color = member.totalScore >= 85 ? '#67C23A'
              : member.totalScore < 75  ? '#F56C6C'
              : '#E6A23C'
  chart.setOption(buildRadarOption(buildRadarIndicators(member), [{ name: member.personName, value: values, color }]))
}

function renderCompareChart() {
  if (!compareChartRef.value) return
  if (!compareChart) compareChart = echarts.init(compareChartRef.value)
  if (!compareNames.value.length || !memberList.value.length) {
    compareChart.clear(); return
  }
  const indicators = buildRadarIndicators(memberList.value[0])
  const COLORS = ['#E6A23C', '#409EFF']
  const series = compareNames.value.map((name, i) => {
    const m = memberList.value.find(x => x.personName === name)
    const values = m ? m.dimensions.map(d => Number(d.contribution)) : []
    return { name, value: values, color: COLORS[i] }
  })
  compareChart.setOption(buildRadarOption(indicators, series))
}

function buildRadarOption(indicators, series) {
  return {
    backgroundColor: 'transparent',
    radar: {
      indicator: indicators,
      shape: 'polygon',
      splitNumber: 4,
      center: ['50%', '52%'],
      radius: '65%',
      name: { textStyle: { color: '#a0c4ff', fontSize: 10 } },
      splitLine: { lineStyle: { color: 'rgba(100,149,237,0.3)' } },
      splitArea: { areaStyle: { color: ['rgba(100,149,237,0.05)', 'rgba(100,149,237,0.1)'] } },
      axisLine: { lineStyle: { color: 'rgba(100,149,237,0.4)' } }
    },
    series: [{
      type: 'radar',
      data: series.map(s => ({
        name: s.name,
        value: s.value,
        lineStyle: { color: s.color, width: 2 },
        itemStyle: { color: s.color },
        areaStyle: { color: s.color, opacity: 0.15 }
      })),
      symbol: 'circle',
      symbolSize: 4
    }],
    tooltip: {
      trigger: 'item',
      appendToBody: true,
      backgroundColor: 'rgba(10,30,60,0.9)',
      borderColor: '#1a4a8a',
      textStyle: { color: '#e0f0ff', fontSize: 12 }
    }
  }
}

// ── 响应式调整 ──────────────────────────────────────────
function resizeAll() {
  Object.values(chartMap).forEach(c => c && c.resize())
  compareChart && compareChart.resize()
}

onMounted(() => {
  loadTeams()
  window.addEventListener('resize', resizeAll)
})
onBeforeUnmount(() => {
  window.removeEventListener('resize', resizeAll)
  Object.values(chartMap).forEach(c => c && c.dispose())
  compareChart && compareChart.dispose()
})

watch(compareNames, () => nextTick(renderCompareChart), { deep: true })
</script>

<style scoped>
/* ── 整体背景 ── */
.radar-screen {
  background: #020c1e;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif;
  overflow: auto;
}

/* ── 顶部 ── */
.screen-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 20px;
  background: linear-gradient(180deg, #051535 0%, #020c1e 100%);
  border-bottom: 1px solid #1a4a8a;
  flex-shrink: 0;
}
.team-select { width: 160px; }
.team-select :deep(.el-input__wrapper) {
  background: #0a2050;
  border-color: #1a6aff;
  box-shadow: none;
}
.team-select :deep(.el-input__inner) { color: #7ecfff; }
.screen-title {
  font-size: 22px;
  font-weight: bold;
  color: #7ecfff;
  letter-spacing: 4px;
  text-shadow: 0 0 12px #1a6aff;
  border: 2px solid #1a6aff;
  padding: 4px 28px;
  border-radius: 4px;
}
.header-right { width: 160px; display: flex; justify-content: flex-end; align-items: center; }
.sync-btn { border-color: #1a6aff; color: #7ecfff; background: transparent; }

/* ── 主体 ── */
.screen-body { flex: 1; padding: 12px; }

/* ── 网格：5列，卡片等宽 ── */
.member-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  grid-auto-rows: minmax(220px, auto);
  gap: 10px;
}

/* ── 卡片基础 ── */
.member-card {
  background: #041228;
  border: 1px solid #1a4a8a;
  border-radius: 6px;
  padding: 8px;
  display: flex;
  flex-direction: column;
  position: relative;
  overflow: hidden;
}
.member-card::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: linear-gradient(90deg, transparent, #1a6aff, transparent);
}

/* 对比分析卡跨2行 */
.compare-card {
  grid-row: span 2;
}

/* ── 边框颜色 ── */
.border-green { border-color: #67C23A; }
.border-green::before { background: linear-gradient(90deg, transparent, #67C23A, transparent); }
.border-red   { border-color: #F56C6C; }
.border-red::before   { background: linear-gradient(90deg, transparent, #F56C6C, transparent); }
.border-normal { border-color: #1a4a8a; }

/* ── 卡片标题 ── */
.card-title-bar {
  font-size: 13px;
  font-weight: bold;
  color: #7ecfff;
  padding-bottom: 4px;
  border-bottom: 1px solid #1a4a8a;
  margin-bottom: 4px;
}
.card-name {
  font-size: 13px;
  font-weight: bold;
  color: #c8e6ff;
  text-align: center;
  padding: 4px 0 2px;
}
.name-green { color: #67C23A; }
.name-red   { color: #F56C6C; }

/* ── 雷达图容器 ── */
.member-radar {
  flex: 1;
  min-height: 170px;
}
.compare-radar {
  height: 200px;
}

/* ── 对比选择器 ── */
.compare-selector {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  padding: 6px 0;
  border-top: 1px solid #1a4a8a;
}
.selector-label { color: #7ecfff; font-size: 12px; }
.compare-tag { cursor: pointer; }
.add-select { width: 100px; }
.add-select :deep(.el-input__wrapper) {
  background: #0a2050;
  border-color: #1a6aff;
  box-shadow: none;
}
.add-select :deep(.el-input__inner) { color: #7ecfff; font-size: 12px; }

/* ── 对比数据表 ── */
.compare-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 11px;
  margin-top: 4px;
}
.compare-table th, .compare-table td {
  border: 1px solid #1a4a8a;
  padding: 3px 6px;
  color: #a0c4ff;
  text-align: center;
}
.compare-table th { background: #071e40; color: #7ecfff; }
.compare-table .col-person { min-width: 48px; }
.score-green { color: #67C23A; font-weight: bold; }
.score-red   { color: #F56C6C; font-weight: bold; }

.clickable-card {
  cursor: pointer;
  transition: box-shadow 0.2s, transform 0.2s;
}
.clickable-card:hover {
  box-shadow: 0 0 12px rgba(26, 106, 255, 0.6);
  transform: translateY(-2px);
}
</style>
