<template>
  <div class="page review-workbench">
    <div class="data-toolbar">
      <span class="data-toolbar__title">绩效考评</span>
      <span class="data-toolbar__sep">|</span>
      <span class="data-toolbar__meta">{{ data.targetUser?.realName || '—' }}</span>
      <span class="data-toolbar__sep">|</span>
      <span class="data-toolbar__meta">{{ data.period?.name || '—' }}</span>
      <span class="data-toolbar__spacer"></span>
      <span class="data-toolbar__meta">{{ data.period?.startDate }} ~ {{ data.period?.endDate }}</span>
    </div>

    <div v-if="data.targetUser" class="scoring-body">
      <div class="compare-grid-3__header">
        <span>证据 · 员工自评</span>
        <span class="compare-grid-3__self">自评分</span>
        <span>你的终评</span>
      </div>

      <div class="section-band">OKR 目标达成 · 满分 60</div>
      <div v-if="!okrRecords[0]?.keyResults?.length" class="panel-empty">暂无 OKR 记录</div>
      <div
        v-for="(kr, i) in okrRecords[0]?.keyResults || []"
        :key="kr.id || i"
        class="compare-grid-3"
      >
        <div>
          <div class="evidence-title">KR{{ i + 1 }} {{ kr.title }}</div>
          <div class="evidence-meta">
            实际 {{ kr.currentValue }} / {{ kr.targetValue }} · 完成率
            <span class="evidence-value">{{ krCompletionPct(kr) }}%</span>
            · {{ krStatusLabel(kr.status) }}
          </div>
        </div>
        <div class="compare-grid-3__self" :style="{ color: selfKrScoreColor(i) }">
          {{ selfKrScore(i) !== null ? selfKrScore(i) : '—' }}
        </div>
        <div>
          <el-select v-if="krScores[i]" v-model="krScores[i].score" size="small" class="score-control" placeholder="选择评级">
            <el-option v-for="grade in gradeOptions" :key="grade.value" :label="grade.label" :value="grade.value" />
          </el-select>
        </div>
      </div>
      <div class="section-subtotal">
        OKR 得分 = 平均 {{ krAvg.toFixed(2) }} × 60 =
        <strong>{{ computedOkrScore.toFixed(1) }} / 60</strong>
      </div>

      <div class="section-band section-band--spaced">绩效维度 · 满分 40</div>
      <div v-for="(dim, i) in dimScores" :key="dim.id || i" class="compare-grid-3">
        <div>
          <div class="evidence-title">{{ dim.name }}</div>
          <div v-if="selfDimDesc(dim.name)" class="evidence-meta">{{ selfDimDesc(dim.name) }}</div>
        </div>
        <div class="compare-grid-3__self">
          {{ selfDimScore(dim.name) !== null ? selfDimScore(dim.name) : '—' }}
        </div>
        <div>
          <el-input-number
            v-model="dim.score"
            :min="0"
            :max="dim.maxScore"
            :precision="1"
            size="small"
            controls-position="right"
            class="score-control"
          />
          <span class="score-unit">/ {{ dim.maxScore }}</span>
        </div>
      </div>
      <div class="section-subtotal">
        绩效得分 = <strong>{{ dimTotal.toFixed(1) }} / 40</strong>
      </div>

      <div class="section-band section-band--spaced">专项调整</div>
      <div class="compare-grid-3">
        <div class="evidence-title">加分（上限 5）</div>
        <div class="compare-grid-3__self adjustment-positive">+{{ data.selfScore?.bonus || 0 }}</div>
        <div>
          <el-input-number
            v-model="form.bonus"
            :min="0"
            :max="5"
            :precision="1"
            size="small"
            controls-position="right"
            class="score-control"
          />
        </div>
      </div>
      <div class="compare-grid-3">
        <div class="evidence-title">扣分</div>
        <div class="compare-grid-3__self">-{{ data.selfScore?.penalty || 0 }}</div>
        <div>
          <el-input-number
            v-model="form.penalty"
            :min="0"
            :precision="1"
            size="small"
            controls-position="right"
            class="score-control"
          />
        </div>
      </div>
      <div class="remark-row">
        <span class="uppercase-label">加减分说明</span>
        <el-input v-model="form.remark" type="textarea" :rows="2" placeholder="请填写加减分说明" />
      </div>

      <div class="review-summary-bar">
        <span class="uppercase-label">终评总分</span>
        <span class="review-summary-bar__score">
          {{ computedTotal.toFixed(1) }}
          <span class="summary-score-max">/ 100</span>
        </span>
        <span class="status-label">
          <span class="status-dot" :class="previewGradeDot"></span>
          {{ computedGrade }}
        </span>
        <span class="uppercase-label summary-diff" :style="{ color: diffColor }">
          自评 {{ selfTotal.toFixed(1) }} · 差异 {{ scoreDiff >= 0 ? '+' : '' }}{{ scoreDiff.toFixed(1) }}
        </span>
        <el-tooltip v-if="Math.abs(scoreDiff) >= 10" content="打分偏差较大，建议复核">
          <span class="summary-warning">!</span>
        </el-tooltip>
      </div>

      <div class="scoring-actions">
        <el-button
          v-if="!data.superiorScore"
          type="primary"
          @click="handleSubmit"
          :loading="submitting"
        >
          提交绩效考评
        </el-button>
        <template v-else>
          <span class="status-label">
            <span class="status-dot" :class="data.finalScore?.status === 'PUBLISHED' ? 'status-dot--active' : 'status-dot--warn'"></span>
            {{ data.finalScore?.status === 'PUBLISHED' ? '已发布' : '上级评分已提交，待发布' }}
          </span>
          <el-button
            v-if="data.finalScore && data.finalScore.status !== 'PUBLISHED'"
            type="success"
            @click="handlePublish"
            :loading="publishing"
          >
            发布绩效结果
          </el-button>
        </template>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted } from 'vue'
import { useRoute } from 'vue-router'
import { scoreApi, dimensionApi } from '../../api'
import { ElMessage } from 'element-plus'

const route = useRoute()
const data = ref({})
const submitting = ref(false)
const publishing = ref(false)
const form = reactive({ bonus: 0, penalty: 0, remark: '' })
const krScores = ref([])
const dimensions = ref([])
const dimScores = ref([])

const okrRecords = computed(() => data.value.okrRecords || [])

const krAvg = computed(() => {
  if (!krScores.value.length) return 0
  const sum = krScores.value.reduce((a, b) => a + b.score, 0)
  return sum / krScores.value.length
})

const computedOkrScore = computed(() => {
  const okrs = okrRecords.value
  if (okrs.length && okrs[0].keyResults?.length) {
    const n = okrs[0].keyResults.length
    const sum = krScores.value.reduce((a, b) => a + b.score, 0)
    return Math.round(sum / n * 60 * 10) / 10
  }
  return 0
})

const dimTotal = computed(() => Math.round(dimScores.value.reduce((s, d) => s + (d.score || 0), 0) * 10) / 10)

const computedTotal = computed(() => {
  return Math.round((computedOkrScore.value + dimTotal.value + form.bonus - form.penalty) * 10) / 10
})

const computedGrade = computed(() => {
  const t = computedTotal.value
  if (t >= 90) return 'S'
  if (t >= 75) return 'A'
  if (t >= 60) return 'B'
  return 'C'
})

const gradeOptions = [
  { label: '1.0 · 卓越', value: 1.0 },
  { label: '0.8 · 良好', value: 0.8 },
  { label: '0.6 · 达标', value: 0.6 },
  { label: '0.3 · 少量推进', value: 0.3 },
  { label: '0.0 · 未做', value: 0.0 }
]

const selfTotal = computed(() => Number(data.value.selfScore?.total || 0))
const scoreDiff = computed(() => Math.round((computedTotal.value - selfTotal.value) * 10) / 10)
const diffColor = computed(() =>
  Math.abs(scoreDiff.value) >= 10 ? 'var(--color-danger)' : 'var(--color-text-muted)'
)
const previewGradeDot = computed(() => {
  if (computedTotal.value >= 75) return 'status-dot--active'
  if (computedTotal.value >= 60) return 'status-dot--warn'
  return 'status-dot--danger'
})

// Parse self-assessment from commentsJson
const selfData = computed(() => {
  if (!data.value.selfScore?.commentsJson) return null
  try { return JSON.parse(data.value.selfScore.commentsJson) } catch { return null }
})

const selfKrScores = computed(() => selfData.value?.krScores || [])
const selfDimensions = computed(() => selfData.value?.dimensions || [])
const selfRemark = computed(() => selfData.value?.remark || '')

const selfOkrTotal = computed(() => {
  if (!selfKrScores.value.length) return 0
  const n = okrRecords.value[0]?.keyResults?.length || selfKrScores.value.length
  const sum = selfKrScores.value.reduce((a, b) => a + (b.score || 0), 0)
  return Math.round(sum / n * 60 * 10) / 10
})

const selfDimTotal = computed(() => {
  return Math.round(selfDimensions.value.reduce((s, d) => s + (d.score || 0), 0) * 10) / 10
})

const selfGrade = computed(() => {
  const t = (data.value.selfScore?.total) || 0
  if (t >= 90) return 'S'
  if (t >= 75) return 'A'
  if (t >= 60) return 'B'
  return 'C'
})

const computedOkrMaxScore = computed(() => {
  const okrs = okrRecords.value
  if (okrs.length && okrs[0]?.keyResults?.length) return 60
  return 60
})

function selfKrScore(idx) {
  return selfKrScores.value[idx]?.score ?? null
}

function selfDimScore(name) {
  const found = selfDimensions.value.find(d => d.name === name)
  return found ? found.score : null
}

function selfDimDesc(name) {
  const found = selfDimensions.value.find(d => d.name === name)
  return found?.description || ''
}

function krCompletionPct(kr) {
  if (!kr.targetValue) return 0
  return Math.min(100, Math.round((kr.currentValue / kr.targetValue) * 100))
}

function selfKrScoreColor(i) {
  const score = selfKrScore(i)
  if (score === null) return 'var(--color-text-muted)'
  return score >= 0.8 ? 'var(--color-success)' : 'var(--color-text-secondary)'
}

async function loadPage() {
  data.value = await scoreApi.getPage(route.query.periodId, route.params.userId)
  const okrs = okrRecords.value
  if (okrs.length && okrs[0].keyResults?.length) {
    krScores.value = okrs[0].keyResults.map(kr => ({ title: kr.title, score: 0.6 }))
  }

  // Load dimensions for the scoring form
  dimensions.value = await dimensionApi.list()
  dimScores.value = dimensions.value.map(d => ({
    id: d.id, name: d.name, maxScore: d.maxScore,
    score: selfDimScore(d.name) ?? Math.round(d.maxScore * 0.7 * 10) / 10
  }))
}

onMounted(async () => {
  await loadPage()
})

async function handleSubmit() {
  if (!form.remark) { ElMessage.warning('请填写加减分备注'); return }
  submitting.value = true
  try {
    const dimItems = dimScores.value.map(d => ({
      dimensionId: d.id, name: d.name, maxScore: d.maxScore,
      score: d.score
    }))
    await scoreApi.submitSuperior({
      periodId: route.query.periodId,
      userId: Number(route.params.userId),
      okrScore: computedOkrScore.value,
      kpiScore: dimTotal.value,
      bonus: form.bonus,
      penalty: form.penalty,
      commentsJson: JSON.stringify({
        krScores: krScores.value,
        dimensions: dimItems,
        remark: form.remark
      })
    })
    ElMessage.success('考评已提交，发布后员工可查看确认')
    await loadPage()
  } finally { submitting.value = false }
}

async function handlePublish() {
  publishing.value = true
  try {
    await scoreApi.publish({
      periodId: route.query.periodId,
      userId: Number(route.params.userId)
    })
    ElMessage.success('绩效结果已发布')
    await loadPage()
  } finally { publishing.value = false }
}

function krStatusLabel(s) { return { NOT_STARTED: '未开始', IN_PROGRESS: '进行中', COMPLETED: '已完成', BLOCKED: '阻塞' }[s] || s }
</script>

<style scoped>
.page { width: 100%; }
.review-workbench { background: var(--color-surface); }
.scoring-body { padding-bottom: 72px; }
.compare-grid-3__header {
  display: grid;
  grid-template-columns: 1.4fr 70px 1fr;
  padding: 8px 14px;
  background: var(--table-header-bg);
  border-bottom: 1px solid var(--toolbar-border);
  color: var(--color-text-muted);
  font-size: var(--label-font-size);
  font-weight: 600;
  letter-spacing: var(--label-letter-spacing);
  text-transform: var(--label-uppercase);
}
.section-band--spaced { margin-top: 8px; border-top: 1px solid var(--table-border); }
.panel-empty { color: var(--color-text-muted); text-align: center; padding: 24px; font-size: var(--font-size-sm); }
.evidence-title { color: var(--color-text); font-weight: 500; }
.evidence-meta { color: var(--color-text-muted); font-size: 11px; margin-top: 2px; }
.evidence-value { color: var(--color-brand); font-weight: 600; }
.section-subtotal {
  padding: 8px 14px;
  text-align: right;
  color: var(--color-brand);
  font-size: var(--font-size-sm);
  border-bottom: 1px solid var(--table-border);
}
.score-control { width: 140px; }
.score-unit { margin-left: 6px; color: var(--color-text-muted); font-size: 11px; }
.adjustment-positive { color: var(--color-success); }
.remark-row {
  display: grid;
  grid-template-columns: 120px 1fr;
  gap: 16px;
  align-items: start;
  padding: 12px 14px;
  border-bottom: 1px solid var(--table-border);
}
.review-summary-bar { position: sticky; bottom: 0; z-index: 2; }
.summary-score-max { font-size: 11px; color: var(--color-text-muted); font-weight: 400; }
.summary-diff { margin-left: auto; }
.summary-warning { color: var(--color-danger); cursor: help; font-size: 12px; }
.scoring-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 12px;
  padding: 12px 14px;
  border-top: 1px solid var(--toolbar-border);
}

@media (max-width: 1279px) {
  .compare-grid-3,
  .compare-grid-3__header {
    grid-template-columns: 1fr;
    gap: 6px;
  }
  .compare-grid-3__self { text-align: left; }
  .remark-row { grid-template-columns: 1fr; }
  .review-summary-bar { position: static; flex-wrap: wrap; }
  .summary-diff { margin-left: 0; width: 100%; }
}
</style>
