<template>
  <div class="kpi-dict-page">
    <!-- 页头 -->
    <div class="page-header">
      <h3>KPI字典</h3>
      <div class="header-actions">
        <el-button @click="openTemplateDialog">📋 从模板创建</el-button>
        <el-button type="primary" @click="openCreate">+ 新建KPI</el-button>
      </div>
    </div>

    <div class="main-layout">
      <!-- 左侧：BSC分类导航树 -->
      <div class="left-tree">
        <div class="tree-header">BSC分类导航</div>
        <el-tree
          ref="treeRef"
          :data="categoryTree"
          node-key="key"
          :props="{ label: 'label', children: 'children' }"
          :default-expanded-keys="defaultExpanded"
          :show-checkbox="true"
          :check-strictly="true"
          @check="onTreeCheck"
          highlight-current
        >
          <template #default="{ node, data }">
            <span class="tree-node">
              <span class="tree-node-label">{{ data.label }}</span>
              <el-tag size="small" :type="data.children && data.children.length > 0 ? '' : 'info'" class="tree-count">{{ data.count }}</el-tag>
            </span>
          </template>
        </el-tree>
      </div>

      <!-- 右侧：搜索+表格 -->
      <div class="right-content">
        <!-- 企业选择器 -->
        <div class="entity-selector">
          <span class="entity-label">🌐 企业：</span>
          <el-select v-model="currentEntityId" @change="onEntityChange" style="width:200px">
            <el-option
              v-for="e in entities"
              :key="e.id"
              :label="e.short_name + ' / ' + e.name"
              :value="e.id"
            />
          </el-select>
          <span class="entity-name-hint">{{ currentEntityName }}</span>
        </div>

        <!-- 搜索栏 -->
        <div class="search-bar">
          <el-input v-model="searchKeyword" placeholder="搜索KPI名称/编码" clearable style="width:220px" @clear="loadKpis" @keyup.enter="loadKpis" />
          <el-select v-model="searchDimension" placeholder="维度" clearable style="width:110px" @change="loadKpis">
            <el-option label="财务" value="finance" />
            <el-option label="客户" value="customer" />
            <el-option label="内部流程" value="process" />
            <el-option label="学习成长" value="learning" />
          </el-select>
          <el-select v-model="searchCategory" placeholder="二级类别" clearable style="width:140px" @change="loadKpis">
            <el-option v-for="c in categoryOptions" :key="c.value" :label="c.label" :value="c.value" />
          </el-select>
          <el-select v-model="searchStatus" placeholder="状态" clearable style="width:100px" @change="loadKpis">
            <el-option label="活跃" value="active" />
            <el-option label="已归档" value="disabled" />
          </el-select>
          <el-button type="primary" @click="loadKpis">查询</el-button>
          <el-button @click="resetSearch">重置</el-button>
        </div>

        <!-- 批量操作栏 -->
        <div class="batch-bar" v-if="selectedIds.length > 0">
          <span class="selected-info">已选 {{ selectedIds.length }} 条</span>
          <el-button size="small" @click="batchDelete">批量删除</el-button>
          <el-button size="small" @click="batchExport">导出CSV</el-button>
          <el-button size="small" @click="selectedIds=[]">取消选择</el-button>
        </div>

        <!-- 表格 -->
        <el-table
          :data="kpis"
          v-loading="loading"
          style="width:100%"
          @selection-change="onSelectionChange"
          @row-click="(row) => $router.push('/kpis/' + row.id)"
          border
          stripe
          size="small"
        >
          <el-table-column type="selection" width="40" />
          <el-table-column prop="kpi_code" label="编码" width="120">
            <template #default="{ row }">
              <span class="kpi-code">{{ row.kpi_code }}</span>
            </template>
          </el-table-column>
          <el-table-column prop="kpi_name" label="名称" min-width="170" />
          <el-table-column prop="dimension" label="维度" width="70">
            <template #default="{ row }">
              <el-tag :type="dimTagType(row.dimension)" size="small">{{ dimLabel(row.dimension) }}</el-tag>
            </template>
          </el-table-column>
          <el-table-column label="二级类别" width="90">
            <template #default="{ row }">{{ catLabel(row.category) }}</template>
          </el-table-column>
          <el-table-column prop="target_value" label="目标值" width="110">
            <template #default="{ row }">
              <span class="target-cell">{{ targetLabel(row) }} <b>{{ formatTarget(targetForRow(row), row.unit) }}</b></span>
            </template>
          </el-table-column>
          <el-table-column prop="frequency" label="频率" width="70">
            <template #default="{ row }">{{ freqLabel(row.frequency) }}</template>
          </el-table-column>
          <el-table-column prop="data_source_type" label="数据源" width="70">
            <template #default="{ row }">{{ sourceLabel(row.data_source_type) }}</template>
          </el-table-column>
          <el-table-column label="所属地图" width="120">
            <template #default="{ row }">
              <span v-if="row.map_title" style="color:#409eff;font-size:12px;">{{ row.map_title }}</span>
              <span v-else style="color:#ccc">-</span>
            </template>
          </el-table-column>
          <el-table-column label="当前值" width="100">
            <template #default="{ row }">
              <span v-if="row.actual_value !== null" :class="'status-' + (row.alert_level || 'none')">
                {{ row.actual_value }}{{ row.unit }}
              </span>
              <span v-else style="color:#ccc">-</span>
            </template>
          </el-table-column>
          <el-table-column label="来源" width="70">
            <template #default="{ row }">
              <el-tag v-if="row.is_system" size="small" type="info">系统</el-tag>
              <el-tag v-else size="small" type="success">自定义</el-tag>
            </template>
          </el-table-column>
          <el-table-column label="预警" width="70">
            <template #default="{ row }">
              <el-tag v-if="row.alert_level && row.alert_level !== 'none'" :type="row.alert_level === 'red' ? 'danger' : row.alert_level === 'yellow' ? 'warning' : 'success'" size="small">
                {{ row.alert_level === 'red' ? '红灯' : row.alert_level === 'yellow' ? '黄灯' : '绿灯' }}
              </el-tag>
              <span v-else style="color:#ccc">-</span>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="130" fixed="right">
            <template #default="{ row }">
              <el-button size="small" text type="primary" @click.stop="$router.push('/kpis/' + row.id)">详情</el-button>
              <el-button size="small" text type="primary" @click.stop="openEdit(row)">编辑</el-button>
              <el-button v-if="row.status === 'active'" size="small" text type="danger" @click.stop="doDelete(row.id)">归档</el-button>
              <el-button v-else size="small" text type="success" @click.stop="doRestore(row.id)">恢复</el-button>
            </template>
          </el-table-column>
        </el-table>

        <el-empty v-if="!loading && kpis.length === 0" description="暂无KPI数据，请新建或搜索其他条件" />

        <!-- 分页 -->
        <div class="pagination-bar">
          <span class="total-info">共 {{ total }} 条</span>
          <el-pagination
            v-model:current-page="page"
            :page-size="pageSize"
            :total="total"
            layout="prev, pager, next"
            @current-change="loadKpis"
          />
        </div>
      </div>
    </div>

    <!-- 新建/编辑对话框 -->
    <MyDialog v-model="showForm" :title="editMode ? '编辑KPI' : '新建KPI'" :width="640">
      <!-- KPI设计引导（五步法·五规则，新建时显示） -->
      <div v-if="!editMode" class="design-guide">
        <el-collapse v-model="guideOpen">
          <el-collapse-item name="guide">
            <template #title>
              <span class="guide-title">📐 KPI设计引导（五步法 · 五规则）</span>
            </template>
            <div class="guide-steps">
              <div v-for="(s, i) in guideSteps" :key="i" class="guide-step">
                <span class="step-no">{{ i + 1 }}</span>
                <div class="step-body">
                  <div class="step-title">{{ s.title }}</div>
                  <div class="step-desc">{{ s.desc }}</div>
                  <el-input v-model="designDraft[s.field]" :placeholder="s.placeholder" size="small" />
                </div>
              </div>
            </div>
            <div class="rule-checks">
              <div class="rule-title">五规则实时校验</div>
              <div v-for="c in designChecks" :key="c.label" class="rule-check">
                <span :class="c.pass ? 'ok' : 'fail'">{{ c.pass ? '✅' : '❌' }}</span>
                <span>{{ c.label }}</span>
                <span v-if="c.note" class="rule-note">{{ c.note }}</span>
              </div>
            </div>
          </el-collapse-item>
        </el-collapse>
      </div>
      <el-form :model="form" label-width="110px" size="small">
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="KPI编码"><el-input v-model="form.kpi_code" :disabled="editMode" /></el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="KPI名称"><el-input v-model="form.kpi_name" /></el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="维度">
              <el-select v-model="form.dimension" style="width:100%" @change="onDimensionChange">
                <el-option label="财务" value="finance" />
                <el-option label="客户" value="customer" />
                <el-option label="内部流程" value="process" />
                <el-option label="学习成长" value="learning" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="二级类别">
              <el-select v-model="form.category" style="width:100%" :disabled="!form.dimension">
                <el-option v-for="c in categoryOptions" :key="c.value" :label="c.label" :value="c.value" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="目标值(月)"><el-input-number v-model="form.target_monthly" :min="0" style="width:100%" /></el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="目标值(季)">
              <el-input-number v-model="form.target_quarterly" :min="0" style="width:100%" />
              <div v-if="derivedPreview.quarterly !== null" class="derive-hint">↳ 自动={{ derivedPreview.quarterly }}</div>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="目标值(年)">
              <el-input-number v-model="form.target_yearly" :min="0" style="width:100%" />
              <div v-if="derivedPreview.yearly !== null" class="derive-hint">↳ 自动={{ derivedPreview.yearly }}</div>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="单位"><el-input v-model="form.unit" placeholder="%, 元, 次, 个..." /></el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="频率">
              <el-select v-model="form.frequency" style="width:100%">
                <el-option label="月度" value="monthly" />
                <el-option label="周度" value="weekly" />
                <el-option label="季度" value="quarterly" />
                <el-option label="半年" value="half_year" />
                <el-option label="年度" value="yearly" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="指标类型">
              <el-select v-model="form.target_calc_type" style="width:100%">
                <el-option label="累计型（月×3=季，可乘）" value="accumulate" />
                <el-option label="比率型（季沿用月，不可乘）" value="ratio" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="数据源">
              <el-select v-model="form.data_source_type" style="width:100%">
                <el-option label="ERP自动" value="erp" />
                <el-option label="Excel导入" value="excel" />
                <el-option label="手工填报" value="manual" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="负责部门"><el-select v-model="form.responsible_dept" style="width:100%"><el-option v-for="d in depts" :key="d" :label="d" :value="d" /></el-select></el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="负责人"><el-select v-model="form.responsible_user" filterable style="width:100%"><el-option v-for="u in users" :key="u" :label="u" :value="u" /></el-select></el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="计算公式"><el-input v-model="form.formula" type="textarea" :rows="2" /></el-form-item>
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="绿灯阈值">
              <el-input v-model="form.threshold_green" placeholder="如 >=80" />
              <div class="threshold-hint">超过此值视为正常</div>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="黄灯阈值">
              <el-input v-model="form.threshold_yellow" placeholder="如 >=60" />
              <div class="threshold-hint">超过此值预警</div>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="红灯阈值">
              <el-input v-model="form.threshold_red" placeholder="如 <60" />
              <div class="threshold-hint">触发此值紧急</div>
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="所属Epic">
          <el-select v-model="form.epic" style="width:100%">
            <el-option v-for="i in 10" :key="i" :label="'Epic ' + i" :value="'Epic' + i" />
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="showForm=false">取消</el-button>
        <el-button type="primary" :loading="saving" @click="saveKPI">{{ editMode ? '保存' : '创建' }}</el-button>
      </template>
    </MyDialog>

    <!-- 从模板创建弹窗 -->
    <MyDialog v-model="showTemplateSelect" title="从模板创建KPI" :width="760">
      <div v-loading="templateLoading">
        <!-- 筛选栏 -->
        <div class="search-bar" style="margin-bottom:12px;">
          <el-input v-model="templateKeyword" placeholder="搜索模板名称/编码" clearable style="width:200px" />
          <el-select v-model="templateDimFilter" placeholder="维度" clearable style="width:110px">
            <el-option label="财务" value="finance" />
            <el-option label="客户" value="customer" />
            <el-option label="内部流程" value="process" />
            <el-option label="学习成长" value="learning" />
          </el-select>
          <el-button @click="loadTemplates">查询</el-button>
        </div>
        <!-- 模板列表 -->
        <el-table :data="templates" style="width:100%" border stripe size="small"
          :highlight-current-row="true"
          @current-change="onTemplateSelect"
        >
          <el-table-column type="index" width="40" />
          <el-table-column prop="kpi_code" label="编码" width="120">
            <template #default="{ row }"><span class="kpi-code">{{ row.kpi_code }}</span></template>
          </el-table-column>
          <el-table-column prop="kpi_name" label="名称" min-width="140" />
          <el-table-column prop="dimension" label="维度" width="70">
            <template #default="{ row }"><el-tag :type="dimTagType(row.dimension)" size="small">{{ dimLabel(row.dimension) }}</el-tag></template>
          </el-table-column>
          <el-table-column label="类别" width="80">
            <template #default="{ row }">{{ catLabel(row.category) }}</template>
          </el-table-column>
          <el-table-column prop="unit" label="单位" width="60" />
          <el-table-column prop="target_value" label="建议目标" width="80">
            <template #default="{ row }">{{ row.target_value ?? '-' }}</template>
          </el-table-column>
          <el-table-column prop="description" label="说明" min-width="120" show-overflow-tooltip />
          <el-table-column label="来源" width="60">
            <template #default="{ row }">
              <el-tag v-if="row.is_system" size="small" type="info">系统</el-tag>
              <el-tag v-else size="small" type="success">自定义</el-tag>
            </template>
          </el-table-column>
        </el-table>
        <div v-if="!selectedTemplate" style="color:#999;font-size:13px;margin-top:8px;">请选择一个模板，然后填写实例化信息</div>
        <!-- 实例化表单 -->
        <div v-if="selectedTemplate" class="instantiate-form" style="margin-top:12px;border-top:1px solid #eee;padding-top:12px;">
          <div style="font-size:14px;font-weight:500;margin-bottom:8px;">从「{{ selectedTemplate.kpi_name }}」创建KPI实例</div>
          <el-form :model="instantiateForm" label-width="90px" size="small">
            <el-row :gutter="16">
              <el-col :span="12">
                <el-form-item label="KPI编码"><el-input v-model="instantiateForm.kpi_code" :placeholder="selectedTemplate.kpi_code" /></el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="KPI名称"><el-input v-model="instantiateForm.kpi_name" :placeholder="selectedTemplate.kpi_name" /></el-form-item>
              </el-col>
            </el-row>
            <el-row :gutter="16">
              <el-col :span="12">
                <el-form-item label="目标值"><el-input-number v-model="instantiateForm.target_value" :min="0" style="width:100%" :placeholder="String(selectedTemplate.target_value ?? '')" /></el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="数据源">
                  <el-select v-model="instantiateForm.data_source_type" style="width:100%">
                    <el-option label="ERP自动" value="erp" />
                    <el-option label="Excel导入" value="excel" />
                    <el-option label="手工填报" value="manual" />
                  </el-select>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row :gutter="16">
              <el-col :span="12">
                <el-form-item label="负责部门"><el-select v-model="instantiateForm.responsible_dept" style="width:100%"><el-option v-for="d in depts" :key="d" :label="d" :value="d" /></el-select></el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="负责人"><el-select v-model="instantiateForm.responsible_user" filterable style="width:100%"><el-option v-for="u in users" :key="u" :label="u" :value="u" /></el-select></el-form-item>
              </el-col>
            </el-row>
          </el-form>
          <div style="color:#999;font-size:12px;margin-top:4px;">* 编码和名称不填则使用模板默认值，后续可在KPI字典中修改</div>
        </div>
      </div>
      <template #footer>
        <el-button @click="showTemplateSelect=false">取消</el-button>
        <el-button type="primary" :disabled="!selectedTemplate" @click="doInstantiate">从模板创建</el-button>
      </template>
    </MyDialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, computed } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { kpiApi, templateApi, dashboardApi, entityApi, userApi, orgApi } from '../api/index'
import MyDialog from '../components/MyDialog.vue'
import { useFormGuard, trackDialogForm } from '../composables/useFormGuard'

// ── 数据 ──
const kpis = ref<any[]>([])
const total = ref(0)
const loading = ref(false)
const page = ref(1)
const pageSize = 20

// ── 搜索筛选 ──
const searchKeyword = ref('')
const searchDimension = ref('')
const searchCategory = ref('')
const searchStatus = ref('active')

// ── 企业选择 ──
const entities = ref<any[]>([])
const currentEntityId = ref(Number(localStorage.getItem('cma_entity_id') || 1))
const currentEntityName = ref(localStorage.getItem('cma_entity_name') || '酣客')

// ── 分类树 ──
const categoryTree = ref<any[]>([])
const defaultExpanded = ref<string[]>([])
const treeRef = ref<any>(null)
const treeFilterDims = ref<string[]>([])
const treeFilterCats = ref<string[]>([])

// ── 多选 ──
const selectedIds = ref<number[]>([])

// ── 部门/用户选项 ──
const depts = ref<string[]>([])
const users = ref<string[]>([])

async function loadDepts() {
  try {
    const r: any = await orgApi.nodes()
    const raw: any[] = r.data || r || []
    const names = raw.map((n: any) => n.name).filter(Boolean)
    depts.value = [...new Set<string>(names)]
  } catch (e) {
    console.error('加载部门列表失败', e)
  }
}

async function loadUsers() {
  try {
    const r: any = await userApi.list()
    const raw: any[] = r.data || r || []
    users.value = raw.map((u: any) => u.name).filter(Boolean)
  } catch (e) {
    console.error('加载用户列表失败', e)
  }
}

// ── 新建/编辑表单 ──
const showForm = ref(false)
const editMode = ref(false)
const form = ref<any>({})
const saving = ref(false)

// 新建入口：重置表单 + 设计引导草稿
function openCreate() {
  editMode.value = false
  form.value = {}
  designDraft.value = {}
  guideOpen.value = ['guide']
  showForm.value = true
}

// ── KPI设计引导（五步法·五规则，对应 docs/kpi-design-rule.md）──
const guideOpen = ref(['guide'])
const guideSteps = [
  { field: 'duty', title: '① 明确岗位职责', desc: '这个KPI考核谁的什么岗位？岗位存在的价值是什么？', placeholder: '如：销售岗——负责新客户开拓与回款' },
  { field: 'customer', title: '② 分析客户是谁', desc: '服务对象：内部客户（上级/下游部门）+ 外部客户（终端/渠道）', placeholder: '如：外部客户（新签/续约）+ 内部（交付/财务）' },
  { field: 'requirement', title: '③ 分析客户需求', desc: '客户对这个岗位的期望标准是什么？', placeholder: '如：快速响应、按时交付、回款可控' },
  { field: 'output', title: '④ 确定成果输出', desc: '岗位需要产出什么可交付成果？（即本KPI，填入上方表单）', placeholder: '如：新签客户数、签约金额' },
  { field: 'factors', title: '⑤ 五因素设计指标', desc: '时间/数量/质量/成本/风险——对应下方表单字段', placeholder: '如：数量=新签数(目标值)、时间=频率(月度)、质量=满意度(阈值)' },
]
const designDraft = ref<Record<string, string>>({})

const designChecks = computed(() => {
  const f = form.value || {}
  const dimCount = kpis.value.filter((k: any) => k.dimension === f.dimension).length
  const hasTarget = f.target_monthly != null || f.target_quarterly != null || f.target_yearly != null || f.target_value != null
  return [
    { label: 'KPI名称已填（SMART·具体）', pass: !!f.kpi_name },
    { label: '已选维度（BSC四维平衡）', pass: !!f.dimension },
    { label: '已填单位（可衡量）', pass: !!f.unit },
    { label: '有目标值（可衡量·五因素数量）', pass: hasTarget },
    { label: '已选频率（SMART·有时限）', pass: !!f.frequency },
    { label: '已选负责人（责任到人）', pass: !!f.responsible_user },
    { label: '本维度KPI数量≤6（规则①）', pass: dimCount < 6, note: dimCount ? `当前${DIM_MAP[f.dimension] || ''}维度已有${dimCount}个，建议聚焦` : '' },
  ]
})

// ── 多粒度目标派生预览（填基准值后季/年自动提示，与后端 derive_cycle_targets 一致）──
const derivedPreview = computed(() => {
  const f = form.value || {}
  const type = f.target_calc_type || 'ratio'
  const freq = f.frequency || 'monthly'
  let base: number | null = null
  if (freq === 'yearly') base = f.target_yearly
  else if (freq === 'quarterly' || freq === 'half_year') base = f.target_quarterly
  else base = f.target_monthly
  if (base == null) base = f.target_value
  if (base == null) return { quarterly: null, yearly: null }
  let q: number | null = f.target_quarterly
  let y: number | null = f.target_yearly
  if (type === 'accumulate') {
    const m: number = f.target_monthly ?? base
    if (q == null) q = m * 3
    if (y == null) y = m * 12
  } else {
    if (q == null) q = base
    if (y == null) y = base
  }
  return { quarterly: f.target_quarterly == null ? q : null, yearly: f.target_yearly == null ? y : null }
})

// ── 编辑入口：列表行 → 弹窗编辑（与新建一致）──
function openEdit(row: any) {
  editMode.value = true
  form.value = {
    id: row.id,
    kpi_code: row.kpi_code,
    kpi_name: row.kpi_name,
    dimension: row.dimension,
    category: row.category,
    target_value: row.target_value,
    target_monthly: row.target_monthly,
    target_quarterly: row.target_quarterly,
    target_yearly: row.target_yearly,
    unit: row.unit,
    frequency: row.frequency,
    data_source_type: row.data_source_type,
    responsible_dept: row.responsible_dept,
    responsible_user: row.responsible_user,
    formula: row.formula,
    threshold_green: row.threshold_green,
    threshold_yellow: row.threshold_yellow,
    threshold_red: row.threshold_red,
    epic: row.epic,
    target_calc_type: row.target_calc_type,
  }
  showForm.value = true
}

// ── 未保存离开守卫 ──
const isDirty = ref(false)
const { markDirty, markClean } = useFormGuard(isDirty)
trackDialogForm(showForm, form, markDirty)

// ── 维度映射 ──
const DIM_MAP: Record<string, string> = { finance: '财务', customer: '客户', process: '内部流程', learning: '学习成长' }
const CAT_MAP: Record<string, string> = {
  revenue_growth: '收入增长', profitability: '盈利水平', cost_control: '成本费用',
  asset_efficiency: '资产效率', cash_risk: '现金流风控',
  customer_scale: '客户规模', customer_concentration: '客户集中度', customer_satisfaction: '客户满意',
  supply_chain: '供应链效率', delivery_quality: '交付质量', customer_mgmt: '客户管理', regulatory: '法规与社会',
  talent_pipeline: '人才梯队', employee_engagement: '员工敬业', innovation_capability: '创新资本',
  r_and_d: '研发管理',
}
const FREQ_MAP: Record<string, string> = { daily: '日', weekly: '周', monthly: '月', quarterly: '季', yearly: '年' }
const SOURCE_MAP: Record<string, string> = { erp: 'ERP', excel: 'Excel', manual: '手工' }

// 维度→二级类别 对照映射
const DIM_CAT_MAP: Record<string, string[]> = {
  finance: ['revenue_growth', 'profitability', 'cost_control', 'asset_efficiency', 'cash_risk'],
  customer: ['customer_scale', 'customer_concentration', 'customer_satisfaction'],
  process: ['supply_chain', 'delivery_quality', 'customer_mgmt', 'regulatory', 'r_and_d'],
  learning: ['talent_pipeline', 'employee_engagement', 'innovation_capability'],
}

// 二级类别选项（联动维度）
const categoryOptions = computed(() => {
  const dim = form.value?.dimension
  if (!dim) return []
  const catKeys = DIM_CAT_MAP[dim] || []
  return catKeys.map(key => ({ value: key, label: CAT_MAP[key] || key }))
})

// 所有二级类别（搜索栏用）
const allCategories = computed(() => {
  const seen = new Set<string>()
  const result: { value: string; label: string }[] = []
  for (const key in DIM_CAT_MAP) {
    for (const cat of DIM_CAT_MAP[key]) {
      if (!seen.has(cat)) {
        seen.add(cat)
        result.push({ value: cat, label: CAT_MAP[cat] || cat })
      }
    }
  }
  return result
})

function dimLabel(d: string) { return DIM_MAP[d] || d }
function catLabel(c: string) { return CAT_MAP[c] || c }
function freqLabel(f: string) { return FREQ_MAP[f] || f }
function sourceLabel(s: string) { return SOURCE_MAP[s] || s }
function dimTagType(d: string) { return ({ finance: '', customer: 'success', process: 'warning', learning: 'info' } as any)[d] || '' }

function formatTarget(val: number, unit: string) {
  if (val === null || val === undefined) return '-'
  if (val >= 10000) return (val / 10000).toFixed(0) + '万' + (unit || '')
  return val + (unit || '')
}

// 多粒度目标：按frequency取对应周期目标值
function targetForRow(row: any) {
  const freq = row.frequency || 'monthly'
  if (freq === 'quarterly' || freq === 'half_year') return row.target_quarterly ?? row.target_value
  if (freq === 'yearly') return row.target_yearly ?? row.target_value
  return row.target_monthly ?? row.target_value
}

function targetLabel(row: any) {
  const freq = row.frequency || 'monthly'
  if (freq === 'quarterly' || freq === 'half_year') return '季'
  if (freq === 'yearly') return '年'
  return '月'
}

// ── 加载分类树 ──
async function loadCategories() {
  try {
    const r: any = await kpiApi.listCategories()
    categoryTree.value = [
      { key: '_all', label: '全部', count: r.total, children: (r.tree || []).map((dim: any) => ({
        ...dim,
        children: (dim.children || []).map((cat: any) => ({ ...cat, label: CAT_MAP[cat.key] || cat.label }))
      })) }
    ]
    defaultExpanded.value = ['_all', ...(r.tree || []).map((n: any) => n.key)]
  } catch (e) {
    console.error('加载分类树失败', e)
  }
}

// ── 树节点勾选（支持多选）──
function onTreeCheck(data: any, { checkedKeys }: any) {
  // 从checkedKeys中分离出维度和分类
  const dimKeys = ['finance', 'customer', 'process', 'learning']
  const checkedDims = checkedKeys.filter((k: string) => dimKeys.includes(k))
  const checkedCats = checkedKeys.filter((k: string) => !dimKeys.includes(k) && k !== '_all')
  
  if (data.key === '_all' || checkedKeys.includes('_all')) {
    // 勾选全部=清空过滤
    treeFilterDims.value = []
    treeFilterCats.value = []
  } else {
    treeFilterDims.value = checkedDims
    treeFilterCats.value = checkedCats
  }
  loadKpis()
}

// ── 加载KPI列表 ──
async function loadKpis() {
  loading.value = true
  try {
    const params: any = { page: page.value, page_size: pageSize, entity_id: currentEntityId.value }
    if (searchKeyword.value) params.keyword = searchKeyword.value
    if (searchDimension.value) params.dimension = searchDimension.value
    if (searchCategory.value) params.category = searchCategory.value
    if (searchStatus.value) params.status = searchStatus.value
    if (treeFilterDims.value.length > 0 && !params.dimension) params.dimension = treeFilterDims.value.join(',')
    if (treeFilterCats.value.length > 0 && !params.category) params.category = treeFilterCats.value.join(',')

    const r: any = await kpiApi.list(params)
    kpis.value = r.data || []
    total.value = r.total || 0
  } catch (e) {
    console.error('加载KPI失败', e)
  }
  loading.value = false
}

// 获取当前值
async function loadActualValues() {
  try {
    const r: any = await dashboardApi.kpis({ role: 'ceo', period: 'month' })
    const vals = r.data || []
    const valMap: Record<number, any> = {}
    for (const v of vals) {
      valMap[v.id] = v
    }
    for (const kpi of kpis.value) {
      if (valMap[kpi.id]) {
        kpi.actual_value = valMap[kpi.id].actual_value
        kpi.alert_level = valMap[kpi.id].alert_level
      }
    }
  } catch (e) {
    // 静默失败
  }
}

function resetSearch() {
  searchKeyword.value = ''
  searchDimension.value = ''
  searchCategory.value = ''
  treeFilterDims.value = []
  treeFilterCats.value = []
  if (treeRef.value) treeRef.value.setCheckedKeys([])
  page.value = 1
  loadKpis()
}

// ── 多选 ──
function onSelectionChange(rows: any[]) {
  selectedIds.value = rows.map((r: any) => r.id)
}

function batchDelete() {
  ElMessageBox.confirm(`确定归档选中的 ${selectedIds.value.length} 条KPI？`, '提示').then(async () => {
    for (const id of selectedIds.value) {
      try { await kpiApi.delete(id) } catch (e) {}
    }
    ElMessage.success('批量删除完成')
    selectedIds.value = []
    loadKpis()
    loadCategories()
  }).catch(() => {})
}

function doRestore(id: number) {
  ElMessageBox.confirm('确定恢复此KPI？', '提示').then(async () => {
    await kpiApi.restore(id)
    ElMessage.success('已恢复')
    loadKpis()
  }).catch(() => {})
}

function batchExport() {
  const header = '编码,名称,维度,二级类别,目标值,频率,数据源,负责人,计算公式'
  const rows = kpis.value.map((k: any) =>
    [k.kpi_code, k.kpi_name, dimLabel(k.dimension), catLabel(k.category), k.target_value, freqLabel(k.frequency), sourceLabel(k.data_source_type), k.responsible_user, (k.formula || '')].join(',')
  )
  const bom = '\uFEFF' // Excel UTF-8 BOM
  const blob = new Blob([bom + header + '\n' + rows.join('\n')], { type: 'text/csv;charset=utf-8;' })
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url; a.download = 'KPI字典_' + new Date().toISOString().slice(0, 10) + '.csv'
  a.click()
  URL.revokeObjectURL(url)
}

// ── 新建/保存 ──
function onDimensionChange(val: string) {
  form.value.category = ''
}

async function saveKPI() {
  if (saving.value) return
  // KPI设计规范·基础门禁（仅新建模式；五步法成果输出 + SMART可衡量）
  if (!editMode.value) {
    if (!form.value.kpi_name || !form.value.dimension) {
      ElMessage.warning('请先填写 KPI名称 和 维度（KPI设计规范·五步法）')
      return
    }
    if (!form.value.unit || (form.value.target_monthly == null && form.value.target_quarterly == null && form.value.target_yearly == null && form.value.target_value == null)) {
      ElMessage.warning('请补充 单位 和 至少一个目标值（KPI设计规范·SMART可衡量）')
      return
    }
  }
  saving.value = true
  try {
    // 多粒度目标同步：按frequency将对应周期目标写入target_value(兼容评分/阈值等旧逻辑)
    const freq = form.value.frequency || 'monthly'
    let tv: any = null
    if (freq === 'quarterly' || freq === 'half_year') tv = form.value.target_quarterly
    else if (freq === 'yearly') tv = form.value.target_yearly
    else tv = form.value.target_monthly
    if (tv != null) form.value.target_value = tv
    if (editMode.value) {
      await kpiApi.update(form.value.id, form.value)
      ElMessage.success('保存成功')
    } else {
      await kpiApi.create(form.value)
      ElMessage.success('创建成功')
    }
    showForm.value = false
    markClean()
    loadKpis()
    loadCategories()
  } catch (e) {
    ElMessage.error(editMode.value ? '保存失败' : '创建失败')
  } finally {
    saving.value = false
  }
}

function doDelete(id: number) {
  ElMessageBox.confirm('确定删除此KPI？', '提示').then(async () => {
    try { await kpiApi.delete(id); ElMessage.success('已删除'); loadKpis(); loadCategories() }
    catch (e: any) { ElMessage.error(e?.response?.data?.detail || '删除失败') }
  }).catch(() => {})
}

// ── 从模板创建 ──
const showTemplateSelect = ref(false)
function openTemplateDialog() {
  showTemplateSelect.value = true
  loadTemplates()
}
const templateLoading = ref(false)
const templates = ref<any[]>([])
const templateKeyword = ref('')
const templateDimFilter = ref('')
const selectedTemplate = ref<any>(null)
const instantiateForm = ref<any>({})
trackDialogForm(showTemplateSelect, instantiateForm, markDirty)

async function loadTemplates() {
  templateLoading.value = true
  try {
    const params: any = {}
    if (templateKeyword.value) params.keyword = templateKeyword.value
    if (templateDimFilter.value) params.dimension = templateDimFilter.value
    const r: any = await templateApi.list(params)
    templates.value = r.data || []
  } catch (e) {
    console.error('加载模板失败', e)
  }
  templateLoading.value = false
}

function onTemplateSelect(tpl: any) {
  selectedTemplate.value = tpl
  instantiateForm.value = {
    kpi_code: '',
    kpi_name: '',
    target_value: undefined,
    data_source_type: 'manual',
    responsible_dept: '',
    responsible_user: '',
  }
}

async function doInstantiate() {
  if (!selectedTemplate.value) return
  try {
    const data: any = {}
    if (instantiateForm.value.kpi_code) data.kpi_code = instantiateForm.value.kpi_code
    if (instantiateForm.value.kpi_name) data.kpi_name = instantiateForm.value.kpi_name
    if (instantiateForm.value.target_value !== undefined && instantiateForm.value.target_value !== null)
      data.target_value = instantiateForm.value.target_value
    if (instantiateForm.value.data_source_type) data.data_source_type = instantiateForm.value.data_source_type
    if (instantiateForm.value.responsible_dept) data.responsible_dept = instantiateForm.value.responsible_dept
    if (instantiateForm.value.responsible_user) data.responsible_user = instantiateForm.value.responsible_user
    await templateApi.instantiate(selectedTemplate.value.id, data)
    ElMessage.success(`已从模板「${selectedTemplate.value.kpi_name}」创建KPI`)
    showTemplateSelect.value = false
    markClean()
    selectedTemplate.value = null
    instantiateForm.value = {}
    loadKpis()
    loadCategories()
  } catch (e: any) {
    ElMessage.error(e?.response?.data?.detail || '创建失败')
  }
}

// ── 企业选择 ──
async function loadEntities() {
  try {
    const r: any = await entityApi.list()
    entities.value = r.data || []
    // Find current entity name
    const cur = entities.value.find((e: any) => e.id === currentEntityId.value)
    if (cur) currentEntityName.value = cur.short_name || cur.name
  } catch (e) {
    console.error('加载企业列表失败', e)
  }
}

function onEntityChange(val: number) {
  const cur = entities.value.find((e: any) => e.id === val)
  currentEntityName.value = cur ? (cur.short_name || cur.name) : ''
  page.value = 1
  loadKpis()
  loadCategories()
}

onMounted(() => {
  loadEntities()
  loadCategories()
  loadKpis()
  loadDepts()
  loadUsers()
})
</script>

<style scoped>
.kpi-dict-page {
  height: 100%;
  display: flex;
  flex-direction: column;
}

/* ── KPI设计引导（五步法·五规则）── */
.design-guide {
  margin-bottom: 12px;
  border: 1px solid #d9e8ff;
  border-radius: 8px;
  background: #f8fbff;
  overflow: hidden;
}
.guide-title {
  font-weight: 600;
  font-size: 13px;
  color: #1f4e9c;
}
.guide-steps {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 4px 8px 10px;
}
.guide-step {
  display: flex;
  gap: 10px;
  align-items: flex-start;
}
.step-no {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: #409EFF;
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  margin-top: 2px;
}
.step-body {
  flex: 1;
}
.step-title {
  font-size: 13px;
  font-weight: 600;
  color: #303133;
}
.step-desc {
  font-size: 12px;
  color: #909399;
  margin: 2px 0 4px;
}
.rule-checks {
  border-top: 1px dashed #d9e8ff;
  padding: 10px 8px 4px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.rule-title {
  font-size: 13px;
  font-weight: 600;
  color: #1f4e9c;
}
.rule-check {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: #303133;
}
.rule-check .ok { color: #67C23A; }
.rule-check .fail { color: #F56C6C; }
.rule-note {
  color: #E6A23C;
  font-size: 12px;
}
.derive-hint {
  font-size: 12px;
  color: #409EFF;
  margin-top: 2px;
  line-height: 1.4;
}
.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
}
.page-header h3 {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
}
.header-actions {
  display: flex;
  gap: 8px;
}
.main-layout {
  display: flex;
  gap: 12px;
  flex: 1;
  overflow: hidden;
}
.left-tree {
  width: 260px;
  min-width: 260px;
  background: #fff;
  border-radius: 4px;
  border: 1px solid #e4e7ed;
  padding: 8px 0;
  overflow-y: auto;
}
.tree-header {
  padding: 8px 16px;
  font-size: 14px;
  font-weight: 600;
  color: #303133;
  border-bottom: 1px solid #f0f0f0;
  margin-bottom: 4px;
}
.tree-node {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex: 1;
  padding-right: 8px;
}
.tree-node-label {
  font-size: 13px;
}
.tree-count {
  font-size: 11px;
  min-width: 20px;
  text-align: center;
}
.right-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.entity-selector {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
  padding: 8px 12px;
  background: #f0f9ff;
  border-radius: 4px;
  border: 1px solid #d0e8ff;
}
.entity-label {
  font-size: 14px;
  font-weight: 500;
  color: #303133;
}
.entity-name-hint {
  font-size: 13px;
  color: #909399;
}
.search-bar {
  display: flex;
  gap: 8px;
  margin-bottom: 12px;
  align-items: center;
  flex-wrap: wrap;
}
.batch-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  background: #ecf5ff;
  border-radius: 4px;
  margin-bottom: 8px;
}
.selected-info {
  font-size: 13px;
  color: #409eff;
  font-weight: 500;
}
.kpi-code {
  font-family: 'Courier New', monospace;
  font-size: 12px;
  color: #606266;
}
.threshold-hint {
  font-size: 11px;
  color: #909399;
  line-height: 1.4;
  margin-top: 2px;
}
.status-red { color: #f56c6c; font-weight: 500; }
.status-yellow { color: #e6a23c; font-weight: 500; }
.status-green { color: #67c23a; font-weight: 500; }
.status-none { color: #606266; }
.pagination-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 12px;
}
.total-info {
  font-size: 13px;
  color: #909399;
}
:deep(.el-tree-node__content) {
  height: 32px;
}
</style>
