<template>
  <div class="report-page">
    <!-- 顶部 -->
    <div class="report-header">
      <h3 class="page-title">📊 CMA管理报表</h3>
      <div class="header-right">
        <el-select
          v-model="currentEntityId"
          size="small"
          style="width:180px"
          placeholder="选择企业"
          @change="onEntityChange"
        >
          <el-option v-for="e in entities" :key="e.id" :label="e.short_name + ' / ' + e.name" :value="e.id" />
        </el-select>
        <el-date-picker
          v-model="reportPeriod"
          type="month"
          placeholder="选择月份"
          value-format="YYYY-MM"
          size="small"
          style="width:140px"
          @change="onPeriodChange"
        />
        <el-button text size="small" :loading="loading" @click="loadAll">刷新</el-button>
        <el-button type="primary" size="small" @click="openDupont">📊 杜邦分析</el-button>
        <el-button type="success" size="small" @click="openSubjectManage">📋 科目打标</el-button>
      </div>
    </div>

    <!-- 标签页 -->
    <el-tabs v-model="activeTab" type="border-card" class="report-tabs">

      <!-- ════ 报表1：管理利润表 ════ -->
      <el-tab-pane label="💰 管理利润表" name="profit">
        <div v-loading="loading">
          <div class="report-desc">基于管理会计视角的利润结构分析：收入 → 变动成本 → 边际贡献 → 固定成本 → 息税前利润</div>
          <el-table :data="profitItems" border stripe size="small" style="width:100%;margin-top:12px;" :summary-method="profitSummary" show-summary>
            <el-table-column prop="name" label="项目" width="200">
              <template #default="{ row }">
                <span :style="{ fontWeight: row.is_total ? 700 : row.is_subtotal ? 600 : 400 }">{{ row.name }}</span>
              </template>
            </el-table-column>
            <el-table-column label="本期金额" width="160" align="right">
              <template #default="{ row }">
                <span :style="{ fontWeight: row.is_total ? 700 : 400, color: (row.name?.includes('利润') || row.name?.includes('贡献')) && row.value != null && row.value < 0 ? '#f56c6c' : '#333' }">
                  {{ row.value != null ? '¥ ' + row.value.toLocaleString() : '-' }}
                </span>
              </template>
            </el-table-column>
            <el-table-column label="上期金额" width="160" align="right">
              <template #default="{ row }">
                <span style="color:#999;">{{ row.prev_value != null ? '¥ ' + row.prev_value.toLocaleString() : '-' }}</span>
              </template>
            </el-table-column>
            <el-table-column label="环比变化" width="120" align="right">
              <template #default="{ row }">
                <span v-if="row.change_rate != null" :style="{ color: row.change_rate > 0 ? '#f56c6c' : row.change_rate < 0 ? '#67c23a' : '#999', fontWeight: 600 }">
                  {{ row.change_rate > 0 ? '↑' : '↓' }}{{ Math.abs(row.change_rate).toFixed(1) }}%
                </span>
                <span v-else style="color:#ccc;">-</span>
              </template>
            </el-table-column>
            <el-table-column label="占比" width="100" align="right">
              <template #default="{ row }">
                <span v-if="row.ratio != null" style="color:#666;">{{ row.ratio.toFixed(1) }}%</span>
                <span v-else style="color:#ccc;">-</span>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </el-tab-pane>

      <!-- ════ 新30号准则利润表 ════ -->
      <el-tab-pane label="📋 新30号准则" name="new30">
        <div v-loading="loadingNew30">
          <div class="report-desc">基于新30号准则的五板块利润表列报（2027版）。经营/投资/筹资分类列示，财务费用拆解。</div>

          <div class="new30-blocks">
            <div v-for="block in new30Blocks" :key="block.key" class="new30-block">
              <div class="new30-block-header" @click="block.expanded = !block.expanded">
                <span class="new30-toggle">{{ block.expanded ? '▼' : '▶' }}</span>
                <span class="new30-block-name">{{ block.name }}</span>
                <span class="new30-block-subtotal" :class="{ negative: block.subtotal < 0 }">
                  {{ block.subtotal != null ? formatMoney(block.subtotal) : '-' }}
                </span>
                <span class="new30-block-label">{{ block.subtotal_name }}</span>
                <span v-if="!block.has_real_data" class="new30-demo-tag">示例数据</span>
              </div>
              <div v-if="block.expanded" class="new30-block-body">
                <div v-for="item in block.items" :key="item.code" class="new30-item">
                  <span class="new30-item-name">{{ item.name }}</span>
                  <span class="new30-item-amount" :class="{ negative: item.effective != null && item.effective < 0 }">
                    {{ item.effective != null ? formatMoney(item.effective) : '-' }}
                  </span>
                  <span v-if="item.effective != null && block.subtotal != null && block.subtotal !== 0" class="new30-item-ratio">
                    {{ (Math.abs(item.effective) / Math.abs(block.subtotal) * 100).toFixed(1) }}%
                  </span>
                </div>
              </div>
            </div>
          </div>

          <div class="new30-net-profit" v-if="new30Format !== 'dual'">
            <div class="new30-profit-row">
              <span class="new30-profit-label">合计：</span>
              <span class="new30-profit-value" :class="{ negative: new30NetProfit < 0 }">
                {{ formatMoney(new30NetProfit) }}
              </span>
              <span class="new30-profit-name">净利润</span>
            </div>
          </div>

          <!-- 双列对比模式 -->
          <div v-if="new30Format === 'dual' && dualComparisonData" class="dual-comparison">
            <div class="dual-desc">新旧准则双列对比 — 旧准则（一行到底） vs 新准则（五板块）</div>

            <div class="dual-grid">
              <!-- 旧准则列 -->
              <div class="dual-col">
                <div class="dual-col-header old-col">旧准则格式</div>
                <el-table :data="dualComparisonData.old_format?.items || []" border stripe size="small" style="width:100%;">
                  <el-table-column prop="name" label="项目" width="180">
                    <template #default="{ row }">
                      <span :style="{ fontWeight: row.is_total ? 700 : row.is_subtotal ? 600 : 400 }">{{ row.name }}</span>
                    </template>
                  </el-table-column>
                  <el-table-column label="金额" width="140" align="right">
                    <template #default="{ row }">
                      <span :style="{ fontWeight: row.is_total ? 700 : 400 }">
                        {{ row.value != null ? '¥ ' + row.value.toLocaleString() : '-' }}
                      </span>
                    </template>
                  </el-table-column>
                </el-table>
              </div>

              <!-- 新准则列 -->
              <div class="dual-col">
                <div class="dual-col-header new-col">新30号准则格式</div>
                <div class="dual-blocks">
                  <div v-for="block in dualComparisonData.new_format?.blocks || []" :key="block.key" class="dual-block">
                    <div class="dual-block-header">
                      <span class="dual-block-name">{{ block.short_name }}</span>
                      <span class="dual-block-subtotal">{{ formatMoney(block.subtotal) }}</span>
                    </div>
                    <div v-for="item in block.items" :key="item.code" class="dual-block-item">
                      <span class="dual-item-name">{{ item.name }}</span>
                      <span class="dual-item-amount">{{ item.effective != null ? formatMoney(item.effective) : '-' }}</span>
                    </div>
                  </div>
                </div>
                <div class="dual-net-profit">
                  <span>净利润：</span>
                  <span class="dual-net-val">{{ formatMoney(dualComparisonData.new_format?.net_profit) }}</span>
                </div>
              </div>
            </div>
          </div>

          <div class="new30-footer">
            <el-button size="small" :type="new30Format === 'new' ? 'primary' : ''" @click="switchNew30Format('new')">新准则</el-button>
            <el-button size="small" :type="new30Format === 'old' ? 'primary' : ''" @click="switchNew30Format('old')">旧准则</el-button>
            <el-button size="small" :type="new30Format === 'dual' ? 'primary' : ''" @click="switchNew30Format('dual')">双列对比</el-button>
            <el-button size="small" @click="exportNew30">导出</el-button>
            <span v-if="new30DemoMode" class="new30-demo-hint">⚠️ 当前显示示例数据，科目打标后显示实际数据</span>
          </div>
        </div>
      </el-tab-pane>

      <!-- ════ 报表2：预算执行报告 ════ -->
      <el-tab-pane label="📋 预算执行报告" name="budget">
        <div v-loading="loading">
          <div class="report-desc">各KPI预算 vs 实际差异分析。正值=超预算，负值=节约。</div>
          <div class="summary-row" style="margin-top:12px;">
            <div class="stat-card blue"><div class="stat-val">{{ budgetSummary.total }}</div><div class="stat-label">KPI总数</div></div>
            <div class="stat-card green"><div class="stat-val">{{ budgetSummary.with_budget }}</div><div class="stat-label">有预算</div></div>
            <div class="stat-card red"><div class="stat-val">{{ budgetSummary.over_budget }}</div><div class="stat-label">超预算</div></div>
            <div class="stat-card gray"><div class="stat-val">{{ budgetSummary.under_budget }}</div><div class="stat-label">节约</div></div>
            <div class="stat-card yellow"><div class="stat-val">{{ budgetSummary.normal }}</div><div class="stat-label">正常</div></div>
          </div>
          <div style="display:flex;gap:8px;margin:12px 0;">
            <el-select v-model="budgetDim" placeholder="维度" clearable size="small" style="width:120px;" @change="loadBudget">
              <el-option v-for="d in dimensions" :key="d.value" :label="d.label" :value="d.value" />
            </el-select>
            <el-select v-model="budgetLevel" placeholder="状态" clearable size="small" style="width:120px;" @change="loadBudget">
              <el-option label="超预算" value="red" />
              <el-option label="预警" value="yellow" />
              <el-option label="正常" value="normal" />
            </el-select>
          </div>
          <el-table :data="budgetItems" border stripe size="small" style="width:100%;" @sort-change="onBudgetSort">
            <el-table-column prop="kpi_name" label="KPI名称" min-width="150" sortable="custom" />
            <el-table-column prop="dimension" label="维度" width="90">
              <template #default="{ row }">{{ dimLabel(row.dimension) }}</template>
            </el-table-column>
            <el-table-column label="实际值" width="120" align="right" prop="actual_value" sortable="custom">
              <template #default="{ row }">{{ row.actual_value != null ? row.actual_value.toLocaleString() : '-' }}</template>
            </el-table-column>
            <el-table-column label="预算值" width="120" align="right" prop="budget_value" sortable="custom">
              <template #default="{ row }">{{ row.budget_value != null ? row.budget_value.toLocaleString() : '-' }}</template>
            </el-table-column>
            <el-table-column label="差异额" width="120" align="right" prop="deviation_amount" sortable="custom">
              <template #default="{ row }">
                <span :style="{ color: row.deviation_amount > 0 ? '#f56c6c' : row.deviation_amount < 0 ? '#67c23a' : '#999' }">
                  {{ row.deviation_amount != null ? (row.deviation_amount > 0 ? '+' : '') + row.deviation_amount.toLocaleString() : '-' }}
                </span>
              </template>
            </el-table-column>
            <el-table-column label="差异率" width="100" align="right" prop="deviation_rate" sortable="custom">
              <template #default="{ row }">
                <el-tag v-if="row.deviation_rate != null" :type="row.alert_level === 'red' ? 'danger' : row.alert_level === 'yellow' ? 'warning' : 'success'" size="small">
                  {{ row.deviation_rate > 0 ? '+' : '' }}{{ row.deviation_rate.toFixed(1) }}%
                </el-tag>
                <span v-else style="color:#ccc;">-</span>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </el-tab-pane>

      <!-- ════ 预编报表（预算版三张报表） ════ -->
      <el-tab-pane label="📋 预编报表" name="proforma">
        <div v-loading="loadingProforma">
          <div class="report-desc">预算版三张报表：预算 vs 实际 vs 差异（口径与预算执行报告一致）。无预算映射的行显式标注，不填示例数据。</div>
          <div style="display:flex;gap:8px;margin:12px 0;align-items:center;">
            <el-radio-group v-model="proformaType" size="small" @change="loadProforma">
              <el-radio-button value="profit">预算版利润表</el-radio-button>
              <el-radio-button value="balance">预算版资产负债表</el-radio-button>
              <el-radio-button value="cash">预算版现金流量表</el-radio-button>
            </el-radio-group>
            <el-tag v-if="proformaBudgetVersion" size="small" type="info">预算版本: {{ proformaBudgetVersion }}</el-tag>
          </div>
          <el-table :data="proformaRows" border stripe size="small" style="width:100%;" :row-class-name="proformaRowClass">
            <el-table-column prop="name" label="项目" min-width="180" />
            <el-table-column label="预算值" width="130" align="right">
              <template #default="{ row }">{{ row.budget_value != null ? row.budget_value.toLocaleString() : (row.has_budget ? '-' : '—') }}</template>
            </el-table-column>
            <el-table-column label="实际值" width="130" align="right">
              <template #default="{ row }">{{ row.actual_value != null ? row.actual_value.toLocaleString() : '-' }}</template>
            </el-table-column>
            <el-table-column label="差异" width="140" align="right">
              <template #default="{ row }">
                <span v-if="row.subtotal" style="color:#909399;">小计</span>
                <span v-else-if="row.ratio_kpi" style="color:#909399;">比率型</span>
                <span v-else-if="!row.has_budget" style="color:#bbb;">无预算</span>
                <span v-else :style="{ color: row.deviation_amount > 0 ? '#f56c6c' : row.deviation_amount < 0 ? '#67c23a' : '#999' }">
                  {{ row.deviation_amount != null ? (row.deviation_amount > 0 ? '+' : '') + row.deviation_amount.toLocaleString() : '-' }}
                </span>
              </template>
            </el-table-column>
            <el-table-column label="差异率" width="110" align="right">
              <template #default="{ row }">
                <span v-if="row.subtotal" style="color:#909399;">—</span>
                <el-tag v-else-if="row.ratio_kpi" type="info" size="small">比率型</el-tag>
                <span v-else-if="!row.has_budget" style="color:#bbb;">无预算</span>
                <el-tag v-else-if="row.deviation_rate != null" :type="proformaRateType(row.deviation_rate)" size="small">
                  {{ row.deviation_rate > 0 ? '+' : '' }}{{ row.deviation_rate.toFixed(1) }}%
                </el-tag>
                <span v-else style="color:#ccc;">-</span>
              </template>
            </el-table-column>
            <el-table-column label="预算来源" width="110">
              <template #default="{ row }">
                <el-tag v-if="row.has_budget && !row.subtotal" :type="row.budget_source === 'budget_plan' ? 'success' : 'warning'" size="small">
                  {{ row.budget_source === 'budget_plan' ? '预算方案' : row.budget_source === 'target_split' ? '目标分摊' : '—' }}
                </el-tag>
                <span v-else style="color:#bbb;">—</span>
              </template>
            </el-table-column>
            <el-table-column prop="note" label="备注" min-width="200" show-overflow-tooltip>
              <template #default="{ row }"><span style="color:#909399;">{{ row.note || '' }}</span></template>
            </el-table-column>
          </el-table>
        </div>
      </el-tab-pane>

      <!-- ════ 报表3：KPI趋势报告 ════ -->
      <el-tab-pane label="📈 KPI趋势报告" name="trends">
        <div v-loading="loading">
          <div class="report-desc">选定KPI的历史趋势分析，含目标线标记。</div>
          <div style="display:flex;gap:8px;margin-top:12px;flex-wrap:wrap;">
            <el-select v-model="trendDim" placeholder="维度" clearable size="small" style="width:120px;" @change="loadTrends">
              <el-option v-for="d in dimensions" :key="d.value" :label="d.label" :value="d.value" />
            </el-select>
            <el-select v-model="trendKpiId" placeholder="选择KPI" clearable filterable size="small" style="width:200px;" @change="loadTrends">
              <el-option v-for="k in kpiOptions" :key="k.id" :label="k.kpi_name" :value="k.id" />
            </el-select>
            <el-select v-model="trendMonths" size="small" style="width:100px;" @change="loadTrends">
              <el-option label="12期" :value="12" />
              <el-option label="24期" :value="24" />
              <el-option label="30期" :value="30" />
            </el-select>
          </div>
          <div v-if="trendData.length > 0" class="trend-grid">
            <el-card v-for="t in trendData" :key="t.kpi_id" class="trend-card-2">
              <template #header>
                <div class="trend-hd">
                  <span class="trend-name">{{ t.kpi_name }}</span>
                  <span class="trend-unit">{{ t.unit }}</span>
                  <span class="trend-stat">均值 {{ t.avg }} | 最高 {{ t.max }} | 最低 {{ t.min }}</span>
                  <span class="trend-dir" :class="t.trend_dir">{{ t.trend_dir === 'up' ? '↑ 上升' : t.trend_dir === 'down' ? '↓ 下降' : '→ 平稳' }}</span>
                </div>
              </template>
              <div :ref="el => setTrendChartRef(t.kpi_id, el)" style="height:180px;"></div>
            </el-card>
          </div>
          <el-empty v-else description="请选择KPI查看趋势" />
        </div>
      </el-tab-pane>

      <!-- ════ 报表4：BSC评分卡 ════ -->
      <el-tab-pane label="🎯 四维度绩效评分卡" name="bsc">
        <div v-loading="loading">
          <div class="report-desc">基于BSC框架的四维度绩效评分，从已发布战略地图构建。</div>
          <div v-if="bscData.overall_score != null" style="margin-top:12px;">
            <div class="bsc-overall">
              <div class="bsc-score-ring" :style="{ borderColor: bscScoreColor(bscData.overall_score) }">
                <span class="bsc-score-val">{{ bscData.overall_score }}</span>
                <span class="bsc-score-label">综合评分</span>
              </div>
              <div class="bsc-map-info" v-if="bscData.map_title">基于：{{ bscData.map_title }} | 周期：{{ bscData.period }}</div>
            </div>
            <div class="bsc-dims">
              <div v-for="dim in bscData.dimensions" :key="dim.key" class="bsc-dim-card">
                <div class="bsc-dim-head" :style="{ borderLeft: '4px solid ' + dim.color }">
                  <span class="bsc-dim-icon">{{ dim.icon }}</span>
                  <span class="bsc-dim-name">{{ dim.name }}</span>
                  <span class="bsc-dim-score" :style="{ color: bscScoreColor(dim.score) }">{{ dim.score }}</span>
                </div>
                <div class="bsc-dim-body">
                  <div v-for="obj in dim.objectives" :key="obj.name" class="bsc-obj-row">
                    <div class="bsc-obj-name">{{ obj.name }}</div>
                    <div class="bsc-obj-kpis" v-if="obj.kpis && obj.kpis.length > 0">
                      <div v-for="k in obj.kpis.slice(0, 3)" :key="k.code" class="bsc-kpi-mini">
                        <span class="bsc-kpi-dot" :class="'dot-' + k.level"></span>
                        <span class="bsc-kpi-name">{{ k.name }}</span>
                        <span class="bsc-kpi-score">{{ k.score ?? '-' }}</span>
                      </div>
                      <div v-if="obj.kpis.length > 3" class="bsc-kpi-more">+{{ obj.kpis.length - 3 }} 更多</div>
                    </div>
                    <div v-else class="bsc-obj-empty">暂无KPI数据</div>
                  </div>
                </div>
              </div>
            </div>
          </div>
          <el-empty v-else description="暂无已发布的战略地图，请先在战略地图中发布" />
        </div>
      </el-tab-pane>

      <!-- ════ 追溯调整：2026数据按新30号准则重述 ════ -->
      <el-tab-pane label="🔄 追溯调整" name="restatement">
        <div v-loading="loadingRestatement">
          <div class="report-desc">2026年数据按新30号准则重述 — 旧口径vs新口径双列对比，差异自动高亮。</div>

          <!-- 净利润对比 -->
          <div v-if="restatementNetProfit" class="restate-net-box">
            <div class="restate-net-row">
              <span class="restate-net-label">旧口径净利润：</span>
              <span class="restate-net-val">{{ formatMoney(restatementNetProfit.old_net_profit) }}</span>
              <span class="restate-net-arrow">→</span>
              <span class="restate-net-label">新口径净利润：</span>
              <span class="restate-net-val" :class="{ negative: restatementNetProfit.new_net_profit < 0 }">{{ formatMoney(restatementNetProfit.new_net_profit) }}</span>
              <span class="restate-net-diff" :class="{ up: restatementNetProfit.difference > 0, down: restatementNetProfit.difference < 0 }">
                差异：{{ restatementNetProfit.difference > 0 ? '+' : '' }}{{ formatMoney(restatementNetProfit.difference) }}
              </span>
            </div>
          </div>

          <!-- 汇总统计 -->
          <div v-if="restatementSummary" class="restate-summary-row">
            <div class="restate-stat green"><span class="restate-stat-val">{{ restatementSummary.total_items }}</span> 总项目</div>
            <div class="restate-stat red"><span class="restate-stat-val">{{ restatementSummary.adjusted_items }}</span> 需调整</div>
            <div class="restate-stat blue"><span class="restate-stat-val">{{ restatementSummary.new_items }}</span> 新增</div>
            <div class="restate-stat gray"><span class="restate-stat-val">{{ restatementSummary.unchanged_items }}</span> 不变</div>
          </div>

          <!-- 对比表格 -->
          <el-table :data="restatementItems" border stripe size="small" style="width:100%;margin-top:12px;" :row-class-name="restatementRowClass">
            <el-table-column prop="item_name" label="项目" width="240">
              <template #default="{ row }">
                <div class="restate-item-name">
                  <el-tag v-if="row.needs_adjustment" type="danger" size="small" effect="plain" class="restate-tag">调整</el-tag>
                  <el-tag v-else size="small" effect="plain" type="info" class="restate-tag">不变</el-tag>
                  <span :class="{ 'restate-breakdown-item': row.category === '_breakdown' }">{{ row.item_name }}</span>
                </div>
              </template>
            </el-table-column>
            <el-table-column label="旧准则" width="160" align="right">
              <template #default="{ row }">
                <span :class="{ 'restate-highlight-red': row.needs_adjustment && row.old_value != null }">
                  {{ row.old_value != null ? formatMoney(row.old_value) : '-' }}
                </span>
              </template>
            </el-table-column>
            <el-table-column label="新准则" width="160" align="right">
              <template #default="{ row }">
                <span :class="{ 'restate-highlight-green': row.needs_adjustment && row.new_value != null }">
                  {{ row.new_value != null ? formatMoney(row.new_value) : '-' }}
                </span>
              </template>
            </el-table-column>
            <el-table-column label="差异" width="140" align="right">
              <template #default="{ row }">
                <span v-if="row.difference != null" :class="restateDiffClass(row.difference)">
                  {{ row.difference > 0 ? '+' : '' }}{{ formatMoney(row.difference) }}
                </span>
                <span v-else-if="row.needs_adjustment" class="restate-new-badge">新</span>
                <span v-else style="color:#ccc;">-</span>
              </template>
            </el-table-column>
            <el-table-column label="调整原因" width="260">
              <template #default="{ row }">
                <span v-if="row.adjustment_reason" class="restate-reason">{{ row.adjustment_reason }}</span>
                <span v-else style="color:#ccc;">-</span>
              </template>
            </el-table-column>
          </el-table>

          <div class="restate-legend">
            <span class="restate-legend-item"><span class="restate-dot restate-dot-red"></span> 旧口径</span>
            <span class="restate-legend-item"><span class="restate-dot restate-dot-green"></span> 新口径</span>
            <span class="restate-legend-item"><span class="restate-dot restate-dot-orange"></span> 需调整项</span>
          </div>
        </div>
      </el-tab-pane>

      <!-- ════ 对外法定报表：新30号准则三表合一 ════ -->
      <el-tab-pane label="📑 对外法定报表" name="statutory">
        <div v-loading="loadingStatutory">
          <div class="report-desc">对外法定报表（新30号准则2027）— 利润表五板块+附注明细 / 资产负债表新准则科目分类 / 现金流量表三活动，支持导出Excel。</div>

          <div class="statutory-toolbar">
            <el-radio-group v-model="statutoryView" size="small">
              <el-radio-button value="profit">利润表</el-radio-button>
              <el-radio-button value="balance">资产负债表</el-radio-button>
              <el-radio-button value="cashflow">现金流量表</el-radio-button>
            </el-radio-group>
            <el-button type="primary" size="small" :loading="exporting" @click="exportStatutory">📥 导出Excel（三表合一）</el-button>
            <span v-if="statutoryDemoMode" class="new30-demo-hint">⚠️ 部分数据为示例数据，导入凭证/打标后显示实际数据</span>
          </div>

          <!-- ── 利润表（五板块+附注） ── -->
          <div v-if="statutoryView === 'profit' && statutoryData.profit">
            <div class="statutory-sub-title">利润表 — 新30号准则五板块（{{ statutoryData.period }}）</div>
            <div class="new30-blocks">
              <div v-for="block in statutoryData.profit.blocks || []" :key="block.key" class="new30-block">
                <div class="new30-block-header" @click="block.expanded = !block.expanded">
                  <span class="new30-toggle">{{ block.expanded ? '▼' : '▶' }}</span>
                  <span class="new30-block-name">{{ block.name }}</span>
                  <span class="new30-block-subtotal" :class="{ negative: block.subtotal < 0 }">{{ formatMoney(block.subtotal) }}</span>
                  <span class="new30-block-label">{{ block.subtotal_name }}</span>
                  <span v-if="!block.has_real_data" class="new30-demo-tag">示例数据</span>
                </div>
                <div v-if="block.expanded" class="new30-block-body">
                  <div v-for="item in block.items" :key="item.code" class="new30-item">
                    <span class="new30-item-name">{{ item.name }}</span>
                    <span class="new30-item-amount" :class="{ negative: item.effective != null && item.effective < 0 }">
                      {{ item.effective != null ? formatMoney(item.effective) : '-' }}
                    </span>
                  </div>
                </div>
              </div>
            </div>
            <div class="new30-net-profit" v-if="statutoryData.profit.net_profit != null">
              <div class="new30-profit-row">
                <span class="new30-profit-label">净利润：</span>
                <span class="new30-profit-value" :class="{ negative: statutoryData.profit.net_profit < 0 }">{{ formatMoney(statutoryData.profit.net_profit) }}</span>
                <span class="new30-profit-name">= 经营 + 投资 + 筹资 + 所得税 + 终止经营</span>
              </div>
            </div>

            <!-- 附注明细 -->
            <div v-if="statutoryData.profit.notes" class="statutory-notes">
              <div class="statutory-notes-title">附注明细</div>
              <div class="statutory-notes-grid">
                <!-- 收入构成 -->
                <div class="statutory-note-card">
                  <div class="statutory-note-head">附注一、收入构成</div>
                  <div v-for="n in statutoryData.profit.notes.revenue_breakdown || []" :key="n.code" class="statutory-note-row">
                    <span>{{ n.name }}（{{ n.code }}）</span>
                    <span>{{ n.amount != null ? formatMoney(n.amount) : '-' }}</span>
                  </div>
                  <div class="statutory-note-row total">
                    <span>营业收入合计</span>
                    <span>{{ statutoryData.profit.notes.revenue_total != null ? formatMoney(statutoryData.profit.notes.revenue_total) : '-' }}</span>
                  </div>
                </div>
                <!-- 费用构成 -->
                <div class="statutory-note-card">
                  <div class="statutory-note-head">附注二、费用构成</div>
                  <div v-for="n in statutoryData.profit.notes.expense_breakdown || []" :key="n.code" class="statutory-note-row">
                    <span>{{ n.name }}（{{ n.code }}）</span>
                    <span>{{ n.amount != null ? formatMoney(n.amount) : '-' }}</span>
                  </div>
                </div>
                <!-- 财务费用拆解 -->
                <div class="statutory-note-card">
                  <div class="statutory-note-head">附注三、财务费用拆解</div>
                  <div v-for="n in statutoryData.profit.notes.finance_breakdown || []" :key="n.code" class="statutory-note-row">
                    <span>{{ n.name }}（{{ n.code }}）</span>
                    <span>{{ n.amount != null ? formatMoney(n.amount) : '-' }}</span>
                  </div>
                </div>
                <!-- 板块勾稽 + 关键比率 -->
                <div class="statutory-note-card">
                  <div class="statutory-note-head">附注四、板块勾稽</div>
                  <div v-for="n in statutoryData.profit.notes.block_reconciliation || []" :key="n.key" class="statutory-note-row">
                    <span>{{ n.name }}</span>
                    <span>{{ formatMoney(n.amount) }}</span>
                  </div>
                  <div class="statutory-note-row total">
                    <span>净利润</span>
                    <span>{{ formatMoney(statutoryData.profit.notes.net_profit) }}</span>
                  </div>
                </div>
                <div class="statutory-note-card">
                  <div class="statutory-note-head">附注五、关键比率</div>
                  <div v-for="n in statutoryData.profit.notes.key_ratios || []" :key="n.name" class="statutory-note-row">
                    <span>{{ n.name }}</span>
                    <span>{{ n.value != null ? n.value.toFixed(2) + '%' : '-' }}</span>
                  </div>
                </div>
              </div>
            </div>
          </div>

          <!-- ── 资产负债表（新准则科目分类） ── -->
          <div v-else-if="statutoryView === 'balance' && statutoryData.balance_sheet">
            <div class="statutory-sub-title">资产负债表 — 新30号准则科目分类（{{ statutoryData.period }}）</div>
            <el-table :data="balanceSheetRows" border stripe size="small" style="width:100%;margin-top:12px;" :row-class-name="statutoryBsRowClass">
              <el-table-column label="项目" min-width="220">
                <template #default="{ row }">
                  <span :style="{ fontWeight: row.is_section ? 700 : row.is_total ? 700 : 400, paddingLeft: row.is_section ? '0' : '16px' }">{{ row.name }}</span>
                </template>
              </el-table-column>
              <el-table-column label="新准则分类" width="110">
                <template #default="{ row }">
                  <el-tag v-if="row.ns_category_label && !row.is_section" size="small" :type="statutoryNsTagType(row.ns_category)">{{ row.ns_category_label }}</el-tag>
                  <span v-else-if="row.is_section" style="color:#999;">{{ row.category_label }}</span>
                  <span v-else>-</span>
                </template>
              </el-table-column>
              <el-table-column label="期末余额" width="150" align="right">
                <template #default="{ row }">
                  <span :style="{ fontWeight: row.is_section || row.is_total ? 700 : 400 }">{{ row.end_value != null ? formatMoney(row.end_value) : '-' }}</span>
                </template>
              </el-table-column>
              <el-table-column label="期初余额" width="150" align="right">
                <template #default="{ row }">
                  <span :style="{ fontWeight: row.is_section || row.is_total ? 700 : 400 }">{{ row.begin_value != null ? formatMoney(row.begin_value) : '-' }}</span>
                </template>
              </el-table-column>
              <el-table-column label="数据" width="80">
                <template #default="{ row }">
                  <span v-if="row.is_demo && !row.is_section" class="new30-demo-tag">示例</span>
                  <span v-else-if="row.is_section" style="color:#999;font-size:12px;">小计</span>
                  <span v-else style="color:#999;font-size:12px;">凭证</span>
                </template>
              </el-table-column>
            </el-table>

            <div class="statutory-totals">
              <div class="statutory-total-card" :class="{ ok: statutoryData.balance_sheet.totals?.balanced }">
                <div class="statutory-total-label">资产总计</div>
                <div class="statutory-total-val">{{ formatMoney(statutoryData.balance_sheet.totals?.assets?.end) }}</div>
              </div>
              <div class="statutory-total-card">
                <div class="statutory-total-label">负债合计</div>
                <div class="statutory-total-val">{{ formatMoney(statutoryData.balance_sheet.totals?.liabilities?.end) }}</div>
              </div>
              <div class="statutory-total-card">
                <div class="statutory-total-label">所有者权益合计</div>
                <div class="statutory-total-val">{{ formatMoney(statutoryData.balance_sheet.totals?.equity?.end) }}</div>
              </div>
              <div class="statutory-total-card" :class="{ ok: statutoryData.balance_sheet.totals?.balanced }">
                <div class="statutory-total-label">勾稽校验（资产=负债+权益）</div>
                <div class="statutory-total-val" style="font-size:14px;">{{ statutoryData.balance_sheet.totals?.balanced ? '✅ 平衡' : '⚠️ 不平' }}</div>
              </div>
            </div>
          </div>

          <!-- ── 现金流量表（三活动） ── -->
          <div v-else-if="statutoryView === 'cashflow' && statutoryData.cash_flow">
            <div class="statutory-sub-title">现金流量表 — 新30号准则三活动（{{ statutoryData.period }}）</div>
            <div v-for="sec in statutoryData.cash_flow.sections || []" :key="sec.key" class="cf-section">
              <div class="cf-section-head">
                <span class="cf-section-name">{{ sec.name }}</span>
                <span class="cf-section-net" :class="{ negative: sec.net < 0 }">{{ formatMoney(sec.net) }}</span>
              </div>
              <div v-for="line in sec.lines" :key="line.code" class="cf-line">
                <span class="cf-line-name">{{ line.name }}</span>
                <span class="cf-line-code">{{ line.code }}</span>
                <span class="cf-line-value" :class="{ negative: line.value != null && line.value < 0 }">{{ line.value != null ? formatMoney(line.value) : '-' }}</span>
                <span v-if="line.is_demo" class="new30-demo-tag">示例</span>
              </div>
            </div>
            <div class="cf-section">
              <div class="cf-section-head">
                <span class="cf-section-name">{{ statutoryData.cash_flow.fx_effect?.name }}</span>
                <span class="cf-section-net">{{ formatMoney(statutoryData.cash_flow.fx_effect?.value) }}</span>
              </div>
            </div>
            <div class="cf-summary">
              <div class="cf-summary-row">
                <span>现金及现金等价物净增加额</span>
                <span class="cf-summary-val">{{ formatMoney(statutoryData.cash_flow.summary?.net_increase) }}</span>
              </div>
              <div class="cf-summary-row">
                <span>加：期初现金及现金等价物余额</span>
                <span class="cf-summary-val">{{ formatMoney(statutoryData.cash_flow.summary?.begin_cash) }}</span>
              </div>
              <div class="cf-summary-row total">
                <span>期末现金及现金等价物余额</span>
                <span class="cf-summary-val">{{ formatMoney(statutoryData.cash_flow.summary?.end_cash) }}</span>
              </div>
            </div>
          </div>
        </div>
      </el-tab-pane>
    </el-tabs>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import axios from 'axios'

// ── 状态 ──
const loading = ref(false)
const activeTab = ref('profit')
const reportPeriod = ref('2026-06')

// ── 企业选择（新30号准则报表联动）──
const entities = ref<any[]>([])
const currentEntityId = ref(Number(localStorage.getItem('cma_entity_id') || 1))

function getEntityId() {
  return Number(localStorage.getItem('cma_entity_id') || currentEntityId.value || 1)
}

async function loadEntities() {
  try {
    const r: any = await api.get('/auth/my-entities')
    entities.value = r.data || r || []
    const e = entities.value.find((x: any) => x.id === currentEntityId.value)
    if (e) localStorage.setItem('cma_entity_name', e.short_name || e.name || '')
  } catch {
    entities.value = []
  }
}

async function onEntityChange(id: number) {
  // 账套模式：切换走 switch-entity 重新签发token + 整页刷新
  if (id === Number(localStorage.getItem('cma_entity_id'))) return
  try {
    const r: any = await api.post('/auth/switch-entity', { entity_id: id })
    localStorage.setItem('cma_token', r.token)
    localStorage.setItem('cma_entity_id', String(r.entity_id))
    localStorage.setItem('cma_entity_name', r.entity_short_name || r.entity_name || '')
    ElMessage.success(`已切换企业：${r.entity_short_name || r.entity_name || id}`)
    location.reload()
  } catch (e: any) {
    ElMessage.error(e?.response?.data?.detail || '切换失败')
  }
}

// 跨页面同步：其他页面切换企业时联动刷新
if (typeof window !== 'undefined') {
  window.addEventListener('storage', (ev: StorageEvent) => {
    if (ev.key === 'cma_entity_id' && ev.newValue) {
      currentEntityId.value = Number(ev.newValue)
      loadAll()
      loadStatutory()
    }
  })
}

// API 配置
const api = axios.create({ baseURL: '/api/cma', timeout: 30000 })
api.interceptors.request.use((config: any) => {
  const token = localStorage.getItem('cma_token')
  if (token) config.headers.Authorization = `Bearer ${token}`
  return config
})

// ── 报表1：管理利润表 ──
const profitItems = ref<any[]>([])

function profitSummary(param: any) {
  const sums: string[] = ['合计']
  const last = profitItems.value[profitItems.value.length - 1]
  if (last) {
    sums.push(last.value != null ? '¥ ' + last.value.toLocaleString() : '-')
    sums.push(last.prev_value != null ? '¥ ' + last.prev_value.toLocaleString() : '-')
    sums.push(last.change_rate != null ? (last.change_rate > 0 ? '↑' : '↓') + Math.abs(last.change_rate).toFixed(1) + '%' : '-')
    sums.push(last.ratio != null ? last.ratio.toFixed(1) + '%' : '-')
  } else {
    sums.push('-', '-', '-', '-')
  }
  return sums
}

// ── 新30号准则利润表 ──
const loadingNew30 = ref(false)
const new30Blocks = ref<any[]>([])
const new30NetProfit = ref(0)
const new30Format = ref('new')
const new30DemoMode = ref(false)
const dualComparisonData = ref<any>(null)

async function loadNew30() {
  loadingNew30.value = true
  dualComparisonData.value = null
  try {
    const params: any = { period: reportPeriod.value, entity_id: getEntityId() }
    if (new30Format.value === 'dual') {
      params.format = 'dual'
    } else {
      params.format = 'new'
    }
    const r = await api.get('/reports/profit-statement', { params })
    const d = (r as any).data || {}

    if (new30Format.value === 'dual') {
      dualComparisonData.value = d
      new30Blocks.value = d.new_format?.blocks || []
      new30NetProfit.value = d.new_format?.net_profit ?? 0
      new30DemoMode.value = !d.new_format?.all_items_have_data
    } else {
      dualComparisonData.value = null
      new30Blocks.value = d.blocks || []
      new30NetProfit.value = d.net_profit ?? 0
      new30DemoMode.value = !d.all_items_have_data
    }
  } catch (e) {
    new30Blocks.value = []
    new30NetProfit.value = 0
    dualComparisonData.value = null
    ElMessage.error('加载新30号准则利润表失败')
  } finally {
    loadingNew30.value = false
  }
}

function formatMoney(val: number): string {
  if (val == null) return '-'
  const abs = Math.abs(val)
  let formatted = '¥ ' + abs.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })
  if (val < 0) formatted = '-' + formatted
  return formatted
}

function switchNew30Format(fmt: string) {
  new30Format.value = fmt
  if (fmt === 'new' || fmt === 'dual') {
    loadNew30()
  } else {
    // 切换到旧准则tab
    activeTab.value = 'profit'
  }
}

function exportNew30() {
  // 新30号准则利润表导出 → 复用对外法定报表Excel（Sheet1=五板块利润表+附注）
  exportStatutory()
}

function openSubjectManage() {
  window.open('/subjects', '_blank')
}

// ════ 对外法定报表（新30号准则三表合一）════
const statutoryData = ref<any>({})
const statutoryView = ref('profit')
const statutoryDemoMode = ref(false)
const statutoryLoading = ref(false)
const exporting = ref(false)

async function loadStatutory() {
  statutoryLoading.value = true
  try {
    const r = await api.get('/reports/statutory', { params: { period: reportPeriod.value, entity_id: getEntityId() } })
    const d = (r as any).data || {}
    statutoryData.value = d
    statutoryDemoMode.value = !d.cash_flow?.all_items_have_data
  } catch (e) {
    ElMessage.error('加载法定报表失败')
  } finally {
    statutoryLoading.value = false
  }
}

async function exportStatutory() {
  exporting.value = true
  try {
    const token = localStorage.getItem('cma_token') || ''
    const url = `/api/cma/reports/statutory/export?period=${reportPeriod.value}&entity_id=${getEntityId()}`
    const resp = await fetch(url, { headers: { 'Authorization': `Bearer ${token}` } })
    if (!resp.ok) throw new Error('导出失败')
    const blob = await resp.blob()
    const a = document.createElement('a')
    a.href = URL.createObjectURL(blob)
    a.download = `对外法定报表_${reportPeriod.value}.xlsx`
    a.click()
    URL.revokeObjectURL(a.href)
    ElMessage.success('导出成功')
  } catch (e) {
    ElMessage.error('导出失败')
  } finally {
    exporting.value = false
  }
}

// ── 报表2：预算执行报告 ──
const budgetSummary = ref({ total: 0, with_budget: 0, over_budget: 0, under_budget: 0, normal: 0 })
const budgetItems = ref<any[]>([])
const budgetDim = ref('')
const budgetLevel = ref('')

// ── 报表3：KPI趋势报告 ──
const trendDim = ref('')
const trendKpiId = ref<number | null>(null)
const trendMonths = ref(24)
const trendData = ref<any[]>([])
const kpiOptions = ref<any[]>([])
const trendChartRefs: Record<string, HTMLElement> = {}

function setTrendChartRef(id: number, el: any) {
  if (el) trendChartRefs['chart-' + id] = el
}

// ── 报表4：BSC评分卡 ──
const bscData = ref<any>({})

// ── 追溯调整：2026年数据按新30号准则重述 ──
const loadingRestatement = ref(false)
const restatementItems = ref<any[]>([])
const restatementSummary = ref<any>(null)
const restatementNetProfit = ref<any>(null)

async function loadRestatement() {
  loadingRestatement.value = true
  try {
    const r = await api.get('/reports/restatement', { params: { period: reportPeriod.value, entity_id: getEntityId() } })
    const d = (r as any).data || {}
    restatementItems.value = d.items || []
    restatementSummary.value = d.summary || null
    restatementNetProfit.value = d.net_profit_comparison || null
  } catch (e) {
    restatementItems.value = []
    restatementSummary.value = null
    restatementNetProfit.value = null
    ElMessage.error('加载追溯调整数据失败')
  } finally {
    loadingRestatement.value = false
  }
}

function restatementRowClass({ row }: any) {
  if (row.needs_adjustment) return 'restate-row-adjusted'
  return ''
}

function restatementDiffClass(diff: number) {
  if (diff > 0) return 'restate-diff-up'
  if (diff < 0) return 'restate-diff-down'
  return 'restate-diff-zero'
}

// ── 公共 ──
const dimensions = [
  { value: 'finance', label: '财务维度' },
  { value: 'customer', label: '客户维度' },
  { value: 'process', label: '内部流程' },
  { value: 'learning', label: '学习成长' },
]

function dimLabel(d: string): string {
  const map: Record<string, string> = { finance: '财务', customer: '客户', process: '内部流程', learning: '学习成长' }
  return map[d] || d
}

function bscScoreColor(score: number): string {
  if (score >= 80) return 'var(--bsc-process)'
  if (score >= 60) return 'var(--bsc-learning)'
  return '#f56c6c'
}

function onPeriodChange() {
  loadAll()
  loadStatutory()
}

// ── 加载 ──
async function loadProfit() {
  try {
    const r = await api.get('/reports/profit-summary', { params: { period: reportPeriod.value, entity_id: getEntityId() } })
    profitItems.value = (r as any).data?.items || []
  } catch { profitItems.value = [] }
}

async function loadBudget() {
  try {
    const params: any = { period: reportPeriod.value, entity_id: getEntityId() }
    if (budgetDim.value) params.dimension = budgetDim.value
    if (budgetLevel.value) params.alert_level = budgetLevel.value
    const r = await api.get('/reports/budget-execution', { params })
    const d = (r as any).data || {}
    budgetSummary.value = d.summary || {}
    budgetItems.value = d.items || []
  } catch { budgetItems.value = [] }
}

// ── 预编报表（预算版三张报表）──
const loadingProforma = ref(false)
const proformaType = ref('profit')
const proformaData = ref<any>(null)

const proformaBudgetVersion = computed(() => {
  const v = proformaData.value?.budget_version
  return Array.isArray(v) ? v.join(', ') : (v || '')
})

const proformaRows = computed(() => {
  const d = proformaData.value
  if (!d) return []
  const rows: any[] = []
  if (proformaType.value === 'profit') {
    for (const b of (d.blocks || [])) {
      rows.push({ name: b.name, subtotal: true, actual_value: b.subtotal_actual, budget_value: b.subtotal_budget, has_budget: b.has_budget })
      for (const it of (b.items || [])) rows.push({ ...it, name: it.name })
    }
    rows.push({ name: '＝ 净利润', subtotal: true, actual_value: d.net_profit_actual, budget_value: d.net_profit_budget, has_budget: true })
  } else if (proformaType.value === 'balance') {
    for (const s of (d.sections || [])) {
      rows.push({ name: s.name, subtotal: true, actual_value: s.subtotal_actual, budget_value: s.subtotal_budget, has_budget: s.has_budget })
      for (const ln of (s.lines || [])) rows.push({ ...ln, name: ln.name })
    }
  } else {
    for (const s of (d.sections || [])) {
      rows.push({ name: s.name, subtotal: true, actual_value: s.net_actual, budget_value: s.net_budget, has_budget: s.has_budget })
      for (const ln of (s.lines || [])) rows.push({ ...ln, name: ln.name })
    }
    const sm = d.summary || {}
    rows.push({ name: '＝ 现金净增加额', subtotal: true, actual_value: sm.net_increase_actual, budget_value: sm.net_increase_budget, has_budget: true })
  }
  return rows
})

async function loadProforma() {
  loadingProforma.value = true
  try {
    const map: Record<string, string> = {
      profit: '/reports/proforma/profit-statement',
      balance: '/reports/proforma/balance-sheet',
      cash: '/reports/proforma/cash-flow',
    }
    const r = await api.get(map[proformaType.value], { params: { period: reportPeriod.value, entity_id: getEntityId() } })
    proformaData.value = (r as any).data || {}
  } catch (e) {
    proformaData.value = null
    ElMessage.error('加载预编报表失败')
  } finally {
    loadingProforma.value = false
  }
}

function proformaRowClass({ row }: any) {
  if (row.subtotal) return 'proforma-subtotal'
  if (!row.has_budget) return 'proforma-no-budget'
  return ''
}

function proformaRateType(rate: number): string {
  const abs = Math.abs(rate)
  if (abs > 20) return 'danger'
  if (abs > 10) return 'warning'
  return 'success'
}

async function loadTrends() {
  try {
    const params: any = { months: trendMonths.value, entity_id: getEntityId() }
    if (trendKpiId.value) params.kpi_id = trendKpiId.value
    else if (trendDim.value) params.dimension = trendDim.value
    const r = await api.get('/reports/kpi-trends', { params })
    trendData.value = (r as any).data?.data || []
    nextTick(() => renderTrendCharts())
  } catch { trendData.value = [] }
}

async function loadBsc() {
  try {
    const r = await api.get('/reports/bsc-scorecard', { params: { period: reportPeriod.value, entity_id: getEntityId() } })
    bscData.value = (r as any).data || {}
  } catch { bscData.value = {} }
}

async function loadKpiOptions() {
  try {
    const r = await api.get('/kpis', { params: { page_size: 100, entity_id: getEntityId() } })
    kpiOptions.value = (r as any).data?.data || []
  } catch {}
}

function loadAll() {
  loading.value = true
  Promise.all([loadProfit(), loadNew30(), loadBudget(), loadProforma(), loadTrends(), loadBsc(), loadRestatement()]).finally(() => { loading.value = false })
}

function openDupont() {
  window.open('/dupont-analysis', '_blank')
}

// ── ECharts 渲染 ──
function renderTrendCharts() {
  import('echarts').then(echarts => {
    trendData.value.forEach((t: any) => {
      const el = trendChartRefs['chart-' + t.kpi_id]
      if (!el) return
      const existing = echarts.getInstanceByDom(el)
      if (existing) existing.dispose()
      const chart = echarts.init(el)
      const dates = t.trend.map((d: any) => d.period)
      const values = t.trend.map((d: any) => d.value)
      const series: any[] = [{
        type: 'line', data: values, smooth: true, lineStyle: { width: 2 },
        areaStyle: { opacity: 0.1 }, symbol: 'circle', symbolSize: 4,
        name: '实际值',
      }]
      if (t.target_value != null) {
        series.push({
          type: 'line', data: Array(dates.length).fill(t.target_value),
          lineStyle: { type: 'dashed', width: 1, color: '#f56c6c' },
          symbol: 'none', name: '目标值',
        })
      }
      chart.setOption({
        grid: { left: 50, right: 15, top: 10, bottom: 28 },
        xAxis: { type: 'category', data: dates, axisLabel: { fontSize: 10, rotate: 45 } },
        yAxis: { type: 'value', splitLine: { lineStyle: { type: 'dashed', color: '#eee' } } },
        series,
        tooltip: { trigger: 'axis' },
        legend: { show: true, bottom: 0, icon: 'circle', itemWidth: 8, itemHeight: 8 },
      })
    })
  })
}

// ── 排序 ──
function onBudgetSort(sort: any) {
  if (!sort.prop || !sort.order) return
  const items = [...budgetItems.value]
  items.sort((a: any, b: any) => {
    const av = a[sort.prop] ?? 0
    const bv = b[sort.prop] ?? 0
    return sort.order === 'ascending' ? av - bv : bv - av
  })
  budgetItems.value = items
}

onMounted(() => {
  loadEntities()
  loadKpiOptions()
  loadAll()
  loadStatutory()
})
</script>

<style scoped>
.report-page { max-width: 1400px; margin: 0 auto; }
.report-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; }
.header-right { display: flex; gap: 8px; align-items: center; }
.report-tabs { margin-bottom: 20px; }
.report-desc { font-size: 13px; color: #888; padding: 8px 0; }

/* 预编报表（预算版） */
:deep(.proforma-no-budget) { opacity: 0.55; }
:deep(.proforma-subtotal) { background: #f0f7ff !important; font-weight: 600; color: #1f2d3d; }

/* 统计卡片 */
.summary-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 12px; }
.stat-card { background: #fff; border-radius: 8px; padding: 12px 16px; box-shadow: 0 1px 3px rgba(0,0,0,0.05); border-top: 3px solid #ccc; }
.stat-card.blue { border-top-color: #409eff; }
.stat-card.red { border-top-color: #f56c6c; }
.stat-card.green { border-top-color: #67c23a; }
.stat-card.yellow { border-top-color: var(--bsc-learning); }
.stat-card.gray { border-top-color: #909399; }
.stat-val { font-size: 22px; font-weight: 700; color: #1a1a2e; }
.stat-label { font-size: 12px; color: #888; margin-top: 2px; }

/* 趋势卡片 */
.trend-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 14px; margin-top: 12px; }
.trend-card-2 { border-radius: 10px; }
.trend-hd { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.trend-name { font-weight: 600; font-size: 14px; flex: 1; }
.trend-unit { color: #999; font-size: 12px; }
.trend-stat { font-size: 11px; color: #999; }
.trend-dir { font-size: 11px; padding: 2px 8px; border-radius: 4px; }
.trend-dir.up { background: #fff1f0; color: #cf1322; }
.trend-dir.down { background: #f6ffed; color: #389e0d; }
.trend-dir.stable { background: #f5f5f5; color: #999; }

/* BSC评分卡 */
.bsc-overall { text-align: center; padding: 20px 0; }
.bsc-score-ring {
  display: inline-flex; flex-direction: column; align-items: center; justify-content: center;
  width: 120px; height: 120px; border-radius: 50%; border: 6px solid #67c23a;
  background: #fff; box-shadow: 0 2px 12px rgba(0,0,0,0.08);
}
.bsc-score-val { font-size: 36px; font-weight: 700; color: #1a1a2e; line-height: 1.1; }
.bsc-score-label { font-size: 12px; color: #999; margin-top: 2px; }
.bsc-map-info { font-size: 12px; color: #999; margin-top: 8px; }
.bsc-dims { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 14px; margin-top: 16px; }
.bsc-dim-card { background: #fff; border-radius: 10px; box-shadow: 0 1px 4px rgba(0,0,0,0.06); overflow: hidden; }
.bsc-dim-head { display: flex; align-items: center; gap: 8px; padding: 12px 14px; background: #fafafa; }
.bsc-dim-icon { font-size: 18px; }
.bsc-dim-name { font-weight: 600; font-size: 14px; flex: 1; }
.bsc-dim-score { font-size: 24px; font-weight: 700; }
.bsc-dim-body { padding: 10px 14px; }
.bsc-obj-row { margin-bottom: 10px; }
.bsc-obj-name { font-size: 13px; font-weight: 500; color: #555; margin-bottom: 4px; }
.bsc-obj-kpis { display: flex; flex-direction: column; gap: 3px; }
.bsc-kpi-mini { display: flex; align-items: center; gap: 6px; font-size: 12px; padding: 2px 6px; background: #f9f9f9; border-radius: 4px; }
.bsc-kpi-dot { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; }
.dot-green { background: #67c23a; }
.dot-yellow { background: var(--bsc-learning); }
.dot-red { background: #f56c6c; }
.dot-gray { background: #ddd; }
.bsc-kpi-name { flex: 1; color: #666; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bsc-kpi-score { font-weight: 600; color: #333; }
.bsc-kpi-more { font-size: 11px; color: #409eff; text-align: center; padding: 2px; }
.bsc-obj-empty { font-size: 11px; color: #ccc; text-align: center; padding: 4px; }

/* 新30号准则样式 */
.new30-blocks { margin-top: 12px; }
.new30-block { background: #fff; border-radius: 8px; margin-bottom: 10px; box-shadow: 0 1px 3px rgba(0,0,0,0.04); border: 1px solid #ebeef5; overflow: hidden; }
.new30-block-header { display: flex; align-items: center; gap: 8px; padding: 10px 14px; cursor: pointer; background: #f9fafc; border-bottom: 1px solid #ebeef5; transition: background 0.2s; }
.new30-block-header:hover { background: #f0f2f5; }
.new30-toggle { font-size: 10px; color: #999; width: 16px; }
.new30-block-name { font-weight: 600; font-size: 14px; flex: 1; color: #1a1a2e; }
.new30-block-subtotal { font-size: 16px; font-weight: 700; color: #1a1a2e; min-width: 120px; text-align: right; }
.new30-block-subtotal.negative { color: #f56c6c; }
.new30-block-label { font-size: 11px; color: #999; width: 80px; }
.new30-demo-tag { font-size: 10px; background: #fff7e6; color: #d46b08; padding: 1px 6px; border-radius: 3px; }
.new30-block-body { padding: 6px 14px 10px 38px; }
.new30-item { display: flex; align-items: center; gap: 8px; padding: 4px 0; border-bottom: 1px dashed #f0f0f0; }
.new30-item:last-child { border-bottom: none; }
.new30-item-name { flex: 1; font-size: 13px; color: #555; }
.new30-item-amount { font-size: 13px; font-weight: 500; min-width: 120px; text-align: right; color: #333; }
.new30-item-amount.negative { color: #f56c6c; }
.new30-item-ratio { font-size: 11px; color: #bbb; width: 60px; text-align: right; }
.new30-net-profit { margin-top: 16px; padding: 12px 16px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 8px; color: #fff; }
.new30-profit-row { display: flex; align-items: center; gap: 12px; }
.new30-profit-label { font-size: 14px; opacity: 0.9; }
.new30-profit-value { font-size: 24px; font-weight: 700; flex: 1; }
.new30-profit-value.negative { color: #ffccc7; }
.new30-profit-name { font-size: 13px; opacity: 0.8; }
.new30-footer { margin-top: 12px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.new30-demo-hint { font-size: 11px; color: #d46b08; margin-left: 8px; }

/* 追溯调整样式 */
.restate-net-box { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 8px; padding: 14px 18px; color: #fff; margin-top: 12px; }
.restate-net-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.restate-net-label { font-size: 13px; opacity: 0.9; }
.restate-net-val { font-size: 18px; font-weight: 700; }
.restate-net-val.negative { color: #ffccc7; }
.restate-net-arrow { font-size: 18px; opacity: 0.7; }
.restate-net-diff { font-size: 13px; padding: 2px 10px; border-radius: 4px; }
.restate-net-diff.up { background: rgba(255,255,255,0.2); color: #b7eb8f; }
.restate-net-diff.down { background: rgba(255,255,255,0.2); color: #ffccc7; }
.restate-summary-row { display: flex; gap: 12px; margin-top: 12px; }
.restate-stat { padding: 8px 14px; border-radius: 6px; font-size: 13px; color: #555; border-left: 3px solid #ccc; background: #fafafa; }
.restate-stat.green { border-left-color: #67c23a; }
.restate-stat.red { border-left-color: #f56c6c; }
.restate-stat.blue { border-left-color: #409eff; }
.restate-stat.gray { border-left-color: #909399; }
.restate-stat-val { font-weight: 700; font-size: 16px; margin-right: 4px; }
.restate-item-name { display: flex; align-items: center; gap: 6px; }
.restate-tag { flex-shrink: 0; }
.restate-breakdown-item { padding-left: 16px; color: #666; font-size: 12px; }
.restate-highlight-red { background: #fff1f0; padding: 1px 4px; border-radius: 2px; font-weight: 600; color: #cf1322; }
.restate-highlight-green { background: #f6ffed; padding: 1px 4px; border-radius: 2px; font-weight: 600; color: #389e0d; }
.restate-diff-up { color: #f56c6c; font-weight: 600; }
.restate-diff-down { color: #67c23a; font-weight: 600; }
.restate-diff-zero { color: #999; }
.restate-new-badge { background: #409eff; color: #fff; padding: 1px 6px; border-radius: 3px; font-size: 11px; }
.restate-reason { font-size: 12px; color: #d46b08; }
.restate-legend { display: flex; gap: 16px; margin-top: 12px; padding: 8px 12px; background: #fafafa; border-radius: 6px; font-size: 12px; color: #666; }
.restate-legend-item { display: flex; align-items: center; gap: 4px; }
.restate-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
.restate-dot-red { background: #cf1322; }
.restate-dot-green { background: #389e0d; }
.restate-dot-orange { background: #d46b08; }

/* 双列对比样式 */
.dual-comparison { margin-top: 12px; }
.dual-desc { font-size: 13px; color: #888; margin-bottom: 12px; }
.dual-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
@media screen and (max-width: 1000px) { .dual-grid { grid-template-columns: 1fr; } }
.dual-col { background: #fff; border-radius: 8px; border: 1px solid #ebeef5; overflow: hidden; }
.dual-col-header { padding: 10px 14px; font-weight: 600; font-size: 14px; color: #fff; }
.dual-col-header.old-col { background: #909399; }
.dual-col-header.new-col { background: #409eff; }
.dual-blocks { padding: 8px; }
.dual-block { margin-bottom: 8px; border: 1px solid #ebeef5; border-radius: 4px; overflow: hidden; }
.dual-block-header { display: flex; justify-content: space-between; padding: 6px 10px; background: #f9fafc; font-size: 13px; font-weight: 600; }
.dual-block-subtotal { color: #1a1a2e; }
.dual-block-item { display: flex; justify-content: space-between; padding: 4px 10px 4px 16px; font-size: 12px; color: #555; border-top: 1px dashed #f0f0f0; }
.dual-item-name { flex: 1; }
.dual-item-amount { font-weight: 500; }
.dual-net-profit { padding: 10px 14px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: #fff; border-radius: 4px; margin: 8px; display: flex; align-items: center; gap: 8px; font-size: 14px; }
.dual-net-val { font-size: 18px; font-weight: 700; flex: 1; }
</style>
