<script setup>
import { computed, nextTick, onMounted, onUnmounted, ref, watch } from 'vue'
import * as echarts from 'echarts'
import { Cpu, DataLine, InfoFilled, Loading, Monitor, Setting, WarningFilled } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'

const currentStep = ref(0)
const selectedMode = ref('')
const selectedCategory = ref('')
const assetId = ref('')
const allAssets = ref([])
const dbAssets = ref([])
const assessmentData = ref(null)
const showBaselineLines = ref(true)
const showFailureLines = ref(true)

const gaugeChartRef = ref(null)
const lineChartRef = ref(null)
const partLineChartRef = ref(null)

let gaugeInstance = null
let lineInstance = null
let partLineInstance = null

const fetchJson = async (url, options) => {
  const response = await fetch(url, options)
  const data = await response.json()
  if (!response.ok || data.status === 'error') {
    throw new Error(data.message || '请求失败')
  }
  return data
}

const loadAssets = async () => {
  const data = await fetchJson('/api/assets')
  allAssets.value = data.data || []
}

const syncAssets = () => {
  if (!selectedMode.value) {
    dbAssets.value = allAssets.value
    return
  }
  dbAssets.value = allAssets.value.filter((item) => (
    selectedMode.value === 'whole' ? item.asset_category === '整机' : item.asset_category !== '整机'
  ))
}

const goBack = (step) => {
  currentStep.value = step
  disposeCharts()
}

const selectMode = (mode) => {
  selectedMode.value = mode
  selectedCategory.value = ''
  assetId.value = ''
  syncAssets()
  currentStep.value = 1
}

const startAlgorithm = async () => {
  if (!assetId.value) return
  currentStep.value = 2

  try {
    assessmentData.value = await fetchJson(`/api/evaluate?asset_id=${assetId.value}&mode=${selectedMode.value}`, {
      method: 'POST',
    })
  } catch (error) {
    ElMessage.error('评估失败，请检查后台服务或该设备是否已有测试记录')
    currentStep.value = 1
    return
  }

  setTimeout(() => {
    currentStep.value = 3
    nextTick(() => {
      if (!assessmentData.value?.is_complete) return
      if (selectedMode.value === 'whole') {
        initWholeCharts(assessmentData.value)
      } else {
        initPartCharts(assessmentData.value)
      }
    })
  }, 600)
}

const buildDynamicSeries = (seriesData, withLimits = false) => {
  const colors = ['#4d73c9', '#77a6d8', '#97c977', '#d2a15e', '#7b91ba']
  const output = []
  ;(seriesData || []).forEach((item, index) => {
    const color = colors[index % colors.length]
    output.push({
      name: item.name,
      type: 'line',
      smooth: true,
      data: item.data,
      connectNulls: true,
      symbolSize: 7,
      lineStyle: { width: 3, color },
      itemStyle: { color, borderWidth: 2, borderColor: '#ffffff' },
      areaStyle: index === 0 ? { color: 'rgba(96, 131, 201, 0.08)' } : undefined,
    })
    if (!withLimits) return
    const baseline = item.baseline_value ?? item.lower_limit
    const failure = item.failure_value ?? item.upper_limit
    if (showBaselineLines.value && baseline !== null && baseline !== undefined) {
      output.push({
        name: `${item.name} 出厂线 ${baseline}${item.unit || ''}`,
        type: 'line',
        data: item.data.map(() => baseline),
        symbol: 'none',
        lineStyle: { color, type: 'dashed', width: 1.4, opacity: 0.62 },
        emphasis: { disabled: true },
      })
    }
    if (showFailureLines.value && failure !== null && failure !== undefined) {
      output.push({
        name: `${item.name} 失效线 ${failure}${item.unit || ''}`,
        type: 'line',
        data: item.data.map(() => failure),
        symbol: 'none',
        lineStyle: { color: '#c86a76', type: 'dashed', width: 1.4, opacity: 0.74 },
        emphasis: { disabled: true },
      })
    }
  })
  return output
}

const renderWholeLineChart = (data) => {
  if (!lineInstance) return
  lineInstance.setOption({
    tooltip: {
      trigger: 'axis',
      valueFormatter: (value) => (value === null || value === undefined ? '-' : value),
    },
    legend: { type: 'scroll', top: 0, textStyle: { fontWeight: 'bold', color: '#5f6f86' } },
    grid: { top: 58, left: 46, right: 28, bottom: 42, containLabel: true },
    xAxis: {
      type: 'category',
      data: data.timelines || [],
      axisLine: { lineStyle: { color: '#6d7480' } },
      axisLabel: { color: '#5f6f86' },
    },
    yAxis: {
      type: 'value',
      name: '测定数值',
      splitLine: { lineStyle: { color: 'rgba(128, 145, 170, 0.28)' } },
      axisLabel: { color: '#5f6f86' },
    },
    series: buildDynamicSeries(data.series_data, true),
  }, true)
}

const initWholeCharts = (data) => {
  gaugeInstance = echarts.init(gaugeChartRef.value)
  gaugeInstance.setOption({
    series: [
      {
        type: 'gauge',
        startAngle: 210,
        endAngle: -30,
        min: 0,
        max: 100,
        pointer: { show: false },
        progress: { show: true, width: 24, roundCap: true, itemStyle: { color: '#6bbd63' } },
        axisLine: { lineStyle: { width: 24, color: [[1, '#e7edf5']] } },
        axisTick: { show: false },
        splitLine: { show: false },
        axisLabel: { show: false },
        detail: {
          formatter: '{value} 分\n\n综合评分',
          fontSize: 24,
          fontWeight: 'bold',
          color: '#2a3d5e',
          offsetCenter: [0, '8%'],
        },
        data: [{ value: data.score || 0 }],
      },
    ],
  })

  lineInstance = echarts.init(lineChartRef.value)
  renderWholeLineChart(data)
}

const initPartCharts = (data) => {
  partLineInstance = echarts.init(partLineChartRef.value)
  partLineInstance.setOption({
    tooltip: { trigger: 'axis' },
    legend: { type: 'scroll', top: 0, textStyle: { fontWeight: 'bold', color: '#5f6f86' } },
    grid: { top: 58, left: 46, right: 28, bottom: 42, containLabel: true },
    xAxis: {
      type: 'category',
      data: data.timelines || [],
      axisLine: { lineStyle: { color: '#6d7480' } },
      axisLabel: { color: '#5f6f86' },
    },
    yAxis: {
      type: 'value',
      name: '测定数值',
      splitLine: { lineStyle: { color: 'rgba(128, 145, 170, 0.28)' } },
      axisLabel: { color: '#5f6f86' },
    },
    series: buildDynamicSeries(data.series_data),
  })
}

const disposeCharts = () => {
  if (gaugeInstance) {
    gaugeInstance.dispose()
    gaugeInstance = null
  }
  if (lineInstance) {
    lineInstance.dispose()
    lineInstance = null
  }
  if (partLineInstance) {
    partLineInstance.dispose()
    partLineInstance = null
  }
}

const latestStatusCards = computed(() => assessmentData.value?.latest_status || [])
const criterionCards = computed(() => assessmentData.value?.criterion_cards || [])
const metricRows = computed(() => assessmentData.value?.metric_rows || [])
const missingItems = computed(() => assessmentData.value?.missing_items || [])
const failedMetrics = computed(() => assessmentData.value?.failed_metrics || [])
const partMetricRows = computed(() => assessmentData.value?.metric_rows || [])
const canAnalyze = computed(() => Boolean(assessmentData.value?.is_complete))
const partMethodLabel = computed(() => {
  if (assessmentData.value?.evaluation_method === 'retention_time') return '精度保持时间评价'
  if (assessmentData.value?.evaluation_method === 'retention_degree') return '精度保持度评价'
  return '部件综合评估'
})
const currentAsset = computed(() => allAssets.value.find((item) => item.asset_id === assetId.value) || null)
const resultLevel = computed(() => {
  if (selectedMode.value === 'part' && assessmentData.value?.evaluation_method === 'retention_time') {
    return { label: '已发生精度失效', className: 'danger' }
  }
  const score = assessmentData.value?.score
  if (score == null) return { label: '等待评价', className: 'neutral' }
  if (score >= 80) return { label: '优秀', className: 'success' }
  if (score >= 70) return { label: '良好', className: 'success' }
  if (score >= 60) return { label: '合格', className: 'warning' }
  return { label: '不合格', className: 'danger' }
})
const resultSummary = computed(() => {
  if (!assessmentData.value) return ''
  if (missingItems.value.length) {
    return `当前仍有 ${missingItems.value.length} 项数据或配置缺口，系统已阻断本次严格评价。`
  }
  if (selectedMode.value === 'part' && assessmentData.value.evaluation_method === 'retention_time') {
    return `检测到精度失效，系统已按规范切换为保持时间评价，最早失效时间为 ${assessmentData.value.retention_time_hours} 小时。`
  }
  if (selectedMode.value === 'part') {
    return `固定循环内未发生精度失效，系统采用保持度评价，综合得分为 ${assessmentData.value.score} 分。`
  }
  return `几何、位置与加工精度已完成逐层汇总，综合得分为 ${assessmentData.value.score} 分。`
})
const modeConfiguration = computed(() => (
  selectedMode.value === 'whole'
    ? [
        { type: 'adjustable', label: '操作者本次可调', title: '评估对象', desc: '本次只需选择整机资产，系统自动读取其全部有效记录。' },
        { type: 'configurable', label: '管理员可配置', title: '指标绑定与评价边界', desc: '在设备台账配置出厂值、失效值、指标层权重和准则层权重。' },
        { type: 'fixed', label: '系统按规范固定', title: 'ARDR / ARD / AFD / ACD / AD', desc: '公式、归一化和组合赋权过程由系统自动执行。' },
      ]
    : [
        { type: 'adjustable', label: '操作者本次可调', title: '评估对象', desc: '本次选择需要评价的功能部件。' },
        { type: 'configurable', label: '管理员可配置', title: '初始值、失效值与循环时长', desc: '在设备台账的部件指标绑定中维护。' },
        { type: 'fixed', label: '系统按规范固定', title: '失效判定与评价路径', desc: '未失效采用保持度，任一指标失效则切换为保持时间。' },
      ]
))
const wholeDimensionNotes = [
  { key: 'ARDR', label: '精度退化速率', desc: '拟合退化曲线的斜率，越小越好。' },
  { key: 'ARD', label: '精度保持度', desc: '相对出厂精度的保持能力，越大越好。' },
  { key: 'AFD', label: '精度波动度', desc: '实测点偏离拟合曲线的程度，越小越好。' },
  { key: 'ACD', label: '加工一致性', desc: '同批制品样本离散程度，越大越好。' },
  { key: 'AD', label: '精度偏离度', desc: '样本均值偏离中心/边界的程度，越小越好。' },
]

const tableColumnTips = {
  raw: '评价量原值是按公式直接算出的原始数值，例如 ARDR、ARD、AFD、ACD、AD，尚未统一到百分制。',
  fuzzy: '模糊评价值是把不同量纲的评价量统一换算为 0-100 分，便于同表比较和加权。',
  weight: '组合权重由主观权重和客观权重融合得到，用来决定同一指标下各评价量对指标得分的贡献。',
}

const formatMetricBundle = (bundle) => Object.entries(bundle || {})
  .map(([key, value]) => `${key} ${value}`)
  .join(' / ')

const formatWeightBundle = (bundle) => Object.entries(bundle || {})
  .map(([key, value]) => `${key} ${Number(value).toFixed(3)}`)
  .join(' / ')

watch(assetId, () => {
  const currentAsset = allAssets.value.find((item) => item.asset_id === assetId.value)
  selectedCategory.value = currentAsset?.asset_category || ''
})

watch([showBaselineLines, showFailureLines], () => {
  if (selectedMode.value === 'whole' && currentStep.value === 3 && assessmentData.value?.is_complete) {
    renderWholeLineChart(assessmentData.value)
  }
})

onMounted(() => {
  loadAssets()
    .then(syncAssets)
    .catch(() => {})
})

onUnmounted(() => {
  disposeCharts()
})
</script>

<template>
  <div class="analysis-container">
    <div v-if="currentStep === 0" class="step-0-wrapper slide-in">
      <h1 class="mode-title">选择综合评估模式</h1>
      <div class="mode-cards">
        <button type="button" class="big-btn-card" @click="selectMode('whole')">
          <div class="card-icon">
            <el-icon size="26"><Monitor /></el-icon>
          </div>
          <h2>整机综合评估系统</h2>
          <p>面向整机资产，结合测试记录和退化趋势，输出整机精度保持性综合评估结果。</p>
        </button>
        <button type="button" class="big-btn-card" @click="selectMode('part')">
          <div class="card-icon">
            <el-icon size="26"><Setting /></el-icon>
          </div>
          <h2>部件综合评估系统</h2>
          <p>面向功能部件资产，聚焦关键参数变化过程，进行部件级综合评估与状态研判。</p>
        </button>
      </div>
    </div>

    <div v-if="currentStep === 1" class="step-1-wrapper slide-in">
      <el-card shadow="hover" class="selection-card">
        <div class="card-header">
          <el-icon size="24" color="#4d78b9"><DataLine /></el-icon>
          <h3>{{ selectedMode === 'whole' ? '选择整机资产并执行综合评估' : '选择部件资产并执行综合评估' }}</h3>
        </div>

        <el-empty
          v-if="!dbAssets.length"
          :description="selectedMode === 'whole' ? '暂无整机资产，请先到设备台账新增整机并录入测试数据' : '暂无部件资产，请先到设备台账新增部件并录入测试数据'"
        />

        <el-form v-else label-position="top" style="margin-top: 20px">
          <el-form-item label="选择资产">
            <el-select v-model="assetId" filterable placeholder="可直接打字搜索..." size="large" style="width: 100%">
              <el-option
                v-for="item in dbAssets"
                :key="item.asset_id"
                :label="`${item.asset_code} (${item.asset_name})`"
                :value="item.asset_id"
              />
            </el-select>
          </el-form-item>
        </el-form>

        <div style="text-align: center; margin-top: 40px">
          <el-button plain size="large" style="margin-right: 12px" @click="goBack(0)">
            返回模式选择
          </el-button>
          <el-button v-if="dbAssets.length" type="primary" size="large" class="execute-btn" :disabled="!assetId" @click="startAlgorithm">
            <el-icon class="el-icon--left"><Cpu /></el-icon> 执行核心综合评估算法
          </el-button>
        </div>
      </el-card>
    </div>

    <div v-if="currentStep === 2" class="step-2-wrapper fade-in">
      <div class="loading-box">
        <el-icon class="is-loading" size="60" color="#409eff"><Loading /></el-icon>
        <h2 style="margin-top: 20px; color: #4d78b9">正在启动算法引擎...</h2>
        <p style="color: #7c8ba1">正在进行综合运算，请稍候</p>
      </div>
    </div>

    <div v-if="currentStep === 3" class="step-3-wrapper analysis-workbench fade-in">
      <div class="analysis-heading">
        <div>
          <span class="result-kicker">{{ selectedMode === 'whole' ? 'WHOLE MACHINE ASSESSMENT' : 'COMPONENT ASSESSMENT' }}</span>
          <h2>
            <el-icon><Cpu /></el-icon>
            {{ selectedMode === 'whole' ? '整机精度保持性综合评估' : '功能部件精度保持性综合评估' }}
          </h2>
          <div class="asset-line">
            <strong>{{ assessmentData?.asset_name }}</strong>
            <span>{{ assessmentData?.asset_code }}</span>
            <span>{{ assessmentData?.asset_type }}</span>
          </div>
        </div>
        <div>
          <el-button type="info" plain style="margin-right: 12px" @click="goBack(1)">返回修改资产</el-button>
          <el-button plain @click="goBack(0)">返回模式选择</el-button>
        </div>
      </div>

      <div v-if="!canAnalyze" class="analysis-card blocked-analysis-card">
        <div class="blocked-icon">
          <el-icon><WarningFilled /></el-icon>
        </div>
        <div>
          <span class="result-kicker">ANALYSIS BLOCKED</span>
          <h3>数据不完整，无法执行严格评价</h3>
          <p>本系统按标准公式进行计算，缺少必要记录、出厂精度、失效精度或权重时不会输出“部分结论”，以避免展示误导性结果。</p>
        </div>
        <div class="missing-list blocked-missing-list">
          <div v-for="item in missingItems" :key="`${item.metric_name}-${item.reason}`" class="missing-item">
            <strong>{{ item.metric_name }}</strong>
            <span>{{ item.reason }}</span>
          </div>
        </div>
      </div>

      <template v-else>
      <div class="result-hero">
        <div>
          <span class="result-grade" :class="resultLevel.className">{{ resultLevel.label }}</span>
          <h3>{{ resultSummary }}</h3>
          <p>报告依据已归档测试记录、设备参数边界和权重配置生成，展示准则层汇总、指标层计算和关键退化轨迹。</p>
        </div>
        <div class="result-hero-metrics">
          <div>
            <span>{{ selectedMode === 'whole' ? '综合得分' : partMethodLabel }}</span>
            <strong v-if="selectedMode === 'part' && assessmentData?.evaluation_method === 'retention_time'">
              {{ assessmentData?.retention_time_hours ?? '--' }}h
            </strong>
            <strong v-else>{{ assessmentData?.score ?? '--' }}</strong>
          </div>
          <div>
            <span>有效指标</span>
            <strong>{{ assessmentData?.metric_rows?.length || 0 }}</strong>
          </div>
          <div>
            <span>缺失项</span>
            <strong>{{ assessmentData?.missing_count || 0 }}</strong>
          </div>
        </div>
      </div>

      <template v-if="selectedMode === 'whole'">
        <div class="analysis-grid whole-grid">
          <section class="analysis-card score-card">
            <div class="analysis-card-title">整机综合评分</div>
            <div ref="gaugeChartRef" class="score-chart"></div>
          </section>

          <section class="analysis-card criterion-card">
            <div class="analysis-card-title">准则层综合结果</div>
            <p class="card-explain">准则层得分由其下属指标层得分按指标权重汇总；整机总分再按准则层权重进行加权。</p>
            <div class="criterion-list">
              <div v-for="item in criterionCards" :key="item.criterion" class="criterion-item">
                <div>
                  <strong>{{ item.criterion }}</strong>
                  <span>权重 {{ (item.weight * 100).toFixed(0) }}%</span>
                </div>
                <b>{{ item.score.toFixed(2) }}</b>
              </div>
            </div>
          </section>
        </div>

        <section class="analysis-card result-table-card">
          <div class="analysis-card-title">指标层计算结果</div>
          <div class="dimension-note-grid">
            <div v-for="item in wholeDimensionNotes" :key="item.key" class="dimension-note">
              <strong>{{ item.key }} · {{ item.label }}</strong>
              <span>{{ item.desc }}</span>
            </div>
          </div>
          <el-table :data="metricRows" stripe class="result-table">
            <el-table-column label="指标项" min-width="220">
              <template #default="{ row }">
                <div class="metric-cell">
                  <strong>{{ row.metric_name }}</strong>
                  <span>{{ row.metric_type === 'process' ? '加工精度指标' : '几何/位置精度指标' }}</span>
                </div>
              </template>
            </el-table-column>
            <el-table-column prop="criterion" label="准则层" width="120" />
            <el-table-column min-width="240">
              <template #header>
                <span class="table-head-help">
                  评价量原值
                  <el-tooltip :content="tableColumnTips.raw" placement="top">
                    <el-icon><InfoFilled /></el-icon>
                  </el-tooltip>
                </span>
              </template>
              <template #default="{ row }">
                {{ formatMetricBundle(row.raw_metrics) }}
              </template>
            </el-table-column>
            <el-table-column min-width="220">
              <template #header>
                <span class="table-head-help">
                  模糊评价值
                  <el-tooltip :content="tableColumnTips.fuzzy" placement="top">
                    <el-icon><InfoFilled /></el-icon>
                  </el-tooltip>
                </span>
              </template>
              <template #default="{ row }">
                {{ formatMetricBundle(row.fuzzy_scores) }}
              </template>
            </el-table-column>
            <el-table-column min-width="220">
              <template #header>
                <span class="table-head-help">
                  组合权重
                  <el-tooltip :content="tableColumnTips.weight" placement="top">
                    <el-icon><InfoFilled /></el-icon>
                  </el-tooltip>
                </span>
              </template>
              <template #default="{ row }">
                {{ formatWeightBundle(row.combined_weights) }}
              </template>
            </el-table-column>
            <el-table-column label="指标得分" width="110">
              <template #default="{ row }">
                <strong style="color: #284874">{{ row.score.toFixed(2) }}</strong>
              </template>
            </el-table-column>
          </el-table>
        </section>

        <section class="analysis-card trend-card">
          <div class="analysis-card-title trend-title-row">
            <span>关键指标精度退化轨迹</span>
            <span class="trend-switches">
              <el-switch v-model="showBaselineLines" size="small" active-text="出厂线" />
              <el-switch v-model="showFailureLines" size="small" active-text="失效线" />
            </span>
          </div>
          <p class="card-explain">曲线来自各指标按时间排序后的实测值；虚线为该指标配置的出厂精度和失效精度，用来判断退化趋势距离边界还有多远。</p>
          <div ref="lineChartRef" class="trend-chart"></div>
        </section>
      </template>

      <template v-else>
        <div class="analysis-grid part-summary-grid">
          <section class="analysis-card score-card">
            <div class="analysis-card-title">{{ partMethodLabel }}</div>
            <div class="part-score-panel">
              <strong v-if="assessmentData?.evaluation_method === 'retention_time'">
                {{ assessmentData.retention_time_hours ?? '--' }} h
              </strong>
              <strong v-else>{{ assessmentData?.score ?? 0 }} 分</strong>
              <span v-if="assessmentData?.evaluation_method === 'retention_time'">最早失效精度保持时间</span>
              <span v-else>固定循环结束后的综合保持度</span>
            </div>
          </section>

          <section class="analysis-card criterion-card">
            <div class="analysis-card-title">部件评价说明</div>
            <div class="criterion-list">
              <div class="criterion-item">
                <div>
                  <strong>评价路径</strong>
                  <span>{{ partMethodLabel }}</span>
                </div>
                <b>{{ Math.round((assessmentData?.coverage_ratio || 0) * 100) }}%</b>
              </div>
              <div class="criterion-item">
                <div>
                  <strong>缺失项</strong>
                  <span>缺参数或缺记录会阻断严格计算</span>
                </div>
                <b>{{ assessmentData?.missing_count || 0 }}</b>
              </div>
            </div>
          </section>
        </div>

        <section v-if="failedMetrics.length" class="analysis-card result-table-card">
          <div class="analysis-card-title">失效指标明细</div>
          <el-table :data="failedMetrics" stripe class="result-table">
            <el-table-column prop="metric_name" label="指标名称" min-width="220" />
            <el-table-column prop="retention_time_hours" label="保持时间(h)" width="140" />
            <el-table-column prop="cycles_to_failure" label="失效循环序号" width="140" />
            <el-table-column prop="latest_value" label="失效值" width="120" />
            <el-table-column prop="reason" label="说明" min-width="240" />
          </el-table>
        </section>

        <section class="analysis-card result-table-card">
          <div class="analysis-card-title">部件指标评价结果</div>
          <el-table :data="partMetricRows" stripe class="result-table">
            <el-table-column prop="metric_name" label="指标名称" min-width="220" />
            <el-table-column prop="evaluation_method" label="评价方式" width="150" />
            <el-table-column prop="baseline_value" label="初始值" width="100" />
            <el-table-column prop="failure_value" label="失效值" width="100" />
            <el-table-column prop="latest_value" label="当前值" width="100" />
            <el-table-column label="结果" width="140">
              <template #default="{ row }">
                {{ row.retention_time_hours ?? row.score ?? '--' }}
              </template>
            </el-table-column>
            <el-table-column prop="note" label="说明" min-width="240" />
          </el-table>
        </section>

        <section class="analysis-card trend-card">
          <div class="analysis-card-title">部件关键指标状态趋势</div>
          <div ref="partLineChartRef" class="trend-chart"></div>
        </section>
      </template>

      <section v-if="latestStatusCards.length" class="analysis-card status-section">
        <div class="analysis-card-title">最新测点状态</div>
        <div class="status-row">
          <div v-for="item in latestStatusCards" :key="item.name" class="status-card" :class="item.status">
            <div class="status-card-kicker">{{ item.status === 'danger' ? '预警' : '稳定' }}</div>
            <strong>{{ item.value ?? '--' }}{{ item.unit || '' }}</strong>
            <span>{{ item.name }}</span>
          </div>
        </div>
      </section>

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

<style scoped>
.analysis-container {
  min-height: 720px;
}

.mode-title {
  margin-bottom: 24px;
  color: #203553;
  font-size: 34px;
}

.mode-cards {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px;
}

.big-btn-card,
.selection-card,
.analysis-card,
.analysis-alert,
.status-card {
  border-radius: 30px;
  border: 1px solid rgba(255, 255, 255, 0.92);
  background: linear-gradient(145deg, rgba(250, 252, 255, 0.96), rgba(235, 244, 252, 0.88));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.92), 0 18px 42px rgba(111, 133, 166, 0.14);
}

.big-btn-card {
  padding: 28px;
  cursor: pointer;
}

.big-btn-card h2 {
  margin: 16px 0 10px;
  color: #203553;
}

.big-btn-card p {
  margin: 0;
  color: #6c7e96;
  line-height: 1.7;
}

.card-icon {
  width: 54px;
  height: 54px;
  padding: 14px;
  border-radius: 18px;
  color: #5d83bc;
  background: rgba(255, 255, 255, 0.74);
}

.selection-card {
  padding: 28px;
}

.selection-card .card-header {
  justify-content: center;
}

.control-boundary {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
  margin: 22px 0 8px;
}

.control-boundary-item {
  position: relative;
  overflow: hidden;
  padding: 18px 19px;
  border: 1px solid rgba(255, 255, 255, 0.88);
  border-radius: 22px;
  background: rgba(255, 255, 255, 0.62);
}

.control-boundary-item::before {
  position: absolute;
  inset: 0 auto 0 0;
  width: 4px;
  content: '';
  background: #6e97c8;
}

.control-boundary-item.configurable::before {
  background: #55a77d;
}

.control-boundary-item.fixed::before {
  background: #929dae;
}

.control-boundary-item span {
  color: #8290a4;
  font-size: 12px;
}

.control-boundary-item strong {
  display: block;
  margin: 8px 0;
  color: #203553;
}

.control-boundary-item p {
  margin: 0;
  color: #6c7e96;
  font-size: 13px;
  line-height: 1.65;
}

.result-boundary {
  margin: 18px 0 0;
}

.card-header {
  display: flex;
  align-items: center;
  gap: 12px;
}

.card-header h3,
.analysis-heading h2 {
  margin: 0;
  color: #203553;
}

.execute-btn {
  min-width: 240px;
}

.step-2-wrapper,
.loading-box {
  display: flex;
  align-items: center;
  justify-content: center;
}

.loading-box {
  min-height: 460px;
  flex-direction: column;
}

.analysis-heading,
.analysis-alerts,
.status-row,
.analysis-grid {
  display: flex;
  gap: 18px;
}

.analysis-heading {
  align-items: center;
  justify-content: space-between;
  margin-bottom: 18px;
}

.result-kicker {
  display: block;
  margin-bottom: 7px;
  color: #7897bc;
  font-size: 11px;
  letter-spacing: 0.18em;
}

.asset-line {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 9px;
  color: #75859a;
  font-size: 13px;
}

.asset-line strong {
  color: #3b506f;
}

.asset-line span {
  padding-left: 10px;
  border-left: 1px solid rgba(116, 137, 164, 0.3);
}

.result-hero {
  display: flex;
  align-items: stretch;
  justify-content: space-between;
  gap: 20px;
  margin-bottom: 18px;
  padding: 24px 26px;
  border: 1px solid rgba(255, 255, 255, 0.92);
  border-radius: 30px;
  background:
    radial-gradient(circle at 8% 0%, rgba(139, 181, 224, 0.2), transparent 38%),
    linear-gradient(145deg, rgba(250, 252, 255, 0.97), rgba(230, 241, 250, 0.9));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.92), 0 20px 44px rgba(111, 133, 166, 0.14);
}

.result-hero > div:first-child {
  flex: 1;
}

.result-hero h3 {
  margin: 13px 0 8px;
  color: #203553;
  font-size: 19px;
  line-height: 1.65;
}

.result-hero p {
  margin: 0;
  color: #6c7e96;
}

.result-grade {
  display: inline-flex;
  padding: 7px 13px;
  border-radius: 999px;
  color: #4c6f9e;
  background: rgba(110, 151, 200, 0.14);
  font-size: 13px;
  font-weight: 700;
}

.result-grade.success {
  color: #347b59;
  background: rgba(79, 169, 123, 0.15);
}

.result-grade.warning {
  color: #a8641e;
  background: rgba(211, 138, 56, 0.16);
}

.result-grade.danger {
  color: #a4515d;
  background: rgba(189, 103, 114, 0.16);
}

.result-hero-metrics {
  display: grid;
  grid-template-columns: repeat(3, minmax(120px, 1fr));
  gap: 12px;
  min-width: 450px;
}

.result-hero-metrics > div {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  padding: 18px 15px;
  border: 1px solid rgba(255, 255, 255, 0.88);
  border-radius: 20px;
  background: rgba(255, 255, 255, 0.68);
}

.result-hero-metrics span {
  margin-bottom: 9px;
  color: #7c8ca2;
  font-size: 12px;
  text-align: center;
}

.result-hero-metrics strong {
  color: #294a75;
  font-size: 25px;
}

.analysis-alerts {
  margin-bottom: 18px;
}

.analysis-alert {
  flex: 1;
  padding: 20px 22px;
  display: flex;
  align-items: center;
  gap: 14px;
}

.analysis-alert strong,
.status-card strong {
  display: block;
  color: #203553;
}

.analysis-alert span,
.status-card span {
  color: #6c7e96;
}

.analysis-alert.warning {
  background: linear-gradient(145deg, rgba(255, 247, 232, 0.96), rgba(247, 236, 217, 0.88));
}

.analysis-alert.success {
  background: linear-gradient(145deg, rgba(236, 248, 234, 0.96), rgba(228, 244, 224, 0.88));
}

.blocked-analysis-card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 18px 22px;
  padding: 28px;
}

.blocked-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 58px;
  height: 58px;
  border-radius: 20px;
  color: #a8641e;
  background: rgba(211, 138, 56, 0.16);
  font-size: 28px;
}

.blocked-analysis-card h3 {
  margin: 7px 0 9px;
  color: #203553;
  font-size: 24px;
}

.blocked-analysis-card p,
.card-explain {
  margin: 0 0 16px;
  color: #6c7e96;
  line-height: 1.75;
}

.blocked-missing-list {
  grid-column: 1 / -1;
}

.status-row {
  margin-top: 10px;
  flex-wrap: wrap;
}

.status-card {
  flex: 1 1 260px;
  padding: 18px 20px;
}

.status-card-kicker {
  margin-bottom: 10px;
  color: #7d8ca3;
  font-size: 12px;
  letter-spacing: 0.18em;
}

.status-card strong {
  font-size: 24px;
  margin-bottom: 8px;
}

.status-card.danger {
  background: linear-gradient(145deg, rgba(250, 237, 237, 0.96), rgba(246, 228, 228, 0.88));
}

.analysis-grid {
  align-items: stretch;
}

.part-summary-grid {
  display: grid;
  grid-template-columns: 1fr 1.2fr;
  margin-bottom: 18px;
}

.analysis-card {
  padding: 20px;
}

.missing-card {
  margin-bottom: 18px;
}

.missing-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}

.missing-item {
  padding: 14px 16px;
  border-radius: 20px;
  background: rgba(255, 244, 232, 0.72);
}

.missing-item strong {
  display: block;
  margin-bottom: 6px;
  color: #9b5f1a;
}

.missing-item span {
  color: #6c7e96;
  line-height: 1.7;
}

.analysis-card-title {
  margin-bottom: 16px;
  color: #203553;
  font-weight: 700;
}

.trend-title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.trend-switches {
  display: inline-flex;
  align-items: center;
  gap: 12px;
}

.whole-grid {
  display: grid;
  grid-template-columns: 1fr 1.25fr;
  margin-bottom: 18px;
}

.criterion-list {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.part-score-panel {
  min-height: 220px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 10px;
}

.part-score-panel strong {
  color: #203553;
  font-size: 42px;
}

.part-score-panel span {
  color: #6c7e96;
}

.criterion-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 18px;
  border-radius: 22px;
  background: rgba(255, 255, 255, 0.74);
}

.criterion-item strong,
.metric-cell strong {
  display: block;
  color: #203553;
}

.criterion-item span,
.metric-cell span {
  color: #70809a;
  font-size: 13px;
}

.criterion-item b {
  color: #2d4d7b;
  font-size: 26px;
}

.dimension-note-grid {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 10px;
  margin-bottom: 16px;
}

.dimension-note {
  padding: 12px 13px;
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.72);
  border: 1px solid rgba(222, 231, 242, 0.84);
}

.dimension-note strong {
  display: block;
  margin-bottom: 7px;
  color: #304a6b;
  font-size: 13px;
}

.dimension-note span {
  color: #6c7e96;
  font-size: 12px;
  line-height: 1.6;
}

.table-head-help {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}

.table-head-help .el-icon {
  color: #7b91af;
  cursor: help;
}

.result-table-card {
  margin-bottom: 18px;
}

.result-table :deep(.el-table__cell) {
  vertical-align: top;
}

.metric-cell {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.trend-card {
  flex: 1;
}

.score-chart {
  height: 320px;
}

.trend-chart {
  height: 560px;
}

@media (max-width: 1200px) {
  .mode-cards,
  .analysis-alerts,
  .status-row,
  .analysis-grid,
  .result-hero {
    grid-template-columns: 1fr;
    flex-direction: column;
  }

  .control-boundary {
    grid-template-columns: 1fr;
  }

  .dimension-note-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .result-hero-metrics {
    min-width: 0;
    width: 100%;
  }

  .whole-grid {
    grid-template-columns: 1fr;
  }

  .trend-chart {
    height: 420px;
  }
}

@media (max-width: 680px) {
  .dimension-note-grid {
    grid-template-columns: 1fr;
  }

  .blocked-analysis-card {
    grid-template-columns: 1fr;
  }

  .trend-title-row {
    align-items: flex-start;
    flex-direction: column;
  }
}
</style>
