<template>
  <view class="record-screen-page">
    <view class="screen-bg"></view>

    <view class="hero-panel">
      <view class="hero-main">
        <text class="eyebrow">RECORD COCKPIT</text>
        <text class="title">{{ record.name || '健康档案态势' }}</text>
        <text class="subtitle">{{ record.personName || selectedPersonName || '--' }} · {{ formatDateTime(record.occurTime) }}</text>
      </view>
      <view class="hero-badge">
        <text>{{ recordStateLabel || '状态' }}</text>
      </view>
    </view>

    <view class="filter-grid">
      <view class="filter-card" @click="showPerson = true">
        <text>当前成员</text>
        <view>
          <text>{{ selectedPersonName || '请选择成员' }}</text>
          <uni-icons type="right" size="16" color="#8ee8ff"></uni-icons>
        </view>
      </view>
      <view class="filter-card" @click="showRecord = true">
        <text>当前档案</text>
        <view>
          <text>{{ selectedRecordName || '请选择档案' }}</text>
          <uni-icons type="right" size="16" color="#8ee8ff"></uni-icons>
        </view>
      </view>
    </view>

    <view class="metric-grid">
      <view v-for="item in metrics" :key="item.key" class="metric-card">
        <view class="metric-dot" :class="item.type"></view>
        <text>{{ item.label }}</text>
        <view>
          <text>{{ item.value }}</text>
          <text>{{ item.unit }}</text>
        </view>
      </view>
    </view>

    <view class="panel-card">
      <view class="panel-head">
        <view>
          <text>档案画像</text>
          <text>{{ recordTypeLabel || '--' }}</text>
        </view>
      </view>
      <view class="info-list">
        <view class="info-row">
          <text>发生原因</text>
          <text>{{ etiologyLabel || '--' }}</text>
        </view>
        <view class="info-row">
          <text>发生时间</text>
          <text>{{ formatDateTime(record.occurTime) }}</text>
        </view>
        <view class="info-row" v-if="record.rehabilitationTime">
          <text>康复时间</text>
          <text>{{ formatDateTime(record.rehabilitationTime) }}</text>
        </view>
        <view class="info-row" v-if="record.duration">
          <text>康复周期</text>
          <text>{{ record.duration }}</text>
        </view>
        <view class="info-row full" v-for="item in symptomRows" :key="item.label" v-show="item.value">
          <text>{{ item.label }}</text>
          <text>{{ item.value }}</text>
        </view>
      </view>
    </view>

    <view class="panel-card">
      <view class="panel-head">
        <view>
          <text>体温趋势</text>
          <text>{{ temperatureTrendList.length }} 条体温数据 · 预警线 37.3℃</text>
        </view>
      </view>
      <view class="temperature-summary">
        <view>
          <text>平均</text>
          <text>{{ formatTemperature(temperature.averageTemp) }}℃</text>
        </view>
        <view>
          <text>最高</text>
          <text>{{ formatTemperature(temperature.maxTemp) }}℃</text>
        </view>
        <view>
          <text>最低</text>
          <text>{{ formatTemperature(temperature.minTemp) }}℃</text>
        </view>
      </view>
      <view class="chart-box tall">
        <qiun-data-charts
          v-if="chartVisible && hasChartData(temperatureChartData)"
          type="line"
          :canvasId="`${canvasIdPrefix}_temp`"
          :chartData="temperatureChartData"
          :opts="temperatureLineOpts"
          :loadingType="1"
          :ontouch="true"
          :inScrollView="true"
        />
        <view v-else class="chart-empty">暂无体温趋势数据</view>
      </view>
    </view>

    <view class="panel-card">
      <view class="panel-head">
        <view>
          <text>数据结构</text>
          <text>过程 / 就医 / 体温 / 用药记录占比</text>
        </view>
      </view>
      <view class="chart-box">
        <qiun-data-charts
          v-if="chartVisible"
          type="ring"
          :canvasId="`${canvasIdPrefix}_mix`"
          :chartData="recordMixChartData"
          :opts="ringChartOpts"
          :loadingType="1"
          :ontouch="true"
          :inScrollView="true"
        />
      </view>
    </view>

    <view class="panel-card">
      <view class="panel-head">
        <view>
          <text>体温风险分布</text>
          <text>{{ formatNumber(temperature.totalCount) }} 次</text>
        </view>
      </view>
      <view class="risk-grid">
        <view v-for="item in tempBands" :key="item.label">
          <text>{{ item.label }}</text>
          <text>{{ formatNumber(item.value) }}</text>
        </view>
      </view>
    </view>

    <view class="panel-card">
      <view class="panel-head">
        <view>
          <text>用药频次</text>
          <text>共 {{ medicineRankList.length }} 种药品 / 图表Top5</text>
        </view>
      </view>
      <view class="chart-box">
        <qiun-data-charts
          v-if="chartVisible && hasChartData(medicineChartData)"
          type="bar"
          :canvasId="`${canvasIdPrefix}_medicine`"
          :chartData="medicineChartData"
          :opts="barChartOpts"
          :loadingType="1"
          :ontouch="true"
          :inScrollView="true"
        />
        <view v-else class="chart-empty">暂无用药排行数据</view>
      </view>
      <view class="rank-list">
        <view v-for="(item, index) in medicineRankList" :key="`${item.name}-${index}`" class="rank-row">
          <text>{{ String(index + 1).padStart(2, '0') }}</text>
          <view>
            <text>{{ item.name }}</text>
            <text>{{ formatNumber(item.count) }}次 / {{ formatNumber(item.useDays) }}天 · {{ item.dosageText }}</text>
          </view>
        </view>
        <u-empty v-if="!medicineRankList.length && !loading" mode="data" text="暂无用药数据"></u-empty>
      </view>
    </view>

    <view class="panel-card">
      <view class="panel-head">
        <view>
          <text>就医费用趋势</text>
          <text>{{ formatMoney(summary.doctorCost) }}</text>
        </view>
      </view>
      <view class="chart-box">
        <qiun-data-charts
          v-if="chartVisible && hasChartData(doctorCostChartData)"
          type="column"
          :canvasId="`${canvasIdPrefix}_doctor`"
          :chartData="doctorCostChartData"
          :opts="moneyChartOpts"
          :loadingType="1"
          :ontouch="true"
          :inScrollView="true"
        />
        <view v-else class="chart-empty">暂无就医费用数据</view>
      </view>
    </view>

    <view class="tab-card">
      <view class="tab-head">
        <view>
          <text>档案全量明细</text>
          <text>共 {{ detailCount }} 条记录</text>
        </view>
      </view>
      <view class="tab-bar">
        <view v-for="item in tabs" :key="item.key" :class="['tab-item', activeTab === item.key ? 'active' : '']" @click="activeTab = item.key">
          <text>{{ item.label }}</text>
          <text>{{ item.count }}</text>
        </view>
      </view>

      <view class="detail-list">
        <template v-if="activeTab === 'process'">
          <view v-for="item in processRecordList" :key="item.id" class="detail-item">
            <view class="detail-head">
              <text>过程记录</text>
              <text>{{ formatDateTime(item.recordingTime || item.createTime) }}</text>
            </view>
            <text class="detail-content">{{ item.content || item.remark || '--' }}</text>
          </view>
        </template>

        <template v-if="activeTab === 'doctor'">
          <view v-for="item in doctorRecordList" :key="item.id" class="detail-item">
            <view class="detail-head">
              <text>{{ item.hospitalName || '就医记录' }}</text>
              <text>{{ formatDateTime(item.visitingTime) }}</text>
            </view>
            <view class="detail-grid">
              <text>科室：{{ item.departments || '--' }}</text>
              <text>医生：{{ item.doctor || '--' }}</text>
              <text>费用：{{ formatMoney(item.totalCost) }}</text>
            </view>
            <text class="detail-content" v-if="item.diagnosis">诊断：{{ item.diagnosis }}</text>
            <text class="detail-content" v-if="item.prescribe">医嘱：{{ item.prescribe }}</text>
          </view>
        </template>

        <template v-if="activeTab === 'temperature'">
          <view v-for="item in temperatureRecordList" :key="item.id" class="detail-item">
            <view class="detail-head">
              <text :class="['temperature', getTemperatureClass(item.temperature)]">{{ item.temperature || '--' }}℃</text>
              <text>{{ formatDateTime(item.measureTime) }}</text>
            </view>
            <text class="detail-content" v-if="item.remark">{{ item.remark }}</text>
          </view>
        </template>

        <template v-if="activeTab === 'medicine'">
          <view v-for="item in marRecordList" :key="item.id" class="detail-item">
            <view class="detail-head">
              <text>{{ medicineRecordName(item) }}</text>
              <text>{{ formatDateTime(item.dosingTime) }}</text>
            </view>
            <view class="detail-grid">
              <text>剂量：{{ item.dosage || '--' }}</text>
              <text>单位：{{ medicineUnitLabel(item.unit, item.unitName) || '--' }}</text>
              <text>类型：{{ marTypeLabel(item.type, item.typeName || item.marTypeName) || '--' }}</text>
            </view>
            <text class="detail-content" v-if="item.remark">{{ item.remark }}</text>
          </view>
        </template>

        <u-empty v-if="currentList.length === 0 && !loading" mode="data" text="暂无数据"></u-empty>
      </view>
    </view>

    <u-loading-page :loading="loading" loading-text="加载中"></u-loading-page>
    <u-picker :show="showPerson" :columns="[personOptions]" keyName="name" @cancel="showPerson = false" @confirm="handlePersonConfirm"></u-picker>
    <u-picker :show="showRecord" :columns="[recordOptions]" keyName="name" @cancel="showRecord = false" @confirm="handleRecordConfirm"></u-picker>
    <suspend></suspend>
  </view>
</template>

<script setup>
import { computed, ref } from 'vue'
import { onLoad, onPullDownRefresh } from '@dcloudio/uni-app'
import { getRecordScreen } from '@/api/health/statisticAnalysis'
import { listPerson } from '@/api/health/person'
import { listHealthRecord } from '@/api/health/healthRecord'
import { getDicts } from '@/api/system/dict/data.js'

const loading = ref(false)
const showPerson = ref(false)
const showRecord = ref(false)
const personOptions = ref([])
const recordOptions = ref([])
const selectedPersonId = ref(null)
const selectedRecordId = ref(null)
const screenData = ref({})
const activeTab = ref('process')
const dictMap = ref({})
const canvasIdPrefix = `h5_record_${Date.now()}`
const chartVisible = computed(() => !showPerson.value && !showRecord.value)

const record = computed(() => screenData.value.record || {})
const summary = computed(() => screenData.value.summary || {})
const temperature = computed(() => screenData.value.temperature || {})
const medicine = computed(() => screenData.value.medicine || {})
const doctor = computed(() => screenData.value.doctor || {})
const processRecordList = computed(() => sortByTime(screenData.value.processRecordList || [], 'recordingTime'))
const doctorRecordList = computed(() => sortByTime(screenData.value.doctorRecordList || [], 'visitingTime'))
const temperatureRecordList = computed(() => sortByTime(screenData.value.temperatureRecordList || [], 'measureTime'))
const marRecordList = computed(() => sortByTime(screenData.value.marRecordList || [], 'dosingTime'))
const temperatureTrendList = computed(() => {
  const list = temperature.value.temperatureList || []
  if (list.length) return list
  return temperatureRecordList.value.map((item) => ({ time: formatShortDate(item.measureTime), value: Number(item.temperature || 0) }))
})

const selectedPersonName = computed(() => personOptions.value.find((item) => item.id === selectedPersonId.value)?.name || record.value.personName || '')
const selectedRecordName = computed(() => recordOptions.value.find((item) => item.id === selectedRecordId.value)?.name || record.value.name || '')
const recordTypeLabel = computed(() => dictLabel('record_type', record.value.type, record.value.typeName || record.value.recordTypeName))
const recordStateLabel = computed(() => dictLabel('health_record_state', record.value.state, record.value.stateName))
const etiologyLabel = computed(() => dictLabel('etiology', record.value.etiology, record.value.etiologyName))

const metrics = computed(() => [
  { key: 'process', type: 'cyan', label: '过程记录', value: formatNumber(summary.value.processRecordCount), unit: '条' },
  { key: 'doctor', type: 'gold', label: '就医次数', value: formatNumber(summary.value.doctorCount), unit: '次' },
  { key: 'cost', type: 'orange', label: '就医费用', value: formatShortMoney(summary.value.doctorCost), unit: '元' },
  { key: 'medicine', type: 'green', label: '用药次数', value: formatNumber(summary.value.marCount), unit: '次' },
  { key: 'marDay', type: 'blue', label: '用药天数', value: formatNumber(summary.value.marDayCount), unit: '天' },
  { key: 'fever', type: 'red', label: '发热天数', value: formatNumber(summary.value.feverDayCount), unit: '天' }
])

const symptomRows = computed(() => [
  { label: '初期症状', value: record.value.initialSymptoms },
  { label: '中期症状', value: record.value.mediumTermSymptoms },
  { label: '后期症状', value: record.value.laterStageSymptoms },
  { label: '备注', value: record.value.remark }
])

const tempBands = computed(() => [
  { label: '正常', value: temperature.value.normalTempCount },
  { label: '低热', value: temperature.value.lowerTempCount },
  { label: '中热', value: temperature.value.middleTempCount },
  { label: '高热', value: temperature.value.higherTempCount }
])

const medicineRankList = computed(() => {
  const list = (medicine.value.marMapList || []).map((item) => ({
    name: item.medicalName || item.name || '未命名药品',
    count: Number(item.count || item.value || 0),
    useDays: Number(item.useDays || 0),
    dosageText: formatDosageText(item)
  }))
  const max = Math.max(...list.map((item) => item.count), 1)
  return list
    .sort((a, b) => b.count - a.count)
    .map((item) => ({ ...item, percent: Math.max(8, Math.round(item.count / max * 100)) }))
})

const detailCount = computed(() => processRecordList.value.length + doctorRecordList.value.length + temperatureRecordList.value.length + marRecordList.value.length)

const tabs = computed(() => [
  { key: 'process', label: '过程', count: processRecordList.value.length },
  { key: 'doctor', label: '就医', count: doctorRecordList.value.length },
  { key: 'temperature', label: '体温', count: temperatureRecordList.value.length },
  { key: 'medicine', label: '用药', count: marRecordList.value.length }
])

const currentList = computed(() => {
  const map = {
    process: processRecordList.value,
    doctor: doctorRecordList.value,
    temperature: temperatureRecordList.value,
    medicine: marRecordList.value
  }
  return map[activeTab.value] || []
})

const temperatureChartData = computed(() => ({
  categories: temperatureTrendList.value.map((item) => formatChartDate(item.time)),
  series: [{ name: '体温', data: temperatureTrendList.value.map((item) => Number(item.value || item.temperature || 0)), color: '#3ddcff' }]
}))

const recordMixChartData = computed(() => ({
  series: [
    {
      data: ensurePieData([
        { name: '过程', value: processRecordList.value.length },
        { name: '就医', value: doctorRecordList.value.length },
        { name: '体温', value: temperatureRecordList.value.length },
        { name: '用药', value: marRecordList.value.length }
      ].filter((item) => item.value > 0))
    }
  ]
}))

const medicineChartData = computed(() => {
  const topList = medicineRankList.value.slice(0, 5).reverse()
  return {
    categories: topList.map((item, index) => `TOP${topList.length - index}`),
    series: [{ name: '用药次数', data: topList.map((item) => Number(item.count || 0)) }]
  }
})

const doctorCostChartData = computed(() => {
  const list = (doctor.value.doctorCostList || []).slice(-12)
  if (list.length) {
    return {
      categories: list.map((item) => formatChartDate(item.time)),
      series: [{ name: '费用', data: list.map((item) => Number(item.value || 0)) }]
    }
  }
  const records = doctorRecordList.value.slice(-12)
  return {
    categories: records.map((item) => formatChartDate(item.visitingTime)),
    series: [{ name: '费用', data: records.map((item) => Number(item.totalCost || 0)) }]
  }
})

const baseAxis = {
  disableGrid: false,
  gridColor: 'rgba(110, 199, 255, 0.12)',
  fontColor: '#9fc7df',
  fontSize: 10,
  lineHeight: 16,
  labelCount: 4,
  marginTop: 8,
  title: ''
}

const temperatureLineOpts = computed(() => ({
  color: ['#3ddcff'],
  padding: [16, 12, 20, 8],
  dataLabel: false,
  dataPointShape: true,
  legend: { show: false },
  xAxis: { ...baseAxis, boundaryGap: 'justify', axisLine: false },
  yAxis: {
    showTitle: false,
    gridType: 'dash',
    dashLength: 4,
    gridColor: 'rgba(110, 199, 255, 0.12)',
    data: [{ min: 34, title: '', fontColor: '#9fc7df', fontSize: 10 }]
  },
  extra: {
    line: { type: 'curve', width: 2, activeType: 'hollow' },
    markLine: {
      type: 'dash',
      dashLength: 5,
      data: [{ value: 37.3, lineColor: '#ffd166', showLabel: true }]
    },
    tooltip: chartTooltip()
  }
}))

const ringChartOpts = computed(() => ({
  color: ['#3ddcff', '#ffd166', '#ff6b8b', '#58e6a7'],
  padding: [10, 10, 10, 10],
  dataLabel: true,
  title: { name: '' },
  subtitle: { name: '' },
  legend: { show: true, position: 'bottom', fontColor: '#c9f6ff', fontSize: 10, lineHeight: 18 },
  extra: {
    ring: { ringWidth: 26, activeOpacity: 0.7, activeRadius: 4, offsetAngle: 0, labelWidth: 12, border: false },
    tooltip: chartTooltip()
  }
}))

const barChartOpts = computed(() => ({
  color: ['#58e6a7'],
  padding: [12, 18, 18, 8],
  dataLabel: false,
  legend: { show: false },
  xAxis: { ...baseAxis, axisLine: false },
  yAxis: { showTitle: false, gridType: 'dash', dashLength: 4, gridColor: 'rgba(110, 199, 255, 0.12)', data: [{ min: 0, title: '', fontColor: '#9fc7df', fontSize: 10 }] },
  extra: { bar: { type: 'group', width: 12, barBorderCircle: true, linearType: 'custom' }, tooltip: chartTooltip() }
}))

const moneyChartOpts = computed(() => ({
  color: ['#ffd166'],
  padding: [12, 12, 22, 8],
  dataLabel: false,
  legend: { show: false },
  xAxis: { ...baseAxis, axisLine: false },
  yAxis: { showTitle: false, gridType: 'dash', dashLength: 4, gridColor: 'rgba(110, 199, 255, 0.12)', data: [{ min: 0, title: '', fontColor: '#9fc7df', fontSize: 10 }] },
  extra: { column: { type: 'group', width: 18, barBorderCircle: true, linearType: 'custom' }, tooltip: chartTooltip() }
}))

function initPage(options = {}) {
  if (options.recordId || options.id) {
    selectedRecordId.value = Number(options.recordId || options.id)
  }
  loading.value = true
  loadDicts()
    .then(() => loadPersonOptions())
    .then(() => loadRecordOptions())
    .then(() => {
      if (!selectedRecordId.value && recordOptions.value.length) {
        selectedRecordId.value = recordOptions.value[0].id
      }
      return loadScreen()
    })
}

function loadDicts() {
  return Promise.all([
    loadDict('record_type'),
    loadDict('health_record_state'),
    loadDict('etiology'),
    loadDict('mar_type'),
    loadDict('medical_unit')
  ])
}

function loadDict(type) {
  return getDicts(type)
    .then((res) => {
      dictMap.value[type] = normalizeDictList(res.data || [])
    })
    .catch(() => {
      dictMap.value[type] = []
    })
}

function loadPersonOptions() {
  return listPerson({ pageNum: 1, pageSize: 999 }).then((res) => {
    personOptions.value = res.rows || res.data || []
    if (!selectedPersonId.value && personOptions.value.length) {
      selectedPersonId.value = personOptions.value[0].id
    }
  })
}

function loadRecordOptions() {
  const query = { pageNum: 1, pageSize: 999 }
  if (selectedPersonId.value) query.personId = selectedPersonId.value
  return listHealthRecord(query).then((res) => {
    recordOptions.value = res.rows || res.data || []
  })
}

function loadScreen() {
  if (!selectedRecordId.value) {
    screenData.value = {}
    loading.value = false
    uni.stopPullDownRefresh()
    return Promise.resolve()
  }
  loading.value = true
  return getRecordScreen({ id: selectedPersonId.value, recordId: selectedRecordId.value, type: '1' })
    .then((res) => {
      screenData.value = res.data || {}
    })
    .finally(() => {
      loading.value = false
      uni.stopPullDownRefresh()
    })
}

function handlePersonConfirm(e) {
  const item = e.value && e.value[0]
  selectedPersonId.value = item?.id || null
  showPerson.value = false
  selectedRecordId.value = null
  loading.value = true
  loadRecordOptions().then(() => {
    selectedRecordId.value = recordOptions.value[0]?.id || null
    return loadScreen()
  })
}

function handleRecordConfirm(e) {
  const item = e.value && e.value[0]
  selectedRecordId.value = item?.id || null
  showRecord.value = false
  loadScreen()
}

function chartTooltip() {
  return {
    showBox: true,
    showArrow: true,
    bgColor: '#06162e',
    bgOpacity: 0.92,
    fontColor: '#e9fbff',
    fontSize: 11,
    lineHeight: 16,
    borderRadius: 4,
    borderWidth: 1,
    borderColor: '#3ddcff',
    padding: [8, 10, 8, 10]
  }
}

function normalizeDictList(list) {
  return (list || []).map((item) => ({
    label: item.dictLabel ?? item.label ?? item.name ?? '',
    value: item.dictValue ?? item.value ?? item.code ?? ''
  }))
}

function dictLabel(type, value, fallback = '') {
  if (fallback) return fallback
  if (value === undefined || value === null || value === '') return ''
  const option = (dictMap.value[type] || []).find((item) => String(item.value) === String(value))
  return option?.label || ''
}

function marTypeLabel(value, fallback = '') {
  return dictLabel('mar_type', value, fallback)
}

function medicineUnitLabel(value, fallback = '') {
  return dictLabel('medical_unit', value, fallback)
}

function formatDosageText(item = {}) {
  const dosage = item.dosage || '--'
  const unit = medicineUnitLabel(item.unit, item.unitName)
  return unit ? `${dosage}/${unit}` : dosage
}

function medicineRecordName(item = {}) {
  return item.name || item.medicalName || item.medicineName || item.shortNameBrandPackaging || '用药记录'
}

function ensurePieData(list) {
  return list && list.length ? list : [{ name: '暂无数据', value: 1 }]
}

function hasChartData(chartData = {}) {
  return (chartData.series || []).some((series) => (series.data || []).some((value) => Number(value || 0) !== 0))
}

function getTemperatureClass(value) {
  const temp = Number(value)
  if (temp >= 38.5) return 'danger'
  if (temp >= 37.3) return 'warning'
  return 'normal'
}

function sortByTime(list, key) {
  return [...list].sort((a, b) => new Date(a[key] || 0).getTime() - new Date(b[key] || 0).getTime())
}

function formatNumber(value) {
  const num = Number(value || 0)
  return Number.isFinite(num) ? String(num) : '0'
}

function formatMoney(value) {
  const num = Number(value || 0)
  if (!Number.isFinite(num)) return '￥0.00'
  if (num >= 10000) return `￥${(num / 10000).toFixed(1)}万`
  return `￥${num.toFixed(2)}`
}

function formatShortMoney(value) {
  const num = Number(value || 0)
  if (!Number.isFinite(num)) return '0'
  if (num >= 10000) return `${(num / 10000).toFixed(1)}万`
  return num.toFixed(0)
}

function formatTemperature(value) {
  const num = Number(value || 0)
  if (!Number.isFinite(num) || num <= 0) return '0'
  return num.toFixed(1).replace(/\.0$/, '')
}

function formatDateTime(value) {
  if (!value) return '--'
  return String(value).replace('T', ' ').slice(0, 16)
}

function formatShortDate(value) {
  if (!value) return '--'
  const text = String(value).replace('T', ' ')
  return text.length >= 10 ? text.slice(5, 10) : text
}

function formatChartDate(value) {
  if (!value) return ''
  const text = String(value).replace('T', ' ').trim()
  const datePart = text.split(' ')[0]
  if (/^\d{4}-\d{2}-\d{2}$/.test(datePart)) return datePart.slice(5).replace('-', '/')
  if (/^\d{4}-\d{2}$/.test(datePart)) return `${datePart.slice(5)}月`
  if (/^\d{2}-\d{2}$/.test(datePart)) return datePart.replace('-', '/')
  if (/^\d{2}\/\d{2}$/.test(datePart)) return datePart
  return datePart.length > 6 ? datePart.slice(0, 6) : datePart
}

onLoad(initPage)
onPullDownRefresh(loadScreen)
</script>

<style lang="scss" scoped>
.record-screen-page {
  position: relative;
  min-height: 100vh;
  padding: 24rpx;
  overflow-x: hidden;
  background: #071529;
  box-sizing: border-box;
}

.screen-bg {
  position: fixed;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(circle at 12% 0%, rgba(61, 220, 255, 0.18), transparent 42%),
    radial-gradient(circle at 88% 12%, rgba(255, 107, 139, 0.14), transparent 34%),
    linear-gradient(180deg, #0b2242 0%, #071529 50%, #06101f 100%);
}

.hero-panel,
.filter-card,
.metric-card,
.panel-card,
.tab-card {
  position: relative;
  z-index: 1;
  border: 1rpx solid rgba(132, 219, 255, 0.18);
  background: rgba(9, 30, 58, 0.78);
  box-shadow: 0 18rpx 48rpx rgba(0, 8, 20, 0.32);
  backdrop-filter: blur(10px);
}

.hero-panel {
  display: flex;
  justify-content: space-between;
  gap: 20rpx;
  padding: 30rpx;
  border-radius: 24rpx;
}

.hero-main {
  min-width: 0;
}

.eyebrow {
  color: #72e9ff;
  font-size: 21rpx;
  letter-spacing: 0;
}

.title {
  display: block;
  margin-top: 10rpx;
  color: #f2fdff;
  font-size: 40rpx;
  font-weight: 800;
  line-height: 1.18;
  overflow-wrap: anywhere;
}

.subtitle {
  display: block;
  margin-top: 12rpx;
  color: #a6cbe0;
  font-size: 24rpx;
  line-height: 1.45;
}

.hero-badge {
  flex: 0 0 auto;
  height: 54rpx;
  padding: 0 18rpx;
  display: flex;
  align-items: center;
  color: #06162e;
  background: #58e6a7;
  border-radius: 999rpx;
  font-size: 23rpx;
  font-weight: 800;
}

.filter-grid {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16rpx;
  margin-top: 20rpx;
}

.filter-card {
  padding: 20rpx;
  border-radius: 18rpx;

  > text {
    color: #82adc6;
    font-size: 22rpx;
  }

  view {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8rpx;
    margin-top: 10rpx;

    text {
      min-width: 0;
      color: #f2fdff;
      font-size: 27rpx;
      font-weight: 700;
      line-height: 1.35;
      overflow-wrap: anywhere;
    }
  }
}

@media screen and (max-width: 360px) {
  .filter-grid {
    grid-template-columns: 1fr;
  }
}

.metric-grid {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16rpx;
  margin-top: 20rpx;
}

.metric-card {
  min-height: 142rpx;
  padding: 20rpx;
  border-radius: 18rpx;
  box-sizing: border-box;

  > text {
    display: block;
    color: #95bed5;
    font-size: 23rpx;
  }

  view:last-child {
    display: flex;
    align-items: baseline;
    gap: 6rpx;
    margin-top: 8rpx;

    text:first-child {
      min-width: 0;
      color: #ffffff;
      font-size: 36rpx;
      font-weight: 800;
      line-height: 1.15;
      overflow-wrap: anywhere;
    }

    text:last-child {
      color: #9fc7df;
      font-size: 21rpx;
    }
  }
}

.metric-dot {
  width: 28rpx;
  height: 6rpx;
  margin-bottom: 14rpx;
  border-radius: 999rpx;
  background: #3ddcff;
}

.metric-dot.cyan { background: #3ddcff; }
.metric-dot.blue { background: #6ba7ff; }
.metric-dot.gold { background: #ffd166; }
.metric-dot.orange { background: #ff9f43; }
.metric-dot.red { background: #ff6b8b; }
.metric-dot.green { background: #58e6a7; }

.panel-card,
.tab-card {
  margin-top: 20rpx;
  padding: 24rpx;
  border-radius: 20rpx;
  overflow: hidden;
}

.tab-card {
  margin-bottom: 36rpx;
}

.panel-head,
.tab-head {
  display: flex;
  justify-content: space-between;
  gap: 16rpx;
  margin-bottom: 18rpx;

  view {
    min-width: 0;
  }

  text:first-child {
    display: block;
    color: #f2fdff;
    font-size: 30rpx;
    font-weight: 800;
    line-height: 1.25;
  }

  text:last-child {
    display: block;
    margin-top: 6rpx;
    color: #83aec8;
    font-size: 22rpx;
    line-height: 1.35;
  }
}

.chart-box {
  width: 100%;
  height: 430rpx;
  overflow: hidden;
}

.chart-box.tall {
  height: 470rpx;
}

.chart-empty {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #82adc6;
  font-size: 24rpx;
  border: 1rpx dashed rgba(132, 219, 255, 0.18);
  border-radius: 16rpx;
  background: rgba(7, 21, 41, 0.38);
}

.info-list,
.rank-list,
.detail-list {
  margin-top: 16rpx;
}

.info-row {
  display: flex;
  justify-content: space-between;
  gap: 18rpx;
  padding: 16rpx 0;
  border-bottom: 1rpx solid rgba(132, 219, 255, 0.1);

  text:first-child {
    flex-shrink: 0;
    color: #72e9ff;
    font-size: 24rpx;
  }

  text:last-child {
    color: #d8f6ff;
    text-align: right;
    font-size: 24rpx;
    line-height: 1.5;
    overflow-wrap: anywhere;
  }
}

.info-row.full {
  flex-direction: column;

  text:last-child {
    text-align: left;
  }
}

.temperature-summary,
.risk-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12rpx;
  margin-bottom: 18rpx;

  view {
    padding: 16rpx;
    border: 1rpx solid rgba(132, 219, 255, 0.14);
    background: rgba(7, 21, 41, 0.58);
    border-radius: 14rpx;
  }

  text {
    display: block;
  }

  text:first-child {
    color: #82adc6;
    font-size: 21rpx;
  }

  text:last-child {
    margin-top: 8rpx;
    color: #ffffff;
    font-size: 28rpx;
    font-weight: 800;
  }
}

.risk-grid {
  grid-template-columns: repeat(4, minmax(0, 1fr));
  margin-bottom: 0;

  view {
    padding: 14rpx 8rpx;
  }

  text {
    text-align: center;
  }

  text:last-child {
    font-size: 26rpx;
    line-height: 1.2;
    overflow-wrap: anywhere;
  }
}

.rank-row {
  display: flex;
  gap: 16rpx;
  padding: 16rpx 0;
  border-bottom: 1rpx solid rgba(132, 219, 255, 0.1);

  > text {
    flex: 0 0 46rpx;
    color: #58e6a7;
    font-size: 24rpx;
    font-weight: 800;
  }

  view {
    min-width: 0;
    flex: 1;
  }

  view text:first-child {
    display: block;
    color: #f2fdff;
    font-size: 25rpx;
    font-weight: 700;
    line-height: 1.4;
    overflow-wrap: anywhere;
  }

  view text:last-child {
    display: block;
    margin-top: 4rpx;
    color: #8eb8d1;
    font-size: 22rpx;
    line-height: 1.45;
    overflow-wrap: anywhere;
  }
}

.tab-bar {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 10rpx;
}

.tab-item {
  min-height: 74rpx;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4rpx;
  color: #8eb8d1;
  background: rgba(7, 21, 41, 0.58);
  border: 1rpx solid rgba(132, 219, 255, 0.12);
  border-radius: 14rpx;

  text:first-child {
    font-size: 23rpx;
    font-weight: 700;
  }

  text:last-child {
    font-size: 21rpx;
  }
}

.tab-item.active {
  color: #06162e;
  background: #3ddcff;
  border-color: #3ddcff;
}

.detail-item {
  margin-bottom: 16rpx;
  padding: 20rpx;
  border: 1rpx solid rgba(132, 219, 255, 0.12);
  background: rgba(7, 21, 41, 0.56);
  border-radius: 16rpx;
}

.detail-head {
  display: flex;
  justify-content: space-between;
  gap: 16rpx;
  align-items: flex-start;
  flex-wrap: wrap;

  text:first-child {
    min-width: 0;
    flex: 1 1 260rpx;
    color: #ffffff;
    font-size: 27rpx;
    font-weight: 800;
    line-height: 1.4;
    overflow-wrap: anywhere;
  }

  text:last-child {
    flex: 0 0 auto;
    color: #8eb8d1;
    font-size: 22rpx;
    line-height: 1.4;
  }
}

.detail-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10rpx;
  margin-top: 14rpx;

  text {
    color: #b7d7e8;
    font-size: 23rpx;
    line-height: 1.45;
    overflow-wrap: anywhere;
  }
}

.detail-content {
  display: block;
  margin-top: 14rpx;
  color: #c7e3ef;
  font-size: 24rpx;
  line-height: 1.6;
  overflow-wrap: anywhere;
}

.temperature.normal {
  color: #58e6a7;
}

.temperature.warning {
  color: #ffd166;
}

.temperature.danger {
  color: #ff6b8b;
}
</style>
