<template>
  <div class="dashboard-container">
    <!-- 顶部标题栏 -->
    <div class="header-container">
      <div class="header-left">
        <div class="back-button" @click="openRegionSelector">
          {{ currentView }}
          <span>···</span>
        </div>
      </div>
      <!-- <h1 class="header-title">集团视角数据看板</h1> -->
      <div class="header-right">
        <div class="date-range-wrapper">
          <el-date-picker v-model="dateRange" type="daterange" range-separator="至" start-placeholder="开始日期"
            end-placeholder="结束日期" format="YYYY-MM-DD" value-format="YYYY-MM-DD" @change="handleDateChange" />
        </div>
        <el-button type="primary" :icon="Refresh" @click="refreshData" class="refresh-btn">
          刷新数据
        </el-button>
      </div>
    </div>

    <!-- 主内容区 - 6个卡片 -->
    <div class="content-container">
      <!-- 第一行：外协管理、风险管理、隐患管理 -->
      <div class="card-row">
        <!-- 外协管理卡片 -->
        <div class="dashboard-card">
          <div class="card-header">
            <div class="card-title">
              <span class="card-icon">👥</span>
              外协管理
            </div>
            <!-- <el-button type="text" class="manage-btn">管理</el-button> -->
          </div>
          <div class="card-content">
            <div class="donut-chart-wrapper">
              <Echart :options="outsourcingChartOption" width="100%" height="200px" />
            </div>
            <div class="region-distribution">
              <div class="distribution-title">区域分布</div>
              <div class="distribution-list">
                <div class="distribution-item" v-for="item in outsourcingDistribution" :key="item.region">
                  <span class="dot" :style="{ backgroundColor: item.color }"></span>
                  <span class="region-name">{{ item.region }}</span>
                  <span class="region-count">{{ item.count }}人</span>
                  <span class="region-percent">({{ item.percent }})</span>
                </div>
              </div>
            </div>
          </div>
        </div>

        <!-- 风险管理卡片 -->
        <div class="dashboard-card">
          <div class="card-header">
            <div class="card-title">
              <span class="card-icon">🛡️</span>
              风险管理
            </div>
            <!-- <el-button type="text" class="manage-btn">管理</el-button> -->
          </div>
          <div class="card-content">
            <div class="donut-chart-wrapper">
              <Echart :options="riskChartOption" width="100%" height="200px" />
            </div>
            <div class="risk-distribution">
              <div class="distribution-title">风险等级分布</div>
              <div class="distribution-list">
                <div class="distribution-item" v-for="item in riskDistribution" :key="item.level">
                  <span class="dot" :style="{ backgroundColor: item.color }"></span>
                  <span class="region-name">{{ item.level }}</span>
                  <span class="region-count">{{ item.count }}项</span>
                  <span class="region-percent">({{ item.percent }})</span>
                </div>
              </div>
            </div>
          </div>
        </div>

        <!-- 隐患管理卡片 -->
        <div class="dashboard-card">
          <div class="card-header">
            <div class="card-title">
              <span class="card-icon warning">⚠️</span>
              隐患管理
            </div>
            <!-- <el-button type="text" class="manage-btn">管理</el-button> -->
          </div>
          <div class="card-content">
            <div class="line-chart-wrapper">
              <Echart :options="hiddenDangerChartOption" width="100%" height="180px" />
            </div>
            <div class="rectification-status">
              <div class="distribution-title">整改状态</div>
              <div class="status-list">
                <div class="status-item" v-for="item in rectificationStatus" :key="item.status">
                  <span class="dot" :style="{ backgroundColor: item.color }"></span>
                  <span class="status-name">{{ item.status }}</span>
                  <span class="status-count">{{ item.count }}项</span>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 第二行：高危作业、应急预案、安全培训 -->
      <div class="card-row">
        <!-- 高危作业卡片 -->
        <div class="dashboard-card">
          <div class="card-header">
            <div class="card-title">
              <span class="card-icon">🚧</span>
              高危作业
            </div>
            <!-- <el-button type="text" class="manage-btn">管理</el-button> -->
          </div>
          <div class="card-content">
            <div class="high-risk-top">
              <div class="donut-chart-wrapper-small">
                <Echart :options="highRiskChartOption" width="100%" height="280px" />
              </div>
              <div class="operation-type-list">
                <div class="operation-type-item" v-for="item in operationTypeDistribution" :key="item.type">
                  <span class="dot" :style="{ backgroundColor: item.color }"></span>
                  <span class="operation-name">{{ item.type }}</span>
                  <div class="operation-bar-wrapper">
                    <div class="operation-bar" :style="{ width: item.percent, backgroundColor: item.color }"></div>
                  </div>
                  <span class="operation-percent">{{ item.count }}项</span>
                </div>
              </div>
            </div>
            <div class="park-operation-distribution">
              <div class="distribution-title">区域作业分布</div>
              <div class="distribution-list">
                <div class="distribution-item" v-for="item in operationDistribution" :key="item.region">
                  <span class="region-name">{{ item.region }}</span>
                  <span class="region-count">{{ item.count }}项</span>
                </div>
              </div>
            </div>
          </div>
        </div>

        <!-- 应急预案卡片 -->
        <div class="dashboard-card">
          <div class="card-header">
            <div class="card-title">
              <span class="card-icon">📄</span>
              应急预案
            </div>
            <!-- <el-button type="text" class="manage-btn">管理</el-button> -->
          </div>
          <div class="card-content">
            <div class="emergency-plan-top">
              <div class="progress-chart-wrapper">
                <Echart :options="emergencyPlanChartOption" width="100%" height="280px" />
              </div>
              <div class="drill-info">
                <div class="drill-item">
                  <span>应完成演练</span>
                  <span class="drill-number">{{ emergencyPlanTotal }}次</span>
                </div>
                <div class="drill-item">
                  <span>已完成演练</span>
                  <span class="drill-number">{{ emergencyPlanCompleted }}次</span>
                </div>
              </div>
            </div>
            <div class="regional-progress">
              <div class="distribution-title">区域演练完成率</div>
              <div class="progress-list">
                <div class="progress-item" v-for="item in regionalDrillProgress" :key="item.region">
                  <span class="region-name">{{ item.region }}</span>
                  <div class="progress-bar-wrapper">
                    <div class="progress-bar" :style="{ width: item.percent, backgroundColor: '#10b981' }"></div>
                  </div>
                  <span class="progress-percent">{{ item.percent }}</span>
                </div>
              </div>
            </div>
          </div>
        </div>

        <!-- 安全培训卡片 -->
        <div class="dashboard-card">
          <div class="card-header">
            <div class="card-title">
              <span class="card-icon">📚</span>
              安全培训
            </div>
            <!-- <el-button type="text" class="manage-btn">管理</el-button> -->
          </div>
          <div class="card-content">
            <div class="bar-chart-wrapper">
              <Echart :options="safetyTrainingChartOption" width="100%" height="180px" />
            </div>
            <div class="regional-progress">
              <div class="distribution-title">区域培训完成率</div>
              <div class="progress-list">
                <div class="progress-item" v-for="item in regionalTrainingProgress" :key="item.region">
                  <span class="region-name">{{ item.region }}</span>
                  <div class="progress-bar-wrapper">
                    <div class="progress-bar" :style="{ width: item.percent }"></div>
                  </div>
                  <span class="progress-percent">{{ item.percent }}</span>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 区域选择弹窗 -->
    <RegionSelector v-model="regionSelectorVisible" :modelSelected="selectedRegion" :regions="regionOption"
      @change="onRegionChange" />
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { Refresh } from '@element-plus/icons-vue'
import Echart from '@/components/Echart/src/Echart.vue'
import RegionSelector from '@/views/screen/components/RegionSelector.vue'
import { getTableList } from '@/api/design/report'
import type { EChartsOption } from 'echarts'
import dayjs from 'dayjs'
import { 
  getHiddenDangerManagementData, 
  getHiddenDangerManagementDataWeek, 
  getHiddenDangerManagementDataMonth,
  getOutsourcingManagementData, 
  getRiskManagementData, 
  getHighRiskManagementData,
  getEmergencyPlanManagementData,
  getTrainingManagementData
} from '@/api'

defineOptions({ name: 'Home10' })

// 类型定义
interface RegionItem {
  name: string
  code: string
}

interface DistributionItem {
  region?: string
  level?: string
  status?: string
  count: number
  percent?: string
  color: string
}

const router = useRouter()
const route = useRoute()

// 区域选择相关
const currentView = ref('集团')
const regionSelectorVisible = ref(false)
const selectedRegion = ref('')
const regionOption = ref<RegionItem[]>([])

// 时间选择相关 - 默认当前月起止，如果路由中有日期范围参数则使用
const getCurrentMonthRange = () => {
  const start = dayjs().startOf('month').format('YYYY-MM-DD')
  const end = dayjs().endOf('month').format('YYYY-MM-DD')
  return [start, end]
}
// 从路由参数读取日期范围，如果没有则使用默认值
const getInitialDateRange = () => {
  const sDate = route.query.sDate as string
  const eDate = route.query.eDate as string
  if (sDate && eDate) {
    return [sDate, eDate]
  }
  return getCurrentMonthRange()
}
const dateRange = ref(getInitialDateRange())

// 外协管理数据
const outsourcingTotal = ref<number>(0) // 外协人员总数
const outsourcingDistribution = ref<DistributionItem[]>([])

// 区域颜色配置
const regionColors = ['#3b82f6', '#8b5cf6', '#06b6d4', '#10b981', '#f59e0b', '#ef4444', '#ec4899']

// 初始化外协管理数据
const initOutsourcingData = async () => {
  try {
    const response = await getOutsourcingManagementData({
      sDate: dateRange.value[0],
      eDate: dateRange.value[1],
      pageNo: 1,
      pageSize: 10000
    })
    
    console.log('外协管理接口返回:', response)
    
    // axios封装后，response就是 { code: 0, data: {...}, msg: "" }
    // 所以records在 response.data.records
    const records = response?.records || []
    
    if (records && records.length > 0) {
      // 计算总人数（从records中累加total）
      const total = records.reduce((sum: number, item: any) => {
        return sum + Number(item.total || 0)
      }, 0)
      
      outsourcingTotal.value = total
      
      // 处理区域分布数据
      outsourcingDistribution.value = records.map((item: any, index: number) => {
        const count = Number(item.total || 0)
        const percent = total > 0 ? ((count / total) * 100).toFixed(1) + '%' : '0%'
        const color = regionColors[index % regionColors.length]
        
        return {
          region: item.name,
          count,
          percent,
          color
        }
      })
      
      console.log('处理后的外协管理数据:', {
        total: outsourcingTotal.value,
        distribution: outsourcingDistribution.value
      })
    } else {
      // 如果没有数据，重置为空
      outsourcingTotal.value = 0
      outsourcingDistribution.value = []
      console.log('外协管理无数据')
    }
  } catch (error) {
    console.error('获取外协管理数据失败:', error)
    // 如果接口失败，重置为空
    outsourcingTotal.value = 0
    outsourcingDistribution.value = []
  }
}

// 风险管理数据
const riskTotal = ref<number>(0) // 风险总数
const riskDistribution = ref<DistributionItem[]>([])

// 风险等级映射和颜色配置
const riskLevelMap: Record<string, { name: string; color: string }> = {
  '低': { name: '低风险', color: '#10b981' },
  '低风险': { name: '低风险', color: '#10b981' },
  '一般': { name: '一般风险', color: '#f59e0b' },
  '一般风险': { name: '一般风险', color: '#f59e0b' },
  '较大': { name: '较大风险', color: '#ef4444' },
  '较大风险': { name: '较大风险', color: '#ef4444' },
  '重大': { name: '重大风险', color: '#dc2626' },
  '重大风险': { name: '重大风险', color: '#dc2626' }
}

// 隐患管理数据
const hiddenDangerTrend = ref<Array<{ date: string; general: number; major: number }>>([])
const rectificationStatus = ref<DistributionItem[]>([
  { status: '已逾期', count: 0, color: '#ef4444' },
  { status: '处理中', count: 0, color: '#f59e0b' },
  { status: '已处理', count: 0, color: '#10b981' }
])

// 高危作业数据
const highRiskTotal = ref<number>(0) // 高危作业总数
const operationTypeDistribution = ref<Array<{ type: string; count: number; percent: string; color: string }>>([]) // 作业类型分布（用于环形图）
const operationDistribution = ref<Array<{ region: string; count: number }>>([]) // 区域作业分布

// 作业类型颜色配置
const operationTypeColors: Record<string, string> = {
  '动火作业': '#f59e0b',
  '高处作业': '#8b5cf6',
  '临时用电': '#3b82f6',
  '有限空间': '#ec4899',
  '动土作业': '#10b981',
  '吊装作业': '#ef4444'
}

// 应急预案数据
const emergencyPlanTotal = ref<number>(0) // 应完成演练总数
const emergencyPlanCompleted = ref<number>(0) // 已完成演练总数
const regionalDrillProgress = ref<Array<{ region: string; percent: string }>>([
  { region: '华北区域', percent: '85%' },
  { region: '华东区域', percent: '75%' },
  { region: '华南区域', percent: '70%' }
])

// 安全培训数据
const trainingBarData = ref<{ regions: string[]; trainingCount: number[]; participants: number[] }>({
  regions: [],
  trainingCount: [],
  participants: []
})
const regionalTrainingProgress = ref<Array<{ region: string; percent: string }>>([])

// 外协管理环形图配置
const outsourcingChartOption = computed<EChartsOption>(() => {
  // 准备图表数据
  const chartData = outsourcingDistribution.value.map(item => ({
    value: item.count,
    name: item.region,
    itemStyle: { color: item.color }
  }))
  
  // 如果没有数据，显示空状态
  if (chartData.length === 0 || outsourcingTotal.value === 0) {
    return {
      tooltip: {
        trigger: 'item',
        formatter: '{a} <br/>{b}: {c} ({d}%)'
      },
      series: [
        {
          name: '外协人员',
          type: 'pie',
          radius: ['55%', '75%'],
          center: ['50%', '50%'],
          avoidLabelOverlap: false,
          itemStyle: {
            borderRadius: 0,
            borderColor: 'transparent',
            borderWidth: 0
          },
          label: {
            show: true,
            position: 'center',
            formatter: () => {
              return `${outsourcingTotal.value}\n外协人员总数`
            },
            fontSize: 16,
            fontWeight: 'bold',
            color: '#333'
          },
          data: [
            { value: 1, name: '暂无数据', itemStyle: { color: '#e5e7eb' } }
          ]
        }
      ]
    }
  }
  
  return {
    tooltip: {
      trigger: 'item',
      formatter: '{a} <br/>{b}: {c} ({d}%)'
    },
    series: [
      {
        name: '外协人员',
        type: 'pie',
        radius: ['55%', '75%'],
        center: ['50%', '50%'],
        avoidLabelOverlap: false,
        itemStyle: {
          borderRadius: 0,
          borderColor: 'transparent',
          borderWidth: 0
        },
        label: {
          show: true,
          position: 'center',
          formatter: () => {
            return `${outsourcingTotal.value}\n外协人员总数`
          },
          fontSize: 16,
          fontWeight: 'bold',
          color: '#333'
        },
        emphasis: {
          label: {
            show: true,
            fontSize: 18,
            fontWeight: 'bold'
          }
        },
        data: chartData
      }
    ]
  }
})

// 风险管理环形图配置
const riskChartOption = computed<EChartsOption>(() => {
  const chartData = riskDistribution.value
    .filter(item => item.count > 0) // 只显示有数据的风险等级
    .map(item => ({
      value: item.count,
      name: item.level,
      itemStyle: { color: item.color }
    }))
  
  // 如果没有数据，显示空状态
  if (chartData.length === 0 || riskTotal.value === 0) {
    return {
      tooltip: { trigger: 'item', formatter: '{a} <br/>{b}: {c} ({d}%)' },
      series: [{
        name: '风险',
        type: 'pie',
        radius: ['55%', '75%'],
        center: ['50%', '50%'],
        avoidLabelOverlap: false,
        itemStyle: { borderRadius: 0, borderColor: 'transparent', borderWidth: 0 },
        label: {
          show: true,
          position: 'center',
          formatter: () => `${riskTotal.value}\n风险总数`,
          fontSize: 16,
          fontWeight: 'bold',
          color: '#333'
        },
        data: [{ value: 1, name: '暂无数据', itemStyle: { color: '#e5e7eb' } }]
      }]
    }
  }
  
  return {
    tooltip: { trigger: 'item', formatter: '{a} <br/>{b}: {c} ({d}%)' },
    series: [{
      name: '风险',
      type: 'pie',
      radius: ['55%', '75%'],
      center: ['50%', '50%'],
      avoidLabelOverlap: false,
      itemStyle: { borderRadius: 0, borderColor: 'transparent', borderWidth: 0 },
      label: {
        show: true,
        position: 'center',
        formatter: () => `${riskTotal.value}\n风险总数`,
        fontSize: 16,
        fontWeight: 'bold',
        color: '#333'
      },
      emphasis: { label: { show: true, fontSize: 18, fontWeight: 'bold' } },
      data: chartData
    }]
  }
})

// 隐患管理折线图配置
const hiddenDangerChartOption = computed<EChartsOption>(() => {
  // 提取日期和对应的数据
  const dates = hiddenDangerTrend.value.map(item => item.date)
  const generalData = hiddenDangerTrend.value.map(item => item.general)
  const majorData = hiddenDangerTrend.value.map(item => item.major)
  
  // 计算Y轴最大值（向上取整到最近的10的倍数）
  const maxValue = Math.max(
    ...generalData,
    ...majorData,
    10 // 最小值为10，避免图表显示过小
  )
  const yAxisMax = Math.ceil(maxValue / 10) * 10 || 10
  
  return {
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'cross'
      }
    },
    legend: {
      data: ['一般隐患', '重大隐患'],
      top: 0,
      textStyle: {
        fontSize: 12
      }
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      top: '12%',
      containLabel: true
    },
    xAxis: {
      type: 'category',
      boundaryGap: false,
      data: dates.length > 0 ? dates : []
    },
    yAxis: {
      type: 'value',
      max: yAxisMax
    },
    series: [
      {
        name: '一般隐患',
        type: 'line',
        smooth: true,
        data: generalData.length > 0 ? generalData : [],
        itemStyle: { color: '#f59e0b' },
        lineStyle: { color: '#f59e0b', width: 2 },
        areaStyle: {
          color: {
            type: 'linear',
            x: 0,
            y: 0,
            x2: 0,
            y2: 1,
            colorStops: [
              { offset: 0, color: 'rgba(245, 158, 11, 0.3)' },
              { offset: 1, color: 'rgba(245, 158, 11, 0.05)' }
            ]
          }
        }
      },
      {
        name: '重大隐患',
        type: 'line',
        smooth: true,
        data: majorData.length > 0 ? majorData : [],
        itemStyle: { color: '#ef4444' },
        lineStyle: { color: '#ef4444', width: 2 },
        areaStyle: {
          color: {
            type: 'linear',
            x: 0,
            y: 0,
            x2: 0,
            y2: 1,
            colorStops: [
              { offset: 0, color: 'rgba(239, 68, 68, 0.3)' },
              { offset: 1, color: 'rgba(239, 68, 68, 0.05)' }
            ]
          }
        }
      }
    ]
  }
})

// 高危作业环形图配置
const highRiskChartOption = computed<EChartsOption>(() => {
  const chartData = operationTypeDistribution.value
    .filter(item => item.count > 0) // 只显示有数据的作业类型
    .map(item => ({
      value: item.count,
      name: item.type,
      itemStyle: { color: item.color }
    }))
  
  // 如果没有数据，显示空状态
  if (chartData.length === 0 || highRiskTotal.value === 0) {
    return {
      tooltip: { trigger: 'item', formatter: '{a} <br/>{b}: {c} ({d}%)' },
      series: [{
        name: '高危作业',
        type: 'pie',
        radius: ['45%', '65%'],
        center: ['50%', '50%'],
        avoidLabelOverlap: false,
        itemStyle: { borderRadius: 0, borderColor: 'transparent', borderWidth: 0 },
        label: {
          show: true,
          position: 'center',
          formatter: () => `${highRiskTotal.value}\n累计作业`,
          fontSize: 15,
          fontWeight: 'bold',
          color: '#333'
        },
        data: [{ value: 1, name: '暂无数据', itemStyle: { color: '#e5e7eb' } }]
      }]
    }
  }
  
  return {
    tooltip: { trigger: 'item', formatter: '{a} <br/>{b}: {c} ({d}%)' },
    series: [{
      name: '高危作业',
      type: 'pie',
      radius: ['49%', '61%'],
      center: ['50%', '50%'],
      avoidLabelOverlap: false,
      itemStyle: { borderRadius: 0, borderColor: 'transparent', borderWidth: 0 },
      label: {
        show: true,
        position: 'center',
        formatter: () => `${highRiskTotal.value}\n累计作业`,
        fontSize: 15,
        fontWeight: 'bold',
        color: '#333'
      },
      emphasis: { label: { show: true, fontSize: 20, fontWeight: 'bold' } },
      data: chartData
    }]
  }
})

// 应急预案环形进度图配置
const emergencyPlanChartOption = computed<EChartsOption>(() => {
  const percent = emergencyPlanTotal.value > 0 
    ? ((emergencyPlanCompleted.value / emergencyPlanTotal.value) * 100).toFixed(0)
    : 0
  
  return {
    tooltip: { trigger: 'item' },
    series: [{
      name: '演练完成率',
      type: 'pie',
      radius: ['49%', '61%'],
      center: ['50%', '50%'],
      avoidLabelOverlap: false,
      itemStyle: { borderRadius: 0, borderColor: 'transparent', borderWidth: 0, color: '#10b981' },
      label: {
        show: true,
        position: 'center',
        formatter: () => `${percent}%\n演练完成率`,
        fontSize: 15,
        fontWeight: 'bold',
        color: '#333'
      },
      emphasis: { label: { show: true, fontSize: 20, fontWeight: 'bold' } },
      data: [
        { value: emergencyPlanCompleted.value, name: '已完成', itemStyle: { color: '#10b981' } },
        { value: emergencyPlanTotal.value - emergencyPlanCompleted.value, name: '未完成', itemStyle: { color: '#e5e7eb' } }
      ]
    }]
  }
})

// 安全培训柱状图配置
const safetyTrainingChartOption = computed<EChartsOption>(() => {
  const regions = trainingBarData.value.regions || []
  const trainingCount = trainingBarData.value.trainingCount || []
  const participants = trainingBarData.value.participants || []
  
  // 计算堆叠后的最大值（培训次数 + 参与人次）
  const stackedValues = trainingCount.map((count, index) => count + (participants[index] || 0))
  const maxValue = Math.max(...stackedValues, 10) // 最小值为10，避免图表显示过小
  const yAxisMax = Math.ceil(maxValue / 10) * 10 || 10
  
  return {
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'shadow'
      },
      formatter: (params: any) => {
        let result = `${params[0].axisValue}<br/>`
        params.forEach((item: any) => {
          result += `${item.marker}${item.seriesName}: ${item.value}<br/>`
        })
        return result
      }
    },
    legend: {
      data: ['培训次数', '参与人次'],
      top: 10,
      textStyle: {
        fontSize: 12,
        color: '#666'
      },
      itemGap: 20
    },
    grid: {
      left: '6%',
      right: '4%',
      bottom: '0',
      top: '25%',
      containLabel: true
    },
    xAxis: {
      type: 'category',
      data: regions.length > 0 ? regions : [],
      axisLine: {
        lineStyle: {
          color: '#d1d5db'
        }
      },
      axisLabel: {
        color: '#666',
        fontSize: 12
      }
    },
    yAxis: {
      type: 'value',
      max: yAxisMax,
      axisLine: {
        show: false
      },
      axisTick: {
        show: false
      },
      axisLabel: {
        color: '#666',
        fontSize: 12
      },
      splitLine: {
        lineStyle: {
          color: '#f3f4f6',
          type: 'dashed'
        }
      }
    },
    series: [
      {
        name: '培训次数',
        type: 'bar',
        stack: 'total',
        data: trainingCount.length > 0 ? trainingCount : [],
        barWidth: 32,
        itemStyle: {
          color: {
            type: 'linear',
            x: 0,
            y: 0,
            x2: 0,
            y2: 1,
            colorStops: [
              { offset: 0, color: '#3b82f6' },
              { offset: 1, color: '#2563eb' }
            ]
          },
          borderRadius: [0, 0, 0, 0]
        },
        label: {
          show: false
        },
        emphasis: {
          itemStyle: {
            shadowBlur: 10,
            shadowColor: 'rgba(59, 130, 246, 0.5)'
          }
        }
      },
      {
        name: '参与人次',
        type: 'bar',
        stack: 'total',
        data: participants.length > 0 ? participants : [],
        barWidth: 32,
        itemStyle: {
          color: {
            type: 'linear',
            x: 0,
            y: 0,
            x2: 0,
            y2: 1,
            colorStops: [
              { offset: 0, color: '#84cc16' },
              { offset: 1, color: '#65a30d' }
            ]
          },
          borderRadius: [6, 6, 0, 0]
        },
        label: {
          show: false
        },
        emphasis: {
          itemStyle: {
            shadowBlur: 10,
            shadowColor: 'rgba(132, 204, 22, 0.5)'
          }
        }
      }
    ]
  }
})

// 方法定义
const openRegionSelector = (): void => {
  regionSelectorVisible.value = true
}

const onRegionChange = (item: RegionItem): void => {
  selectedRegion.value = item.name
  router.push({
    path: '/region',
    query: { 
      region: item.name, 
      regionCode: item.code,
      sDate: dateRange.value[0],
      eDate: dateRange.value[1]
    }
  })
}

const handleDateChange = async (value: string[] | null) => {
  if (value) {
    console.log('日期范围变化:', value)
    await refreshData()
  }
}

const refreshData = async () => {
  initData()
}

// 初始化区域数据
const initRegionData = async () => {
  try {
    const { records } = await getTableList('park_info_list')
    if (records && records.length > 0) {
      // 去重region字段，使用Map来确保唯一性
      const regionMap = new Map<string, RegionItem>()
      records.forEach((el: any) => {
        if (!regionMap.has(el.region)) {
          regionMap.set(el.region, {
            name: el.region,
            code: el.region_id
          })
        }
      })
      // 转换为数组
      regionOption.value = Array.from(regionMap.values())
    }
  } catch (error) {
    console.error('初始化区域数据失败:', error)
  }
}

// 初始化风险管理数据
const initRiskData = async () => {
  try {
    const response = await getRiskManagementData({
      sDate: dateRange.value[0],
      eDate: dateRange.value[1],
      pageNo: 1,
      pageSize: 10000
    })
    
    console.log('风险管理接口返回:', response)
    
    const records = response?.records || []
    
    if (records && records.length > 0) {
      // 计算风险总数
      const total = records.reduce((sum: number, item: any) => {
        return sum + Number(item.total || 0)
      }, 0)
      
      riskTotal.value = total
      
      // 处理风险等级分布数据
      riskDistribution.value = records.map((item: any) => {
        const count = Number(item.total || 0)
        const percent = total > 0 ? ((count / total) * 100).toFixed(1) + '%' : '0%'
        
        // 映射风险等级名称和颜色
        const levelKey = item.name || ''
        const levelConfig = riskLevelMap[levelKey] || { name: levelKey || '未知', color: '#9ca3af' }
        
        return {
          level: levelConfig.name,
          count,
          percent,
          color: levelConfig.color
        }
      })
      
      // 如果没有数据，确保包含所有四个风险等级（显示为0）
      const allLevels = [
        { level: '低风险', count: 0, percent: '0%', color: '#10b981' },
        { level: '一般风险', count: 0, percent: '0%', color: '#f59e0b' },
        { level: '较大风险', count: 0, percent: '0%', color: '#ef4444' },
        { level: '重大风险', count: 0, percent: '0%', color: '#dc2626' }
      ]
      
      // 合并数据：如果某个等级有数据就使用数据，没有就保留0
      const mergedDistribution = allLevels.map(defaultItem => {
        const existingItem = riskDistribution.value.find(item => item.level === defaultItem.level)
        return existingItem || defaultItem
      })
      
      riskDistribution.value = mergedDistribution
      
      console.log('处理后的风险管理数据:', {
        total: riskTotal.value,
        distribution: riskDistribution.value
      })
    } else {
      // 如果没有数据，设置为默认值
      riskTotal.value = 0
      riskDistribution.value = [
        { level: '低风险', count: 0, percent: '0%', color: '#10b981' },
        { level: '一般风险', count: 0, percent: '0%', color: '#f59e0b' },
        { level: '较大风险', count: 0, percent: '0%', color: '#ef4444' },
        { level: '重大风险', count: 0, percent: '0%', color: '#dc2626' }
      ]
      console.log('风险管理无数据')
    }
  } catch (error) {
    console.error('获取风险管理数据失败:', error)
    // 如果接口失败，设置为默认值
    riskTotal.value = 0
    riskDistribution.value = [
      { level: '低风险', count: 0, percent: '0%', color: '#10b981' },
      { level: '一般风险', count: 0, percent: '0%', color: '#f59e0b' },
      { level: '较大风险', count: 0, percent: '0%', color: '#ef4444' },
      { level: '重大风险', count: 0, percent: '0%', color: '#dc2626' }
    ]
  }
}

// 根据日期范围判断应该调用哪个接口
const getHiddenDangerApi = (startDate: string, endDate: string) => {
  const start = dayjs(startDate)
  const end = dayjs(endDate)
  const daysDiff = end.diff(start, 'day') + 1 // 包含起始和结束日期
  
  // 如果日期范围 <= 7天，使用"天"接口
  if (daysDiff <= 7) {
    return getHiddenDangerManagementData
  }
  // 如果日期范围 <= 30天，使用"周"接口
  else if (daysDiff <= 30) {
    return getHiddenDangerManagementDataWeek
  }
  // 如果日期范围 > 30天，使用"月"接口
  else {
    return getHiddenDangerManagementDataMonth
  }
}

const initDangerData = async () => {
  try {
    // 根据日期范围选择接口
    const apiFunc = getHiddenDangerApi(dateRange.value[0], dateRange.value[1])
    
    const response = await apiFunc({
      sDate: dateRange.value[0],
      eDate: dateRange.value[1],
      pageNo: 1,
      pageSize: 10000
    })
    
    console.log('隐患管理接口返回:', response)
    
    const records = response?.records || []
    
    if (records && records.length > 0) {
      // 按日期和等级分组统计，用于折线图
      const trendMap = new Map<string, { general: number; major: number }>()
      
      // 按状态统计，用于整改状态列表
      const statusMap = new Map<string, number>()
      
      records.forEach((item: any) => {
        const dayname = item.dayname || ''
        const level = item.name || ''
        const status = item.status || ''
        const count = Number(item.total || 0)
        
        // 统计趋势数据（按日期和等级）
        if (dayname) {
          if (!trendMap.has(dayname)) {
            trendMap.set(dayname, { general: 0, major: 0 })
          }
          const trend = trendMap.get(dayname)!
          if (level === '一般' || level === '一般隐患') {
            trend.general += count
          } else if (level === '重大' || level === '重大隐患') {
            trend.major += count
          }
        }
        
        // 统计状态数据
        if (status) {
          statusMap.set(status, (statusMap.get(status) || 0) + count)
        }
      })
      
      // 转换为数组并按日期排序
      hiddenDangerTrend.value = Array.from(trendMap.entries())
        .map(([date, counts]) => ({ date, ...counts }))
        .sort((a, b) => {
          // 提取日期中的数字部分进行排序
          const numA = parseInt(a.date.replace('日', '')) || 0
          const numB = parseInt(b.date.replace('日', '')) || 0
          return numA - numB
        })
      
      // 更新整改状态数据
      rectificationStatus.value = [
        { 
          status: '已逾期', 
          count: statusMap.get('已逾期') || 0, 
          color: '#ef4444' 
        },
        { 
          status: '处理中', 
          count: statusMap.get('处理中') || 0, 
          color: '#f59e0b' 
        },
        { 
          status: '已处理', 
          count: statusMap.get('已处理') || 0, 
          color: '#10b981' 
        }
      ]
      
      console.log('处理后的隐患管理数据:', {
        trend: hiddenDangerTrend.value,
        status: rectificationStatus.value
      })
    } else {
      // 如果没有数据，重置为空
      hiddenDangerTrend.value = []
      rectificationStatus.value = [
        { status: '已逾期', count: 0, color: '#ef4444' },
        { status: '处理中', count: 0, color: '#f59e0b' },
        { status: '已处理', count: 0, color: '#10b981' }
      ]
      console.log('隐患管理无数据')
    }
  } catch (error) {
    console.error('获取隐患管理数据失败:', error)
    // 如果接口失败，重置为空
    hiddenDangerTrend.value = []
    rectificationStatus.value = [
      { status: '已逾期', count: 0, color: '#ef4444' },
      { status: '处理中', count: 0, color: '#f59e0b' },
      { status: '已处理', count: 0, color: '#10b981' }
    ]
  }
}

const initHighRiskData = async () => {
  try {
    const response = await getHighRiskManagementData({
      sDate: dateRange.value[0],
      eDate: dateRange.value[1],
      pageNo: 1,
      pageSize: 10000
    })
    
    console.log('高危作业接口返回:', response)
    
    const records = response?.records || []
    
    if (records && records.length > 0) {
      // 按作业类型分组统计，用于环形图
      const typeMap = new Map<string, number>()
      
      // 按区域分组统计，用于区域分布列表
      const areaMap = new Map<string, number>()
      
      records.forEach((item: any) => {
        const itemType = item.item || ''
        const area = item.area || ''
        const count = Number(item.total || 0)
        
        // 统计作业类型
        if (itemType) {
          typeMap.set(itemType, (typeMap.get(itemType) || 0) + count)
        }
        
        // 统计区域分布
        if (area) {
          areaMap.set(area, (areaMap.get(area) || 0) + count)
        }
      })
      
      // 计算总数
      const total = Array.from(typeMap.values()).reduce((sum, count) => sum + count, 0)
      highRiskTotal.value = total
      
      // 处理作业类型分布数据
      operationTypeDistribution.value = Array.from(typeMap.entries())
        .map(([type, count]) => ({
          type,
          count,
          percent: total > 0 ? ((count / total) * 100).toFixed(1) + '%' : '0%',
          color: operationTypeColors[type] || '#9ca3af' // 如果没有配置颜色，使用灰色
        }))
        .sort((a, b) => b.count - a.count) // 按数量降序排序
      
      // 处理区域分布数据
      operationDistribution.value = Array.from(areaMap.entries())
        .map(([region, count]) => ({
          region,
          count
        }))
        .sort((a, b) => b.count - a.count) // 按数量降序排序
      
      console.log('处理后的高危作业数据:', {
        total: highRiskTotal.value,
        typeDistribution: operationTypeDistribution.value,
        areaDistribution: operationDistribution.value
      })
    } else {
      // 如果没有数据，重置为空
      highRiskTotal.value = 0
      operationTypeDistribution.value = []
      operationDistribution.value = []
      console.log('高危作业无数据')
    }
  } catch (error) {
    console.error('获取高危作业数据失败:', error)
    // 如果接口失败，重置为空
    highRiskTotal.value = 0
    operationTypeDistribution.value = []
    operationDistribution.value = []
  }
}

const initEmergencyPlanData = async () => {
  try {
    const response = await getEmergencyPlanManagementData({
      sDate: dateRange.value[0],
      eDate: dateRange.value[1],
      pageNo: 1,
      pageSize: 10000
    })
    
    console.log('应急预案接口返回:', response)
    
    const records = response?.records || []
    
    if (records && records.length > 0) {
      // 统计应完成演练总数（所有记录的total总和）
      const total = records.reduce((sum: number, item: any) => {
        return sum + Number(item.total || 0)
      }, 0)
      
      emergencyPlanTotal.value = total
      
      // 统计已完成演练数（根据状态判断）
      // 可能的完成状态：已完成、已完成演练、已执行等
      const completedCount = records.reduce((sum: number, item: any) => {
        const status = item.status || ''
        const count = Number(item.total || 0)
        // 判断是否已完成：包含"完成"或"已执行"的状态
        if (status.includes('完成') || status.includes('已执行')) {
          return sum + count
        }
        return sum
      }, 0)
      
      emergencyPlanCompleted.value = completedCount
      
      // 按区域统计演练完成率
      const areaMap = new Map<string, { total: number; completed: number }>()
      
      records.forEach((item: any) => {
        const area = item.area || ''
        const count = Number(item.total || 0)
        const status = item.status || ''
        const isCompleted = status.includes('完成') || status.includes('已执行')
        
        if (area) {
          if (!areaMap.has(area)) {
            areaMap.set(area, { total: 0, completed: 0 })
          }
          const areaData = areaMap.get(area)!
          areaData.total += count
          if (isCompleted) {
            areaData.completed += count
          }
        }
      })
      
      // 转换为数组并计算完成率
      regionalDrillProgress.value = Array.from(areaMap.entries())
        .map(([region, data]) => {
          const percent = data.total > 0 
            ? ((data.completed / data.total) * 100).toFixed(0) + '%'
            : '0%'
          return { region, percent }
        })
        .sort((a, b) => {
          // 按完成率降序排序
          const percentA = parseFloat(a.percent)
          const percentB = parseFloat(b.percent)
          return percentB - percentA
        })
      
      console.log('处理后的应急预案数据:', {
        total: emergencyPlanTotal.value,
        completed: emergencyPlanCompleted.value,
        regionalProgress: regionalDrillProgress.value
      })
    } else {
      // 如果没有数据，重置为空
      emergencyPlanTotal.value = 0
      emergencyPlanCompleted.value = 0
      regionalDrillProgress.value = []
      console.log('应急预案无数据')
    }
  } catch (error) {
    console.error('获取应急预案数据失败:', error)
    // 如果接口失败，重置为空
    emergencyPlanTotal.value = 0
    emergencyPlanCompleted.value = 0
    regionalDrillProgress.value = []
  }
}

const initTrainingData = async () => {
  try {
    const response = await getTrainingManagementData({
      sDate: dateRange.value[0],
      eDate: dateRange.value[1],
      pageNo: 1,
      pageSize: 10000
    })
    
    console.log('安全培训接口返回:', response)
    
    const records = response?.records || []
    
    if (records && records.length > 0) {
      // 按区域分组统计
      const areaMap = new Map<string, { trainingCount: number; participants: number }>()
      
      records.forEach((item: any) => {
        // 只统计有区域字段的记录
        if (!item.area) {
          return
        }
        
        const area = item.area
        const trainingCount = Number(item.plannum || 0) // 计划数量作为培训次数
        const participants = Number(item.exenum || 0) // 执行数量作为参与人次
        
        if (!areaMap.has(area)) {
          areaMap.set(area, { trainingCount: 0, participants: 0 })
        }
        const areaData = areaMap.get(area)!
        areaData.trainingCount += trainingCount
        areaData.participants += participants
      })
      
      // 转换为数组并排序
      const areaDataArray = Array.from(areaMap.entries())
        .map(([region, data]) => ({
          region,
          ...data,
          // 计算完成率（参与人次 / 培训次数 * 100%）
          percent: data.trainingCount > 0
            ? ((data.participants / data.trainingCount) * 100).toFixed(0) + '%'
            : '0%'
        }))
        .sort((a, b) => {
          // 按培训次数降序排序
          return b.trainingCount - a.trainingCount
        })
      
      // 更新柱状图数据
      trainingBarData.value = {
        regions: areaDataArray.map(item => item.region),
        trainingCount: areaDataArray.map(item => item.trainingCount),
        participants: areaDataArray.map(item => item.participants)
      }
      
      // 更新区域培训完成率数据
      regionalTrainingProgress.value = areaDataArray.map(item => ({
        region: item.region,
        percent: item.percent
      }))
      
      console.log('处理后的安全培训数据:', {
        barData: trainingBarData.value,
        regionalProgress: regionalTrainingProgress.value
      })
    } else {
      // 如果没有数据，重置为空
      trainingBarData.value = {
        regions: [],
        trainingCount: [],
        participants: []
      }
      regionalTrainingProgress.value = []
      console.log('安全培训无数据')
    }
  } catch (error) {
    console.error('获取安全培训数据失败:', error)
    // 如果接口失败，重置为空
    trainingBarData.value = {
      regions: [],
      trainingCount: [],
      participants: []
    }
    regionalTrainingProgress.value = []
  }
}

const initData = async () => {
  await initRegionData()
  initOutsourcingData()
  
  initRiskData()
  initDangerData()
  initHighRiskData()
  initEmergencyPlanData()
  initTrainingData()
}

onMounted(async () => {
  initData()
})
</script>

<style lang="scss" scoped>
.dashboard-container {
  width: 100%;
  min-height: 100vh;
  background: #f5f7fa;
  padding: 20px;
  box-sizing: border-box;

  // 确保内容不会贴边
  max-width: 100%;
  overflow-x: hidden;
}

.header-container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: white;
  padding: 16px 24px;
  border-radius: 8px;
  margin-bottom: 20px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);

  .header-left {
    // flex: 1;
    display: flex;
    align-items: center;

    .back-button {
      display: inline-flex;
      align-items: center;
      padding: 8px 16px;
      background: #409eff;
      border: 1px solid #e5e7eb;
      border-radius: 6px;
      cursor: pointer;
      transition: all 0.3s;
      font-size: 16px;
      color: white;
      user-select: none;
      font-weight: 600;
      span {
        margin-left: 8px;
        font-size: 18px;
        color: #6b7280;
      }

      &:hover {
        background: #e5e7eb;
        border-color: #d1d5db;
      }

      &:active {
        transform: scale(0.98);
      }
    }
  }

  .header-title {
    flex: 1;
    text-align: center;
    font-size: 20px;
    font-weight: bold;
    color: #1f2937;
    margin: 0;
  }

  .header-right {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 16px;
    min-width: 0; // 防止flex子元素溢出

    .date-range-wrapper {
      :deep(.el-date-editor) {
        width: 280px;
        max-width: 100%;
      }
    }

    .refresh-btn {
      display: flex;
      align-items: center;
      gap: 6px;
      flex-shrink: 0; // 防止按钮被压缩
    }
  }
}

.content-container {
  display: flex;
  flex-direction: column;
  gap: 20px;
  width: 100%;
  box-sizing: border-box;
}

.card-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
  width: 100%;
  box-sizing: border-box;

  @media (max-width: 1400px) {
    grid-template-columns: repeat(2, 1fr);
  }

  @media (max-width: 768px) {
    grid-template-columns: 1fr;
    gap: 16px;
  }
}

@media (max-width: 1200px) {
  .high-risk-top,
  .emergency-plan-top {
    gap: 10px;
  }
  
  .donut-chart-wrapper-small,
  .progress-chart-wrapper {
    min-width: 160px;
  }
  
  .operation-type-list,
  .drill-info {
    min-width: 140px;
    max-width: 180px;
  }
}

@media (max-width: 768px) {
  .high-risk-top,
  .emergency-plan-top {
    flex-direction: column;
    align-items: stretch;
  }
  
  .donut-chart-wrapper-small,
  .progress-chart-wrapper {
    min-width: 100%;
    max-width: 100%;
    height: 220px;
    min-height: 220px;
  }
  
  .operation-type-list,
  .drill-info {
    min-width: 100%;
    max-width: 100%;
  }
}

.dashboard-card {
  background: white;
  border-radius: 8px;
  padding: 20px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  display: flex;
  flex-direction: column;
  transition: box-shadow 0.3s;

  &:hover {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  }

  .card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 16px;
    padding-bottom: 12px;
    border-bottom: 1px solid #e5e7eb;

    .card-title {
      display: flex;
      align-items: center;
      gap: 8px;
      font-size: 16px;
      font-weight: bold;
      color: #1f2937;

      .card-icon {
        font-size: 18px;

        &.warning {
          color: #ef4444;
        }
      }
    }

    .manage-btn {
      color: #3b82f6;
      padding: 4px 8px;
      font-size: 14px;
      transition: color 0.3s;

      &:hover {
        color: #2563eb;
      }
    }
  }

  .card-content {
    flex: 1;
    display: flex;
    flex-direction: column;
  }
}

.donut-chart-wrapper,
.donut-chart-wrapper-small {
  height: 200px;
  min-height: 200px;
}

.line-chart-wrapper,
.bar-chart-wrapper {
  height: 200px;
  background: linear-gradient(180deg, #faf9ff 0%, #ffffff 100%);
  border-radius: 8px;
  padding: 8px;
  box-sizing: border-box;
}

.bar-chart-wrapper {
  height: 215px;
}

.progress-chart-wrapper {
  height: 200px;
  min-height: 200px;
}

.high-risk-top {
  display: flex;
  align-items: center;
  gap: 15px;
  margin-bottom: 15px;
}

.donut-chart-wrapper-small {
  flex: 0.8;
  min-width: 150px;
  max-width: 45%;
  display: flex;
  align-items: center;
}

.operation-type-list {
  flex: 0.7;
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 140px;
  max-width: 170px;
  justify-content: center;
  flex-shrink: 0;
}

.operation-type-item {
  display: flex;
  align-items: center;
  gap: 8px;
}

.operation-name {
  width: 55px;
  font-size: 12px;
  color: #666;
  flex-shrink: 0;
}

.operation-bar-wrapper {
  flex: 1;
  height: 12px;
  background-color: #e5e7eb;
  border-radius: 6px;
  overflow: hidden;
}

.operation-bar {
  height: 100%;
  border-radius: 6px;
}

.operation-percent {
  font-size: 12px;
  color: #666;
  font-weight: 500;
  min-width: 40px;
  text-align: right;
  flex-shrink: 0;
}

.emergency-plan-top {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 15px;
}

.progress-chart-wrapper {
  flex: 0.8;
  min-width: 150px;
  max-width: 45%;
  display: flex;
  align-items: center;
}

.region-distribution,
.risk-distribution,
.rectification-status,
.operation-distribution,
.park-operation-distribution,
.regional-progress {
  margin-top: 8px;

  .distribution-title {
    font-size: 14px;
    font-weight: 600;
    color: #374151;
    margin-bottom: 12px;
  }

  .distribution-list,
  .status-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
  }

  .distribution-item,
  .status-item {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    color: #6b7280;
    padding: 4px 0;

    .dot {
      width: 8px;
      height: 8px;
      border-radius: 50%;
      flex-shrink: 0;
    }

    .region-name,
    .status-name {
      flex: 1;
      color: #374151;
    }

    .region-count,
    .status-count {
      color: #1f2937;
      font-weight: 500;
      margin-left: auto;
    }

    .region-percent {
      color: #9ca3af;
      margin-left: 4px;
    }
  }
}

.drill-info {
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex: 0.7;
  min-width: 140px;
  max-width: 170px;
  justify-content: center;
  flex-shrink: 0;
}

.drill-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 10px;
  background-color: #f0fdf4;
  border-radius: 4px;
  font-size: 12px;
  color: #666;
}

.drill-number {
  font-size: 16px;
  font-weight: bold;
  color: #10b981;
}

.progress-list {
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin-top: 12px;
}

.progress-item {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 13px;
  padding: 4px 0;

  .region-name {
    width: 90px;
    color: #374151;
    flex-shrink: 0;
    font-weight: 500;
  }

  .progress-bar-wrapper {
    flex: 1;
    height: 10px;
    background: #f3f4f6;
    border-radius: 5px;
    overflow: hidden;
    position: relative;
    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.05);
  }

  .progress-bar {
    height: 100%;
    border-radius: 5px;
    transition: width 0.5s ease;
    background: linear-gradient(90deg, #8b5cf6 0%, #a78bfa 100%);
    box-shadow: 0 2px 4px rgba(139, 92, 246, 0.3);
    position: relative;
    overflow: hidden;
    
    &::after {
      content: '';
      position: absolute;
      top: 0;
      left: 0;
      bottom: 0;
      right: 0;
      background: linear-gradient(
        90deg,
        transparent 0%,
        rgba(255, 255, 255, 0.3) 50%,
        transparent 100%
      );
      animation: shimmer 2s infinite;
    }
  }

  .progress-percent {
    min-width: 45px;
    text-align: right;
    color: #7c3aed;
    font-weight: 600;
    flex-shrink: 0;
    font-size: 13px;
  }
}

@keyframes shimmer {
  0% {
    transform: translateX(-100%);
  }
  100% {
    transform: translateX(100%);
  }
}
</style>
