<template>
  <div class="dashboard-page">
    <div class="page-header" style="display: flex; justify-content: space-between; align-items: flex-end;">
      <div>
        <h1>全局统计看板</h1>
        <p>多维度查看工时数据：销售视角 / 研发视角 / 项目视角</p>
      </div>
      <div style="display: flex; gap: 12px; align-items: center;">
        <el-date-picker v-model="allExportDateRange" type="daterange" range-separator="至"
            start-placeholder="全部时间起" end-placeholder="全部时间止" value-format="YYYY-MM-DD" size="large" />
        <el-button type="success" @click="exportData('all')" :loading="exportingAll" size="large">
          📊 总导出 (All in One)
        </el-button>
      </div>
    </div>

    <!-- Tabs -->
    <el-tabs v-model="activeTab" type="border-card" class="dashboard-tabs">

      <!-- ==================== Sales Perspective ==================== -->
      <el-tab-pane label="📈 销售视角" name="sales">
        <div class="filter-bar">
          <el-date-picker v-model="salesFilter.dateRange" type="daterange" range-separator="至"
            start-placeholder="开始日期" end-placeholder="结束日期" value-format="YYYY-MM-DD" size="default" />

          <el-button type="primary" @click="loadSalesData">查询</el-button>
          <el-button @click="exportData('sales')">📥 导出该页</el-button>
        </div>

        <div class="two-col-layout">
          <!-- Sales Table -->
          <div class="table-col">
            <div class="section-title">📋 销售人员汇总 (点击展开查看研发明细)</div>
            <el-table :data="salesSummary" stripe v-loading="salesLoading" style="width: 100%" row-key="sales_name">
              <el-table-column type="expand">
                <template #default="props">
                  <div style="padding: 10px 40px; background: rgba(0,0,0,0.2);">
                    <div style="margin-bottom: 8px; font-weight: bold; color: var(--text-secondary);">
                      [ {{ props.row.sales_name }} ] 的研发工时消耗明细：
                    </div>
                    <el-table :data="props.row.rdList" border style="width: 100%" size="small">
                      <el-table-column prop="rd_name" label="研发人员" width="150" />
                      <el-table-column prop="total_hours" label="消耗工时(h)" width="120" />
                      <el-table-column prop="work_days" label="工作天数" width="120" />
                    </el-table>
                  </div>
                </template>
              </el-table-column>
              <el-table-column prop="sales_name" label="销售人员" min-width="140" />
              <el-table-column prop="project_count" label="项目数" min-width="100" />
              <el-table-column prop="rd_count" label="涉及研发" min-width="120" />
              <el-table-column prop="total_hours" label="总消耗工时(h)" min-width="130" sortable />
            </el-table>
          </div>
          <!-- Sales Charts -->
          <div class="chart-col">
            <div class="chart-card">
              <div class="chart-title">销售占用工时占比（饼图）</div>
              <div ref="salesChartRef" class="big-chart"></div>
            </div>
            <div class="chart-card" style="margin-top: 16px">
              <div class="chart-title">各销售工时对比（柱状图）</div>
              <div ref="salesBarRef" class="big-chart"></div>
            </div>
          </div>
        </div>
      </el-tab-pane>

      <!-- ==================== R&D Perspective ==================== -->
      <el-tab-pane label="👨‍💻 研发视角" name="rd">
        <div class="filter-bar">
          <el-date-picker v-model="rdFilter.dateRange" type="daterange" range-separator="至"
            start-placeholder="开始日期" end-placeholder="结束日期" value-format="YYYY-MM-DD" size="default" />
          <el-select v-model="rdFilter.user_id" placeholder="全部研发" clearable size="default" style="width: 150px">
            <el-option v-for="u in rdUsers" :key="u.id" :label="u.realname" :value="u.id" />
          </el-select>
          <el-button type="primary" @click="loadRdData">查询</el-button>
          <el-button @click="exportData('rd')">📥 导出该页</el-button>
        </div>

        <div class="two-col-layout">
          <!-- R&D Table -->
          <div class="table-col">
             <div class="section-title">📋 研发人员填报明细</div>
            <el-table :data="rdData" stripe v-loading="rdLoading" style="width: 100%">
              <el-table-column prop="user_name" label="研发人员" min-width="120" />
              <el-table-column prop="client_name" label="客户/项目" min-width="180" />
              <el-table-column prop="work_date" label="日期" min-width="120" />
              <el-table-column prop="hours" label="工时(h)" min-width="100" />
              <el-table-column prop="remark" label="备注" min-width="180" />
            </el-table>
          </div>
          <!-- R&D Charts -->
          <div class="chart-col">
            <div class="chart-card">
              <div class="chart-title">研发人员工时产出占比（饼图）</div>
              <div ref="rdChartRef" class="big-chart"></div>
            </div>
            <div class="chart-card" style="margin-top: 16px">
              <div class="chart-title">各研发人员工时对比（柱状图）</div>
              <div ref="rdBarRef" class="big-chart"></div>
            </div>
          </div>
        </div>
      </el-tab-pane>

      <!-- ==================== Project Perspective ==================== -->
      <el-tab-pane label="🏢 项目视角" name="project">
        <div class="filter-bar">
          <el-date-picker v-model="projFilter.dateRange" type="daterange" range-separator="至"
            start-placeholder="开始日期" end-placeholder="结束日期" value-format="YYYY-MM-DD" size="default" style="margin-right: 12px;" />
          <el-select v-model="projFilter.sales_id" clearable placeholder="全部销售" style="width: 140px; margin-right: 12px;">
            <el-option v-for="u in salesUsers" :key="u.id" :label="u.realname" :value="u.id" />
          </el-select>
          <el-button type="primary" @click="loadProjectData">查询</el-button>
          <el-button @click="exportData('project')">📥 导出该页</el-button>
        </div>

        <div class="two-col-layout">
          <!-- Project Table -->
          <div class="table-col">
            <div class="section-title">📋 项目总览 (点击展开查看研发明细)</div>
            <el-table :data="projectData" stripe v-loading="projLoading" style="width: 100%" row-key="client_id">
              <el-table-column type="expand">
                <template #default="props">
                  <div style="padding: 10px 40px; background: rgba(0,0,0,0.2);">
                    <div style="margin-bottom: 8px; font-weight: bold; color: var(--text-secondary);">
                      [ {{ props.row.client_name }} ] 的参与研发明细：
                    </div>
                    <el-table :data="props.row.rdList" border style="width: 100%" size="small">
                      <el-table-column prop="rd_name" label="研发人员" width="150" />
                      <el-table-column prop="total_hours" label="消耗工时(h)" width="120" sortable />
                      <el-table-column prop="work_days" label="工作天数" width="120" />
                      <el-table-column prop="first_date" label="首次介入" width="120" />
                      <el-table-column prop="last_date" label="最近介入" width="120" />
                    </el-table>
                  </div>
                </template>
              </el-table-column>
              <el-table-column prop="client_name" label="客户/项目" min-width="200" />
              <el-table-column prop="sales_name" label="所属销售" min-width="120" />
              <el-table-column prop="client_status" label="状态" min-width="90">
                <template #default="{ row }">
                  <el-tag :type="row.client_status === 1 ? 'success' : 'info'" effect="dark" round>
                    {{ row.client_status === 1 ? '进行中' : '已结算' }}
                  </el-tag>
                </template>
              </el-table-column>
              <el-table-column prop="total_hours" label="总工时(h)" min-width="110" sortable />
              <el-table-column prop="rd_count" label="研发人数" min-width="100" />
            </el-table>
          </div>
          <!-- Project Charts -->
          <div class="chart-col">
            <div class="chart-card">
              <div class="chart-title">项目工时分布（饼图）</div>
              <div ref="projectChartRef" class="big-chart"></div>
            </div>
            <div class="chart-card" style="margin-top: 16px">
              <div class="chart-title">各项目工时对比（柱状图）</div>
              <div ref="projectBarRef" class="big-chart"></div>
            </div>
          </div>
        </div>
      </el-tab-pane>

      <!-- ==================== Matrix Summary ==================== -->
      <el-tab-pane label="📊 研发工时汇总" name="matrix">
        <div class="filter-bar">
          <el-date-picker v-model="matrixFilter.dateRange" type="daterange" range-separator="至"
            start-placeholder="开始日期" end-placeholder="结束日期" value-format="YYYY-MM-DD" size="default" />
          <el-button type="primary" @click="loadMatrixData">查询</el-button>
          <el-button @click="exportMatrix">📥 导出该页</el-button>
        </div>
        <div class="content-card" style="margin-top: 16px; overflow-x: auto;" v-loading="matrixLoading">
          <table class="matrix-table" v-if="matrixRows.length">
            <thead>
              <tr>
                <th class="row-header">研发人员</th>
                <th v-for="col in matrixCols" :key="col">{{ col }}</th>
                <th class="total-col">合计</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="(row, ri) in matrixRows" :key="ri" :class="{ 'total-row': ri === matrixRows.length - 1 }">
                <td class="row-header">{{ row.label }}</td>
                <td v-for="col in matrixCols" :key="col">{{ row.cells[col] || '-' }}</td>
                <td class="total-col">{{ row.total }}</td>
              </tr>
            </tbody>
          </table>
          <el-empty v-else description="暂无工时数据" />
        </div>
      </el-tab-pane>

      <!-- ==================== Fill-out Calendar ==================== -->
      <el-tab-pane label="📅 填报日历" name="calendar">
        <div class="filter-bar">
          <el-date-picker v-model="calendarFilter.month" type="month" placeholder="选择月份"
            value-format="YYYY-MM" size="default" :clearable="false" @change="handleCalendarFilterChange" style="width: 140px; margin-right: 12px;" />
            
          <el-radio-group v-model="calendarViewMode" size="default" style="margin-right: 12px;">
            <el-radio-button value="grid">全员概览</el-radio-button>
            <el-radio-button value="individual">个人日历</el-radio-button>
          </el-radio-group>

          <el-select v-if="calendarViewMode === 'individual'" v-model="calendarFilter.user_id" placeholder="选择研发人员" size="default" style="width: 150px" @change="loadIndividualCalendarData">
            <el-option v-for="u in rdUsers" :key="u.id" :label="u.realname" :value="u.id" />
          </el-select>
        </div>

        <!-- 1. All Staff Heatmap Grid (全员概览) -->
        <div v-if="calendarViewMode === 'grid'" class="content-card" style="margin-top: 16px; overflow-x: auto;" v-loading="calendarLoading">
          <div class="card-title">
            <span>👥 R&D 全员填报状态矩阵 ({{ calendarFilter.month }})</span>
            <div class="calendar-legends">
              <span class="legend-item"><span class="dot green"></span>已满8h</span>
              <span class="legend-item"><span class="dot yellow"></span>未满8h</span>
              <span class="legend-item"><span class="dot red"></span>漏填报</span>
              <span class="legend-item"><span class="dot gray"></span>周末/未到期</span>
            </div>
          </div>
          <table class="grid-table" v-if="gridData.length">
            <thead>
              <tr>
                <th class="name-header">姓名</th>
                <th v-for="day in daysInSelectedMonth" :key="day" class="day-col">
                  {{ day }}
                  <span class="day-weekday">{{ getDayLabel(day) }}</span>
                </th>
                <th class="total-header">累计工时</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="row in gridData" :key="row.user_id" class="grid-row">
                <td class="name-header clickable" @click="switchToIndividual(row.user_id)">
                  {{ row.user_name }}
                  <span class="arrow-tip">📅</span>
                </td>
                <td v-for="day in daysInSelectedMonth" :key="day" 
                    :class="['status-cell', getGridCellClass(row, day)]"
                    :title="getGridCellTitle(row, day)">
                  <span class="cell-hours">{{ getGridCellHours(row, day) }}</span>
                </td>
                <td class="total-cell">{{ row.total_hours }}h</td>
              </tr>
            </tbody>
          </table>
          <el-empty v-else description="暂无研发人员数据" />
        </div>

        <!-- 2. Individual Calendar View (个人日历) -->
        <div v-else class="two-col-layout" style="margin-top: 16px;" v-loading="calendarLoading">
          <!-- Calendar Card -->
          <div class="table-col" style="flex: 1.5;">
            <div class="content-card" style="margin-bottom: 0;">
              <div class="card-title">
                <span>📅 {{ selectedDeveloperName }} 的个人日历 ({{ calendarFilter.month }})</span>
                <div class="calendar-legends">
                  <span class="legend-item"><span class="dot green"></span>已满8h</span>
                  <span class="legend-item"><span class="dot yellow"></span>未满8h</span>
                  <span class="legend-item"><span class="dot red"></span>漏填</span>
                  <span class="legend-item"><span class="dot gray"></span>周末/未到期</span>
                </div>
              </div>

              <!-- Inline Calendar -->
              <el-calendar v-model="adminCalendarDate" :key="adminCalendarKey">
                <template #date-cell="{ data }">
                  <div class="day-cell-content" @click="handleAdminSelectDate(data.day)">
                    <div class="day-header">
                      <span class="day-num">{{ data.day.split('-')[2] }}</span>
                      <span v-if="data.type === 'current-month' && isRestDay(data.day)" class="weekend-tag">休</span>
                    </div>
                    <div class="day-body" v-if="data.type === 'current-month'">
                      <div v-if="getAdminDayHours(data.day) >= 8" class="status-badge filled">
                        {{ getAdminDayHours(data.day) }}h
                      </div>
                      <div v-else-if="getAdminDayHours(data.day) > 0" class="status-badge partial">
                        {{ getAdminDayHours(data.day) }}h
                      </div>
                      <div v-else-if="isAdminPastUnfilled(data.day)" class="status-badge unfilled">
                        未填报
                      </div>
                    </div>
                  </div>
                </template>
              </el-calendar>
            </div>
          </div>

          <!-- Side Details Card -->
          <div class="chart-col" style="flex: 1; min-width: 320px;">
            <!-- Month Summary Card -->
            <div class="content-card">
              <div class="card-title">📊 月度数据汇总</div>
              <div class="mini-stats-grid">
                <div class="mini-stat-item green-glow">
                  <div class="label">满额填报</div>
                  <div class="value green-text">{{ individualStats.fullDays }}<span class="unit">天</span></div>
                </div>
                <div class="mini-stat-item yellow-glow">
                  <div class="label">部分填报</div>
                  <div class="value yellow-text">{{ individualStats.partialDays }}<span class="unit">天</span></div>
                </div>
                <div class="mini-stat-item red-glow">
                  <div class="label">漏填工作日</div>
                  <div class="value red-text">{{ individualStats.unfilledDays }}<span class="unit">天</span></div>
                </div>
                <div class="mini-stat-item purple-glow">
                  <div class="label">累计总工时</div>
                  <div class="value purple-text">{{ individualStats.totalHours }}<span class="unit">小时</span></div>
                </div>
              </div>
            </div>

            <!-- Date records card -->
            <div class="content-card" style="margin-top: 16px;">
              <div class="card-title">📋 {{ adminSelectedDate }} 工时明细</div>
              <el-table :data="adminSelectedDateRecords" stripe style="width: 100%" size="small">
                <el-table-column prop="client_name" label="客户/项目" min-width="130" />
                <el-table-column prop="hours" label="工时" width="70" />
                <el-table-column prop="remark" label="备注" min-width="120" show-overflow-tooltip />
              </el-table>
              <el-empty v-if="!adminSelectedDateRecords.length" description="当天暂无工时记录" :image-size="50" />
            </div>
          </div>
        </div>
      </el-tab-pane>

    </el-tabs>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted, nextTick, watch, onBeforeUnmount } from 'vue'
import { ElMessage } from 'element-plus'
import { adminApi } from '../../api'
import * as echarts from 'echarts'

const activeTab = ref('sales')
const salesUsers = ref([])
const rdUsers = ref([])

const salesChartRef = ref(null)
const rdChartRef = ref(null)
const projectChartRef = ref(null)
const salesBarRef = ref(null)
const rdBarRef = ref(null)
const projectBarRef = ref(null)

let salesChartInstance = null
let rdChartInstance = null
let projectChartInstance = null
let salesBarInstance = null
let rdBarInstance = null
let projectBarInstance = null
const exportingAll = ref(false)

const getRecentMonthRange = () => {
  const end = new Date()
  const start = new Date()
  start.setMonth(start.getMonth() - 1)
  const pad = (n) => String(n).padStart(2, '0')
  const format = (d) => `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`
  return [format(start), format(end)]
}
const defaultRange = getRecentMonthRange()

const allExportDateRange = ref(defaultRange)

// ====== Sales ======
const salesFilter = reactive({ dateRange: defaultRange })
const salesRawData = ref([])
const salesDetailData = ref([])
const salesLoading = ref(false)

const salesSummary = computed(() => {
  const map = {}
  
  // Aggregate detail row by rd_id into the sales object
  salesDetailData.value.forEach(row => {
    if (!map[row.sales_id]) {
      map[row.sales_id] = {
        sales_id: row.sales_id,
        sales_name: row.sales_name,
        projects: new Set(),
        rdMap: {},
        total_hours: 0
      }
    }
    const sales = map[row.sales_id]
    if (!sales.rdMap[row.rd_id]) {
      sales.rdMap[row.rd_id] = { rd_name: row.rd_name, total_hours: 0, work_days: 0 }
    }
    sales.rdMap[row.rd_id].total_hours += row.total_hours
    sales.rdMap[row.rd_id].work_days += row.work_days
  })

  // Add project counts & total hours from raw overviews to base object
  salesRawData.value.forEach(row => {
    if (!map[row.sales_id]) {
      map[row.sales_id] = {
        sales_id: row.sales_id,
        sales_name: row.sales_name,
        projects: new Set(),
        rdMap: {},
        total_hours: 0
      }
    }
    map[row.sales_id].projects.add(row.client_id)
    map[row.sales_id].total_hours += row.total_hours
  })

  return Object.values(map).map(m => {
    return {
      sales_name: m.sales_name,
      project_count: m.projects.size,
      rd_count: Object.keys(m.rdMap).length,
      total_hours: Math.round(m.total_hours * 10) / 10,
      rdList: Object.values(m.rdMap).sort((a,b)=> b.total_hours - a.total_hours)
    }
  })
})

async function loadSalesData() {
  salesLoading.value = true
  try {
    const params = {}
    if (salesFilter.dateRange) {
      params.start_date = salesFilter.dateRange[0]
      params.end_date = salesFilter.dateRange[1]
    }
    
    const [overview, detail] = await Promise.all([
      adminApi.getSalesStats(params),
      adminApi.getSalesDetail(params)
    ])
    salesRawData.value = overview.data
    salesDetailData.value = detail.data
    await nextTick()
    const pieData = salesSummary.value.filter(s => s.total_hours > 0).map(s => ({name: s.sales_name, value: s.total_hours}))
    renderPieChart(salesChartRef, salesChartInstance, 'sales', pieData)
    const salesBarData = salesSummary.value.filter(s => s.total_hours > 0)
    renderBarChart(salesBarRef, salesBarInstance, 'sales',
      salesBarData.map(s => s.sales_name),
      salesBarData.map(s => s.total_hours)
    )
  } finally { salesLoading.value = false }
}

// ====== R&D ======
const rdFilter = reactive({ dateRange: defaultRange, user_id: '' })
const rdData = ref([])
const rdLoading = ref(false)

const rdSummary = computed(() => {
  const map = {}
  rdData.value.forEach(row => {
    if (!map[row.user_id]) {
      map[row.user_id] = { name: row.user_name, value: 0 }
    }
    map[row.user_id].value += row.hours
  })
  return Object.values(map).filter(r => r.value > 0)
})

async function loadRdData() {
  rdLoading.value = true
  try {
    const params = {}
    if (rdFilter.dateRange) {
      params.start_date = rdFilter.dateRange[0]
      params.end_date = rdFilter.dateRange[1]
    }
    if (rdFilter.user_id) params.user_id = rdFilter.user_id
    const res = await adminApi.getRdStats(params)
    rdData.value = res.data
    await nextTick()
    renderPieChart(rdChartRef, rdChartInstance, 'rd', rdSummary.value)
    renderBarChart(rdBarRef, rdBarInstance, 'rd',
      rdSummary.value.map(r => r.name),
      rdSummary.value.map(r => r.value)
    )
  } finally { rdLoading.value = false }
}

// ====== Project ======
const projFilter = reactive({ dateRange: defaultRange, sales_id: '' })
const projectData = ref([])
const projLoading = ref(false)
const projectDetailData = ref([])

async function loadProjectData() {
  projLoading.value = true
  try {
    const params = {}
    if (projFilter.dateRange) {
      params.start_date = projFilter.dateRange[0]
      params.end_date = projFilter.dateRange[1]
    }
    if (projFilter.sales_id) params.sales_id = projFilter.sales_id
    const [overview, detail] = await Promise.all([
      adminApi.getProjectStats(params),
      adminApi.getProjectDetail(params)
    ])
    
    // Group details by project
    const detailMap = {}
    detail.data.forEach(row => {
      if (!detailMap[row.client_id]) detailMap[row.client_id] = []
      detailMap[row.client_id].push(row)
    })

    // Attach rdList to each project
    projectData.value = overview.data.map(p => {
      p.rdList = detailMap[p.client_id] || []
      return p
    })
    
    await nextTick()
    const projPieData = projectData.value.filter(p => p.total_hours > 0).map(p => ({name: p.client_name, value: p.total_hours}))
    renderPieChart(projectChartRef, projectChartInstance, 'project', projPieData)
    const projBarData = projectData.value.filter(p => p.total_hours > 0)
    renderBarChart(projectBarRef, projectBarInstance, 'project',
      projBarData.map(p => p.client_name),
      projBarData.map(p => p.total_hours)
    )
  } finally { projLoading.value = false }
}

// ====== Charts ======
function renderPieChart(domRef, instanceRef, type, dataArray) {
  if (!domRef.value || domRef.value.clientWidth === 0) return
  if (instanceRef) instanceRef.dispose()
  let inst = echarts.init(domRef.value, 'dark')
  if (type === 'sales') salesChartInstance = inst
  if (type === 'rd') rdChartInstance = inst
  if (type === 'project') projectChartInstance = inst
  inst.setOption({
    backgroundColor: 'transparent',
    tooltip: { trigger: 'item', formatter: '{b}: {c}h ({d}%)', confine: true },
    legend: { type: 'scroll', bottom: 10, textStyle: { color: '#94a3b8' } },
    series: [{
      type: 'pie', radius: ['35%', '65%'], center: ['50%', '45%'],
      avoidLabelOverlap: true,
      itemStyle: { borderRadius: 8, borderColor: '#1e293b', borderWidth: 2 },
      label: { color: '#f1f5f9', fontSize: 13 },
      emphasis: {
        label: { show: true, fontSize: 16, fontWeight: 'bold' },
        itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: 'rgba(0,0,0,0.5)' }
      },
      data: dataArray
    }]
  })
}

function renderBarChart(domRef, instanceRef, type, categories, values) {
  if (!domRef.value || domRef.value.clientWidth === 0) return
  if (instanceRef) instanceRef.dispose()
  let inst = echarts.init(domRef.value, 'dark')
  if (type === 'sales') salesBarInstance = inst
  if (type === 'rd') rdBarInstance = inst
  if (type === 'project') projectBarInstance = inst
  inst.setOption({
    backgroundColor: 'transparent',
    tooltip: { trigger: 'axis', formatter: (p) => `${p[0].name}: ${p[0].value}h`, confine: true },
    grid: { left: '3%', right: '4%', bottom: '15%', containLabel: true },
    xAxis: {
      type: 'category', data: categories,
      axisLabel: { color: '#94a3b8', interval: 0, rotate: categories.length > 5 ? 30 : 0, fontSize: 12 }
    },
    yAxis: { type: 'value', name: '工时(h)', axisLabel: { color: '#94a3b8' } },
    series: [{
      type: 'bar', barMaxWidth: 50, data: values,
      itemStyle: {
        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          { offset: 0, color: '#818cf8' }, { offset: 1, color: '#4f46e5' }
        ]),
        borderRadius: [4, 4, 0, 0]
      },
      label: { show: true, position: 'top', color: '#f1f5f9', fontSize: 12, formatter: '{c}h' },
      markLine: type === 'rd' && values.length > 0 ? {
        data: [{ type: 'average', name: '平均值' }],
        lineStyle: { type: 'dashed', color: '#f59e0b', width: 2 },
        label: { formatter: '平均: {c}h', position: 'end', color: '#f59e0b', fontWeight: 'bold' }
      } : undefined
    }]
  })
}

function handleResize() { 
  salesChartInstance?.resize()
  rdChartInstance?.resize()
  projectChartInstance?.resize()
  salesBarInstance?.resize()
  rdBarInstance?.resize()
  projectBarInstance?.resize()
}

// ====== Export ======
async function exportData(type) {
  try {
    if (type === 'all') {
      exportingAll.value = true
      let params = {}
      let start = '开始', end = '至今'
      if (allExportDateRange.value && allExportDateRange.value.length === 2) { 
        params.start_date = allExportDateRange.value[0]
        params.end_date = allExportDateRange.value[1]
        start = params.start_date
        end = params.end_date
      }
      const response = await adminApi.exportAllExcel(params)
      downloadBlob(response.data, `总报表_${start}至${end}.xlsx`)
      ElMessage.success('全导成功')
      exportingAll.value = false
      return
    }

    let params = {}
    let start = '开始', end = '至今', prefix = ''
    if (type === 'sales') {
      prefix = '销售视角'
      if (salesFilter.dateRange && salesFilter.dateRange.length === 2) {
        params.start_date = salesFilter.dateRange[0]; params.end_date = salesFilter.dateRange[1];
        start = params.start_date; end = params.end_date;
      }
    } else if (type === 'rd') {
      prefix = '研发视角'
      if (rdFilter.dateRange && rdFilter.dateRange.length === 2) {
        params.start_date = rdFilter.dateRange[0]; params.end_date = rdFilter.dateRange[1];
        start = params.start_date; end = params.end_date;
      }
    } else if (type === 'project') {
      prefix = '项目视角'
      if (projFilter.dateRange && projFilter.dateRange.length === 2) {
        params.start_date = projFilter.dateRange[0]; params.end_date = projFilter.dateRange[1];
        start = params.start_date; end = params.end_date;
      }
      if (projFilter.sales_id) params.sales_id = projFilter.sales_id;
    }
    const response = await adminApi.exportExcel(type, params)
    downloadBlob(response.data, `${prefix}_${start}至${end}.xlsx`)
    ElMessage.success('导出成功')
  } catch (e) {
    exportingAll.value = false
    ElMessage.error('导出失败')
  }
}

function downloadBlob(data, filename) {
  const url = URL.createObjectURL(new Blob([data]))
  const link = document.createElement('a')
  link.href = url
  link.download = filename
  link.click()
  URL.revokeObjectURL(url)
}

watch(activeTab, (tab) => {
  nextTick(() => {
    if (tab === 'sales') {
      const filtered = salesSummary.value.filter(s => s.total_hours > 0)
      renderPieChart(salesChartRef, salesChartInstance, 'sales', filtered.map(s => ({name: s.sales_name, value: s.total_hours})))
      renderBarChart(salesBarRef, salesBarInstance, 'sales', filtered.map(s => s.sales_name), filtered.map(s => s.total_hours))
    } else if (tab === 'rd') {
      renderPieChart(rdChartRef, rdChartInstance, 'rd', rdSummary.value)
      renderBarChart(rdBarRef, rdBarInstance, 'rd', rdSummary.value.map(r => r.name), rdSummary.value.map(r => r.value))
    } else if (tab === 'project') {
      const filtered = projectData.value.filter(p => p.total_hours > 0)
      renderPieChart(projectChartRef, projectChartInstance, 'project', filtered.map(p => ({name: p.client_name, value: p.total_hours})))
      renderBarChart(projectBarRef, projectBarInstance, 'project', filtered.map(p => p.client_name), filtered.map(p => p.total_hours))
    } else if (tab === 'matrix') {
      loadMatrixData()
    } else if (tab === 'calendar') {
      if (rdUsers.value.length && !calendarFilter.user_id) {
        calendarFilter.user_id = rdUsers.value[0].id
      }
      loadCalendarData().then(() => {
        if (calendarViewMode.value === 'individual') {
          loadIndividualCalendarData()
        }
      })
    }
  })
})

onMounted(async () => {
  window.addEventListener('resize', handleResize)
  try {
    const [s, r] = await Promise.all([adminApi.getSalesUsers(), adminApi.getRdUsers()])
    salesUsers.value = s.data
    rdUsers.value = r.data
    if (rdUsers.value.length && !calendarFilter.user_id) {
      calendarFilter.user_id = rdUsers.value[0].id
    }
  } catch (e) {}
  loadSalesData()
  loadRdData()
  loadProjectData()
  loadMatrixData()
  loadCalendarData().then(() => {
    if (calendarViewMode.value === 'individual') {
      loadIndividualCalendarData()
    }
  })
})

onBeforeUnmount(() => {
  window.removeEventListener('resize', handleResize)
  salesChartInstance?.dispose()
  rdChartInstance?.dispose()
  projectChartInstance?.dispose()
  salesBarInstance?.dispose()
  rdBarInstance?.dispose()
  projectBarInstance?.dispose()
})

// ====== Calendar (填报日历) ======
const calendarViewMode = ref('grid')
const calendarLoading = ref(false)
const todayStr = ref(new Date().toLocaleDateString('sv-SE', { timeZone: 'Asia/Shanghai' }))
const calendarFilter = reactive({
  month: new Date().toLocaleDateString('sv-SE', { timeZone: 'Asia/Shanghai' }).substring(0, 7),
  user_id: ''
})
const adminCalendarDate = ref(new Date())
const adminSelectedDate = ref(new Date().toLocaleDateString('sv-SE', { timeZone: 'Asia/Shanghai' }))

const calendarRawRecords = ref([])
const gridData = ref([])
const adminRecordsMap = ref({})
const adminCalendarKey = ref(0)

const selectedDeveloperName = computed(() => {
  const found = rdUsers.value.find(u => u.id === calendarFilter.user_id)
  return found ? found.realname : ''
})

const daysInSelectedMonth = computed(() => {
  const [year, month] = calendarFilter.month.split('-').map(Number)
  const daysCount = new Date(year, month, 0).getDate()
  return Array.from({ length: daysCount }, (_, i) => i + 1)
})

const getDayLabel = (day) => {
  const [year, month] = calendarFilter.month.split('-').map(Number)
  const d = new Date(year, month - 1, day)
  const weekdays = ['日', '一', '二', '三', '四', '五', '六']
  return weekdays[d.getDay()]
}

const getGridCellHours = (row, day) => {
  const dStr = `${calendarFilter.month}-${String(day).padStart(2, '0')}`
  const hours = row.dates[dStr]?.hours || 0
  return hours > 0 ? hours : ''
}

const holidaysMap = ref({})
const loadedHolidayYear = ref(null)

async function loadHolidays(year) {
  try {
    const res = await adminApi.getHolidays(year)
    holidaysMap.value = res.data || {}
    adminCalendarKey.value++
  } catch (e) {
    console.error('Failed to load holidays:', e)
  }
}

const getGridCellClass = (row, day) => {
  const dStr = `${calendarFilter.month}-${String(day).padStart(2, '0')}`
  const hours = row.dates[dStr]?.hours || 0
  if (hours >= 8) {
    return 'cell-filled'
  } else if (hours > 0) {
    return 'cell-partial'
  } else {
    if (dStr < todayStr.value && !isRestDay(dStr)) {
      return 'cell-unfilled'
    }
    return 'cell-neutral'
  }
}

const getGridCellTitle = (row, day) => {
  const dStr = `${calendarFilter.month}-${String(day).padStart(2, '0')}`
  const hours = row.dates[dStr]?.hours || 0
  if (hours > 0) {
    return `${row.user_name} 在 ${dStr} 已填报 ${hours}h`
  } else {
    if (dStr < todayStr.value && !isRestDay(dStr)) {
      return `${row.user_name} 在 ${dStr} 漏填报`
    }
    return `${row.user_name} 在 ${dStr} 无需填报/未到期`
  }
}

const getDayOfWeek = (dayStr) => {
  const d = new Date(dayStr + 'T00:00:00')
  return d.getDay()
}

const isWorkday = (dayStr) => {
  const mmDd = dayStr.substring(5)
  if (holidaysMap.value && holidaysMap.value[mmDd]) {
    return !holidaysMap.value[mmDd].holiday
  }
  const day = getDayOfWeek(dayStr)
  return day !== 0 && day !== 6
}

const isRestDay = (dayStr) => {
  return !isWorkday(dayStr)
}

const getAdminDayHours = (dayStr) => {
  return adminRecordsMap.value[dayStr]?.hours || 0
}

const isAdminPastUnfilled = (dayStr) => {
  if (dayStr >= todayStr.value) return false
  if (isRestDay(dayStr)) return false
  return getAdminDayHours(dayStr) === 0
}

const adminSelectedDateRecords = computed(() => {
  return adminRecordsMap.value[adminSelectedDate.value]?.list || []
})

async function loadCalendarData() {
  calendarLoading.value = true
  try {
    const [yearStr, monthStr] = calendarFilter.month.split('-')
    const year = parseInt(yearStr)
    const month = parseInt(monthStr)
    const daysCount = new Date(year, month, 0).getDate()
    const start_date = `${calendarFilter.month}-01`
    const end_date = `${calendarFilter.month}-${String(daysCount).padStart(2, '0')}`

    // Fetch holidays if year changes
    if (loadedHolidayYear.value !== year) {
      loadedHolidayYear.value = year
      await loadHolidays(year)
    }

    const res = await adminApi.getRdStats({ start_date, end_date })
    calendarRawRecords.value = res.data || []
    buildGridData()
  } catch (e) {
    ElMessage.error('获取填报日历数据失败')
  } finally {
    calendarLoading.value = false
  }
}

function buildGridData() {
  const userMap = {}
  rdUsers.value.forEach(u => {
    userMap[u.id] = {
      user_id: u.id,
      user_name: u.realname,
      dates: {},
      total_hours: 0
    }
  })
  
  calendarRawRecords.value.forEach(r => {
    const uid = r.user_id
    if (!userMap[uid]) {
      userMap[uid] = {
        user_id: uid,
        user_name: r.user_name || '未知研发',
        dates: {},
        total_hours: 0
      }
    }
    const dateStr = r.work_date
    if (!userMap[uid].dates[dateStr]) {
      userMap[uid].dates[dateStr] = { hours: 0, records: [] }
    }
    userMap[uid].dates[dateStr].hours += r.hours
    userMap[uid].dates[dateStr].records.push(r)
    userMap[uid].total_hours += r.hours
  })
  
  gridData.value = Object.values(userMap)
    .map(u => {
      u.total_hours = Math.round(u.total_hours * 10) / 10
      return u
    })
    .filter(u => u.total_hours > 0)
}

function handleCalendarFilterChange() {
  loadCalendarData().then(() => {
    if (calendarViewMode.value === 'individual') {
      loadIndividualCalendarData()
    }
  })
}

function switchToIndividual(userId) {
  calendarFilter.user_id = userId
  calendarViewMode.value = 'individual'
  loadIndividualCalendarData()
}

function loadIndividualCalendarData() {
  if (!calendarFilter.user_id) return
  const map = {}
  calendarRawRecords.value.forEach(r => {
    if (r.user_id === calendarFilter.user_id) {
      if (!map[r.work_date]) {
        map[r.work_date] = { hours: 0, list: [] }
      }
      map[r.work_date].hours += r.hours
      map[r.work_date].list.push(r)
    }
  })
  adminRecordsMap.value = map
  adminCalendarKey.value++
  
  const [cy, cm] = calendarFilter.month.split('-').map(Number)
  const currentCalDate = adminCalendarDate.value
  if (currentCalDate.getFullYear() !== cy || (currentCalDate.getMonth() + 1) !== cm) {
    adminCalendarDate.value = new Date(cy, cm - 1, 1)
  }
  
  updateAdminSelectedDate()
}

function handleAdminSelectDate(dayStr) {
  adminSelectedDate.value = dayStr
}

function updateAdminSelectedDate() {
  const today = new Date().toLocaleDateString('sv-SE', { timeZone: 'Asia/Shanghai' })
  if (today.startsWith(calendarFilter.month)) {
    adminSelectedDate.value = today
  } else {
    adminSelectedDate.value = `${calendarFilter.month}-01`
  }
}

watch(adminCalendarDate, (newDate) => {
  if (newDate && calendarViewMode.value === 'individual') {
    const year = newDate.getFullYear()
    const month = String(newDate.getMonth() + 1).padStart(2, '0')
    const yyyyMm = `${year}-${month}`
    if (calendarFilter.month !== yyyyMm) {
      calendarFilter.month = yyyyMm
      loadCalendarData().then(() => {
        loadIndividualCalendarData()
      })
    }
  }
})

watch(rdUsers, () => {
  buildGridData()
})

watch(calendarViewMode, (newMode) => {
  if (newMode === 'individual') {
    if (!calendarFilter.user_id && rdUsers.value.length) {
      calendarFilter.user_id = rdUsers.value[0].id
    }
    loadIndividualCalendarData()
  }
})

const individualStats = computed(() => {
  const [year, month] = calendarFilter.month.split('-').map(Number)
  const daysCount = new Date(year, month, 0).getDate()
  
  let fullDays = 0
  let partialDays = 0
  let unfilledDays = 0
  let totalHours = 0
  
  for (let day = 1; day <= daysCount; day++) {
    const dStr = `${calendarFilter.month}-${String(day).padStart(2, '0')}`
    const hours = getAdminDayHours(dStr)
    totalHours += hours
    
    if (hours >= 8) {
      fullDays++
    } else if (hours > 0) {
      partialDays++
    } else {
      if (dStr < todayStr.value && !isRestDay(dStr)) {
        unfilledDays++
      }
    }
  }
  
  return {
    fullDays,
    partialDays,
    unfilledDays,
    totalHours: Math.round(totalHours * 10) / 10
  }
})

// ====== Matrix (研发工时汇总) ======
const matrixFilter = reactive({ dateRange: defaultRange })
const matrixLoading = ref(false)
const matrixCols = ref([])   // 项目-子项目 labels
const matrixRows = ref([])   // { label, cells:{colName:hours}, total }

async function loadMatrixData() {
  matrixLoading.value = true
  try {
    const params = {}
    if (matrixFilter.dateRange && matrixFilter.dateRange.length === 2) {
      params.start_date = matrixFilter.dateRange[0]
      params.end_date = matrixFilter.dateRange[1]
    }
    const res = await adminApi.getSummaryMatrix(params)
    const raw = res.data
    // Build cols = unique 项目-子项目 labels
    const colSet = new Set(raw.map(r => r.sub_project ? `${r.client_name}-${r.sub_project}` : r.client_name))
    matrixCols.value = [...colSet].sort()
    // Build row keys = 研发人员
    const rowKeyMap = {}
    raw.forEach(r => {
      const ck = r.sub_project ? `${r.client_name}-${r.sub_project}` : r.client_name
      if (!rowKeyMap[r.user_name]) rowKeyMap[r.user_name] = {}
      rowKeyMap[r.user_name][ck] = (rowKeyMap[r.user_name][ck] || 0) + r.hours
    })
    const dataRows = Object.entries(rowKeyMap).map(([label, cells]) => {
      const total = Object.values(cells).reduce((s, v) => s + v, 0)
      return { label, cells, total: Math.round(total * 10) / 10 }
    })
    // Totals row
    const totalCells = {}
    matrixCols.value.forEach(c => {
      totalCells[c] = Math.round(dataRows.reduce((s, r) => s + (r.cells[c] || 0), 0) * 10) / 10
    })
    const grandTotal = Math.round(dataRows.reduce((s, r) => s + r.total, 0) * 10) / 10
    dataRows.push({ label: '合计', cells: totalCells, total: grandTotal })
    matrixRows.value = dataRows
  } finally { matrixLoading.value = false }
}

async function exportMatrix() {
  const params = {}
  let start = '开始', end = '至今'
  if (matrixFilter.dateRange && matrixFilter.dateRange.length === 2) {
    params.start_date = matrixFilter.dateRange[0]
    params.end_date = matrixFilter.dateRange[1]
    start = params.start_date; end = params.end_date
  }
  const response = await adminApi.exportMatrixExcel(params)
  downloadBlob(response.data, `研发工时汇总_${start}至${end}.xlsx`)
  ElMessage.success('导出成功')
}
</script>

<style scoped>
/* Tabs Overrides */
.dashboard-page :deep(.el-tabs--border-card) {
  background: var(--bg-card) !important;
  border-color: var(--border-color) !important;
  border-radius: var(--radius) !important;
  overflow: visible !important;
}
.dashboard-page :deep(.el-tabs__content) {
  overflow: visible !important;
  padding: 20px !important;
}
.dashboard-page :deep(.el-tab-pane) {
  overflow: visible !important;
}
.dashboard-page :deep(.el-tabs__header) {
  background: rgba(51, 65, 85, 0.3) !important;
  border-bottom-color: var(--border-color) !important;
}
.dashboard-page :deep(.el-tabs__item) { color: var(--text-secondary) !important; }
.dashboard-page :deep(.el-tabs__item.is-active) {
  color: var(--primary-light) !important;
  background: var(--bg-card) !important;
}
.dashboard-page :deep(.el-tabs__item:hover) { color: var(--text-primary) !important; }

/* Table Overrides for Expandable Rows */
.dashboard-page :deep(.el-table__expanded-cell) {
  background-color: rgba(0,0,0,0.1) !important;
  padding: 0 !important;
}
.dashboard-page :deep(.el-table__expanded-cell:hover) {
  background-color: rgba(0,0,0,0.1) !important;
}

.section-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--text-primary);
  margin-bottom: 14px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--border-color);
}

.two-col-layout {
  display: flex;
  gap: 24px;
  align-items: flex-start;
  margin-top: 16px;
}
.table-col {
  flex: 2;
  min-width: 0;
}
.chart-col {
  flex: 1;
  min-width: 350px;
}

.chart-card {
  background: rgba(30, 41, 59, 0.5);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
  padding: 20px;
}
.chart-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--text-primary);
  margin-bottom: 16px;
  text-align: center;
}
.big-chart {
  width: 100%;
  height: 400px;
}

/* Matrix Table */
.matrix-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.matrix-table th, .matrix-table td {
  border: 1px solid var(--border-color);
  padding: 8px 12px;
  text-align: center;
  white-space: nowrap;
}
.matrix-table thead th {
  background: rgba(99, 102, 241, 0.15);
  color: var(--primary-light);
  font-weight: 600;
}
.matrix-table .row-header {
  text-align: left;
  font-weight: 500;
  background: rgba(255,255,255,0.03);
  min-width: 160px;
}
.matrix-table .total-col {
  font-weight: 700;
  color: #818cf8;
  background: rgba(99,102,241,0.08);
}
.matrix-table .total-row td {
  font-weight: 700;
  background: rgba(99,102,241,0.12);
  color: #c7d2fe;
}
.matrix-table tbody tr:hover td {
  background: rgba(255,255,255,0.04);
}

/* Calendar tab custom styles */
.calendar-legends {
  display: flex;
  gap: 12px;
  font-size: 12px;
}

.legend-item {
  display: flex;
  align-items: center;
  gap: 4px;
  color: var(--text-secondary);
}

.legend-item .dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
}

.legend-item .dot.green { background: var(--success); }
.legend-item .dot.yellow { background: var(--warning); }
.legend-item .dot.red { background: var(--danger); }
.legend-item .dot.gray { background: var(--text-muted); }

/* All staff grid table */
.grid-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
}

.grid-table th, .grid-table td {
  border: 1px solid var(--border-color);
  padding: 6px 4px;
  text-align: center;
  vertical-align: middle;
}

.grid-table thead th {
  background: rgba(51, 65, 85, 0.5);
  color: var(--text-secondary);
  font-weight: 600;
  padding: 8px 4px;
}

.grid-table .name-header {
  text-align: left;
  font-weight: 600;
  color: var(--text-primary);
  min-width: 100px;
  padding-left: 12px;
  background: var(--bg-card);
  position: sticky;
  left: 0;
  z-index: 5;
  border-right: 2px solid var(--border-color);
}

.grid-table .name-header.clickable {
  cursor: pointer;
  transition: var(--transition);
}

.grid-table .name-header.clickable:hover {
  background: var(--bg-hover);
  color: var(--primary-light);
}

.arrow-tip {
  font-size: 10px;
  opacity: 0;
  transition: var(--transition);
  margin-left: 4px;
}

.grid-table tr:hover .arrow-tip {
  opacity: 0.8;
}

.day-col {
  min-width: 32px;
  font-size: 11px;
}

.day-weekday {
  display: block;
  font-size: 9px;
  color: var(--text-muted);
  font-weight: normal;
  margin-top: 2px;
}

.status-cell {
  position: relative;
  transition: var(--transition);
}

.cell-hours {
  font-weight: 600;
  font-size: 11px;
}

.status-cell.cell-filled {
  background-color: rgba(16, 185, 129, 0.2) !important;
  color: #34d399;
}

.status-cell.cell-partial {
  background-color: rgba(245, 158, 11, 0.2) !important;
  color: #fbbf24;
}

.status-cell.cell-unfilled {
  background-color: rgba(239, 68, 68, 0.2) !important;
  color: #f87171;
}

.status-cell.cell-neutral {
  background-color: transparent;
  color: var(--text-muted);
}

.total-header, .total-cell {
  font-weight: 700;
  min-width: 70px;
  background: rgba(99, 102, 241, 0.05);
}

.total-cell {
  color: var(--primary-light);
}

/* Individual Calendar UI overrides */
:deep(.el-calendar) {
  --el-calendar-border-color: var(--border-color);
  background-color: var(--bg-card);
  border: 1px solid var(--border-color);
  border-radius: var(--radius);
}

:deep(.el-calendar__header) {
  border-bottom: 1px solid var(--border-color);
  padding: 12px 16px;
}

:deep(.el-calendar-table td) {
  border-bottom: 1px solid var(--border-color);
  border-right: 1px solid var(--border-color);
  background-color: transparent !important;
}

:deep(.el-calendar-table .el-calendar-day) {
  height: 60px;
  padding: 4px;
  transition: var(--transition);
}

:deep(.el-calendar-table .el-calendar-day:hover) {
  background-color: var(--bg-hover) !important;
}

:deep(.el-calendar-table td.is-selected) {
  background-color: rgba(99, 102, 241, 0.15) !important;
}

.day-cell-content {
  display: flex;
  flex-direction: column;
  height: 100%;
  justify-content: space-between;
}

.day-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.day-num {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-primary);
}

.weekend-tag {
  font-size: 9px;
  color: var(--text-muted);
  background: rgba(255, 255, 255, 0.05);
  padding: 0 3px;
  border-radius: 2px;
}

.day-body {
  margin-top: 2px;
  display: flex;
  justify-content: center;
}

.status-badge {
  font-size: 9px;
  padding: 0px 4px;
  border-radius: 3px;
  font-weight: 500;
  text-align: center;
  width: 90%;
}

.status-badge.filled {
  background: rgba(16, 185, 129, 0.15);
  color: #34d399;
  border: 1px solid rgba(16, 185, 129, 0.2);
}

.status-badge.partial {
  background: rgba(245, 158, 11, 0.15);
  color: #fbbf24;
  border: 1px solid rgba(245, 158, 11, 0.2);
}

.status-badge.unfilled {
  background: rgba(239, 68, 68, 0.15);
  color: #f87171;
  border: 1px solid rgba(239, 68, 68, 0.2);
}

/* Stats mini grid for Admin calendar */
.mini-stats-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
}

.mini-stat-item {
  background: rgba(30, 41, 59, 0.4);
  border: 1px solid var(--border-color);
  padding: 12px;
  border-radius: var(--radius-sm);
  display: flex;
  flex-direction: column;
  gap: 4px;
  transition: var(--transition);
}

.mini-stat-item:hover {
  transform: translateY(-1px);
}

.green-glow:hover { border-color: rgba(16, 185, 129, 0.4); }
.yellow-glow:hover { border-color: rgba(245, 158, 11, 0.4); }
.red-glow:hover { border-color: rgba(239, 68, 68, 0.4); }
.purple-glow:hover { border-color: rgba(99, 102, 241, 0.4); }

.mini-stat-item .label {
  font-size: 11px;
  color: var(--text-muted);
}

.mini-stat-item .value {
  font-size: 18px;
  font-weight: 700;
}

.mini-stat-item .unit {
  font-size: 10px;
  color: var(--text-secondary);
}

.green-text { color: #10b981; }
.yellow-text { color: #f59e0b; }
.red-text { color: #ef4444; }
.purple-text { color: #818cf8; }
</style>
