<template>
  <div v-loading="dashboardLoading" class="dashboard-container ec-command-dashboard">
    <!-- 关键指标 -->
    <div class="dashboard-kpi">
      <el-row :gutter="16" type="flex" style="flex-wrap:wrap">
        <el-col
          v-for="(s, i) in stats"
          :key="i"
          :xs="24" :sm="12" :md="8" :lg="6" :xl="4"
          class="kpi-col"
        >
          <stat-card
            :title="s.title"
            :value="s.value"
            :suffix="s.suffix"
            :icon="s.icon"
            :color="s.color"
            :desc="s.desc"
            :duration="1500"
          />
        </el-col>
      </el-row>
    </div>

    <!-- 2×2：折线 / 柱 / 柱(类型) / 环(状态) -->
    <div class="dashboard-charts">
      <el-row :gutter="20" class="chart-row">
        <el-col :xs="24" :lg="12">
          <el-card class="chart-card" shadow="hover">
            <div slot="header" class="card-header">事件趋势（按级别）</div>
            <p class="chart-sub">近 7 天各等级事件走势，面积与折线辅助对比</p>
            <div class="chart-pad">
              <event-trend-chart :chart-data="eventTrendData" height="280px" />
            </div>
          </el-card>
        </el-col>
        <el-col :xs="24" :lg="12">
          <el-card class="chart-card" shadow="hover">
            <div slot="header" class="card-header">近 7 天事件量</div>
            <p class="chart-sub">合并未分级总量，用于观察节奏与波峰</p>
            <div class="chart-pad">
              <event-bar-chart :chart-data="eventBarData" height="280px" />
            </div>
          </el-card>
        </el-col>
      </el-row>
      <el-row :gutter="20" class="chart-row">
        <el-col :xs="24" :lg="12">
          <el-card class="chart-card" shadow="hover">
            <div slot="header" class="card-header">事件类型分布</div>
            <p class="chart-sub">各类型件数（柱状对比）</p>
            <div class="chart-pad">
              <event-type-chart :chart-data="eventTypeData" height="240px" />
            </div>
          </el-card>
        </el-col>
        <el-col :xs="24" :lg="12">
          <el-card class="chart-card" shadow="hover">
            <div slot="header" class="card-header">事件状态分布</div>
            <p class="chart-sub">待处理 / 处理中 / 完成占比</p>
            <div class="chart-pad">
              <event-status-chart :chart-data="eventStatusData" height="260px" />
            </div>
          </el-card>
        </el-col>
      </el-row>
    </div>

    <div class="dashboard-row-2a">
      <el-row :gutter="20">
        <el-col :xs="24" :md="8">
          <el-card class="scroll-card narrow-card" shadow="hover">
            <div slot="header" class="card-header">最新事件</div>
            <real-time-activity
              :latest-events="latestEvents"
              :active-dispatches="[]"
              :todos="[]"
              :show-events="true"
              :show-dispatches="false"
              :show-todos="false"
              :suppress-section-header="true"
              @event-click="handleEventClick"
            />
          </el-card>
        </el-col>
        <el-col :xs="24" :md="8">
          <el-card class="scroll-card narrow-card" shadow="hover">
            <div slot="header" class="card-header">调度任务</div>
            <real-time-activity
              :latest-events="[]"
              :active-dispatches="activeDispatches"
              :todos="[]"
              :show-events="false"
              :show-dispatches="true"
              :show-todos="false"
              :suppress-section-header="true"
              @dispatch-click="handleDispatchClick"
            />
          </el-card>
        </el-col>
        <el-col :xs="24" :md="8">
          <el-card class="scroll-card narrow-card" shadow="hover">
            <div slot="header" class="card-header">待办提醒</div>
            <real-time-activity
              :latest-events="[]"
              :active-dispatches="[]"
              :todos="todos"
              :show-events="false"
              :show-dispatches="false"
              :show-todos="true"
              :suppress-section-header="true"
              @todo-click="handleTodoClick"
            />
          </el-card>
        </el-col>
      </el-row>
    </div>

    <div class="dashboard-row-2">
      <el-card class="module-card" shadow="hover">
        <div slot="header" class="card-header">业务模块快速入口</div>
        <el-row :gutter="20">
          <el-col
            v-for="(module, index) in modules"
            :key="index"
            :xs="12" :sm="8" :md="6" :lg="4"
          >
            <div class="module-item">
              <div class="module-icon">
                <i :class="module.icon" />
              </div>
              <div class="module-name">{{ module.name }}</div>
              <div class="module-desc">{{ module.desc }}</div>
              <div class="module-actions">
                <el-button size="mini" type="primary" plain>查看</el-button>
              </div>
            </div>
          </el-col>
        </el-row>
      </el-card>
    </div>

    <div class="dashboard-row-3">
      <el-row :gutter="20">
        <el-col :xs="24" :lg="12">
          <el-card class="scroll-card" shadow="hover">
            <div slot="header" class="card-header">资源状态总览</div>
            <resource-overview :type-data="resourceTypeData" :status-data="resourceStatusData" />
          </el-card>
        </el-col>
        <el-col :xs="24" :lg="12">
          <el-card class="scroll-card" shadow="hover">
            <div slot="header" class="card-header">值守与预警</div>
            <duty-warning-panel :weekly-data="dutyWeeklyData" :warnings="warningList" />
          </el-card>
        </el-col>
      </el-row>
    </div>

    <div class="dashboard-footer">
      <el-row :gutter="20">
        <el-col :xs="24" :md="8">
          <el-card class="info-card" shadow="hover">
            <div slot="header" class="card-header">系统公告/通知</div>
            <div class="announce-wrapper">
              <div class="announce-meta">
                <el-tag type="danger" size="mini">待读 {{ unreadCount }}</el-tag>
              </div>
              <div class="announce-list">
                <div v-for="(a, i) in announcements" :key="i" class="announce-item">
                  <div class="announce-title" :title="a.title">{{ a.title }}</div>
                  <div class="announce-time">{{ a.time }}</div>
                </div>
                <div v-if="!announcements.length" class="empty-state">
                  <i class="el-icon-info" /> 暂无公告
                </div>
              </div>
            </div>
          </el-card>
        </el-col>
        <el-col :xs="24" :md="8">
          <el-card class="info-card" shadow="hover">
            <div slot="header" class="card-header">操作日志/活动流</div>
            <div class="timeline-wrapper">
              <el-timeline>
                <el-timeline-item
                  v-for="(log, i) in activityLogs"
                  :key="i"
                  :timestamp="log.time"
                  :type="log.type"
                  :color="log.color"
                >
                  <div class="log-title">{{ log.title }}</div>
                  <div class="log-meta">{{ log.user }} · {{ log.module }}</div>
                </el-timeline-item>
              </el-timeline>
              <div v-if="!activityLogs.length" class="empty-state">
                <i class="el-icon-info" /> 暂无活动
              </div>
            </div>
          </el-card>
        </el-col>
        <el-col :xs="24" :md="8">
          <el-card class="info-card" shadow="hover">
            <div slot="header" class="card-header">快捷工具</div>
            <div class="quick-wrapper">
              <el-row :gutter="10">
                <el-col v-for="(tool, i) in quickTools" :key="i" :span="12">
                  <el-button
                    class="quick-btn"
                    type="primary"
                    plain
                    @click="go(tool.path)"
                  >
                    <i :class="tool.icon" />
                    <span>{{ tool.name }}</span>
                  </el-button>
                </el-col>
              </el-row>
              <div class="help-links">
                <el-link type="info" :underline="false">操作手册</el-link>
                <el-divider direction="vertical" />
                <el-link type="info" :underline="false">视频教程</el-link>
                <el-divider direction="vertical" />
                <el-link type="info" :underline="false">常见问题</el-link>
              </div>
            </div>
          </el-card>
        </el-col>
      </el-row>
    </div>
  </div>
</template>

<script>
import { listEvents } from '@/api/emergency/event'
import { listDispatchTasks } from '@/api/emergency/dispatchTask'
import { listNotice } from '@/api/system/notice'
import { formatDateTime, getTodayDateRange } from '@/views/duty/alert/utils/dateHelpers'
import { parseTime } from '@/utils/shuyu-utils'
import * as M from './dashboard/mockOpsData'
import StatCard from './dashboard/components/StatCard'
import EventTrendChart from './dashboard/components/EventTrendChart'
import EventBarChart from './dashboard/components/EventBarChart'
import EventTypeChart from './dashboard/components/EventTypeChart'
import EventStatusChart from './dashboard/components/EventStatusChart'
import RealTimeActivity from './dashboard/components/RealTimeActivity'
import ResourceOverview from './dashboard/components/ResourceOverview'
import DutyWarningPanel from './dashboard/components/DutyWarningPanel'

const emptyKpi = () => M.getMockKpi().map(s => ({ ...s, value: 0 }))

function normalizeEventLevel(lev) {
  if (lev == null) return 'IV'
  const s = String(lev)
  if (/^[IVX]+$/i.test(s) || s.length <= 4) return s.toUpperCase()
  const map = { 1: 'I', 2: 'II', 3: 'III', 4: 'IV' }
  return map[Number(lev)] || 'IV'
}

function mapEventRow(e) {
  return {
    eventNo: e.eventNo || e.eventCode || e.id,
    title: e.title || '—',
    type: e.eventType || e.typeName || e.type || '—',
    level: normalizeEventLevel(e.level),
    time: e.occurredAt
      ? parseTime(e.occurredAt, '{h}:{i}')
      : (e.createTime ? parseTime(e.createTime, '{h}:{i}') : '—')
  }
}

function mapTaskRow(t) {
  return {
    id: t.id,
    title: t.name || t.taskNo || '调度任务',
    eventNo: t.eventNo || t.relatedEventNo || '—',
    assignee: t.assignedToName || t.assignedTo || t.executingUnitName || t.leadUnitName || '—',
    progress: t.progress != null && t.progress >= 0 ? Math.min(100, Number(t.progress)) : 0
  }
}

export default {
  name: 'Dashboard',
  components: {
    StatCard,
    EventTrendChart,
    EventBarChart,
    EventTypeChart,
    EventStatusChart,
    RealTimeActivity,
    ResourceOverview,
    DutyWarningPanel
  },
  data() {
    const m = M.getMockActivityLists()
    return {
      dashboardLoading: false,
      stats: emptyKpi(),
      modules: [
        { name: '事件管理', desc: '事件全生命周期管理', icon: 'el-icon-warning' },
        { name: '调度管理', desc: '应急资源调度协调', icon: 'el-icon-coordinate' },
        { name: '预案管理', desc: '应急预案编制与执行', icon: 'el-icon-document' },
        { name: '资源管理', desc: '应急资源统一管理', icon: 'el-icon-box' },
        { name: '值守管理', desc: '7×24小时应急值守', icon: 'el-icon-user-solid' },
        { name: '知识库', desc: '知识文档智能调取', icon: 'el-icon-notebook-2' },
        { name: '案例库', desc: '案例自动归档与查询', icon: 'el-icon-folder' },
        { name: '预测分析', desc: '路网与客流预测', icon: 'el-icon-data-analysis' }
      ],
      eventTrendData: M.getMockEventTrend(),
      eventBarData: M.getMockEventBar(),
      eventTypeData: M.getMockEventType(),
      eventStatusData: M.getMockEventStatus(),
      latestEvents: [],
      activeDispatches: [],
      todos: m.todos,
      resourceTypeData: m.resourceTypeData,
      resourceStatusData: m.resourceStatusData,
      dutyWeeklyData: m.dutyWeeklyData,
      warningList: m.warningList,
      unreadCount: m.unreadCount,
      announcements: m.announcements,
      activityLogs: [
        { title: '发布预案《冰雪灾害专项》', user: '王强', module: '预案管理', time: '10:05', type: 'primary', color: '' },
        { title: '调度任务分配', user: '李丽', module: '调度管理', time: '09:50', type: 'success', color: '' },
        { title: '创建新事件', user: '张三', module: '事件管理', time: '09:30', type: 'warning', color: '' }
      ],
      quickTools: [
        { name: '创建事件', icon: 'el-icon-plus', path: '/event/create' },
        { name: '创建调度', icon: 'el-icon-coordinate', path: '/dispatch/create' },
        { name: '预案列表', icon: 'el-icon-document', path: '/plan' },
        { name: '资源总览', icon: 'el-icon-box', path: '/resource' },
        { name: '值守排班', icon: 'el-icon-user', path: '/duty' },
        { name: '知识库', icon: 'el-icon-notebook-2', path: '/knowledge' }
      ]
    }
  },
  mounted() {
    this.loadDashboard()
  },
  methods: {
    go(path) {
      this.$router.push({ path })
    },
    applyMockListsOnly() {
      const m = M.getMockActivityLists()
      this.resourceTypeData = m.resourceTypeData
      this.resourceStatusData = m.resourceStatusData
      this.dutyWeeklyData = m.dutyWeeklyData
      this.warningList = m.warningList
      this.announcements = m.announcements
      this.unreadCount = m.unreadCount
      this.todos = m.todos
      this.latestEvents = m.latestEvents
      this.activeDispatches = m.activeDispatches
      this._mockListsApplied = true
    },
    applyKpiIfZero() {
      if (!M.isZeroMockDisabled() && M.isKpiAllZero(this.stats)) {
        this.stats = M.getMockKpi()
      }
    },
    async loadDashboard() {
      this.dashboardLoading = true
      this.eventTrendData = M.getMockEventTrend()
      this.eventBarData = M.getMockEventBar()
      this.eventTypeData = M.getMockEventType()
      this.eventStatusData = M.getMockEventStatus()
      if (M.isForceMock()) {
        this.stats = M.getMockKpi()
        this.applyMockListsOnly()
        this.dashboardLoading = false
        return
      }
      try {
        const { startOfDay, endOfDay } = getTodayDateRange()
        const t0 = formatDateTime(startOfDay)
        const t1 = formatDateTime(endOfDay)
        const eventTodayParams = { pageNum: 1, pageSize: 500, beginOccurredAt: t0, endOccurredAt: t1 }
        const eventLatestParams = { pageNum: 1, pageSize: 8, order: 'desc' }
        const runningParams = { pageNum: 1, pageSize: 20, status: 'in_progress' }
        const [resToday, resList, resDisp, resNotice] = await Promise.all([
          listEvents(eventTodayParams).catch(() => null),
          listEvents(eventLatestParams).catch(() => null),
          listDispatchTasks(runningParams).catch(() => null),
          listNotice({ pageNum: 1, pageSize: 8, status: '0' }).catch(() => null)
        ])
        const base = emptyKpi()
        if (resToday && resToday.code === 200) {
          const n = Array.isArray(resToday.rows) ? resToday.rows.length : 0
          const tot = typeof resToday.total === 'number' ? resToday.total : n
          base[0].value = tot
        }
        if (resList && resList.code === 200 && Array.isArray(resList.rows)) {
          this.latestEvents = resList.rows.map(mapEventRow)
        }
        if (resDisp && resDisp.code === 200 && Array.isArray(resDisp.rows)) {
          this.activeDispatches = resDisp.rows.map(mapTaskRow)
          const totalRunning = typeof resDisp.total === 'number' ? resDisp.total : resDisp.rows.length
          base[3].value = totalRunning
        }
        if (resToday && resToday.code === 200 && Array.isArray(resToday.rows)) {
          const rows = resToday.rows
          const done = rows.filter(
            (r) =>
              (r.status || r.eventStatus) === 'completed' || (r.status || r.eventStatus) === 'closed' || (r.status || r.eventStatus) === '已完结'
          ).length
          const run = rows.filter(
            (r) =>
              (r.status || r.eventStatus) === 'processing' || (r.status || r.eventStatus) === 'in_progress' || (r.status || r.eventStatus) === '处理中'
          ).length
          base[1].value = run
          base[2].value = done
        }
        if (resNotice && resNotice.code === 200 && Array.isArray(resNotice.rows) && resNotice.rows.length) {
          this.announcements = resNotice.rows.map((n) => ({
            title: n.noticeTitle || n.title,
            time: n.createTime ? parseTime(n.createTime, '{y}-{m}-{d}') : '—'
          }))
          this.unreadCount = Math.min(this.announcements.length, 5)
        }
        this.stats = base
        this.applyKpiIfZero()
        const m = M.getMockActivityLists()
        if (!this.latestEvents || !this.latestEvents.length) {
          this.latestEvents = m.latestEvents
        }
        if (!this.activeDispatches || !this.activeDispatches.length) {
          this.activeDispatches = m.activeDispatches
        }
      } catch (e) {
        this.stats = M.getMockKpi()
        this.applyMockListsOnly()
        if (this.$message) {
          this.$message.warning('看板使用演示数据：接口暂不可用。')
        }
      }
      this.dashboardLoading = false
    },
    handleEventClick(event) {
      this.$router.push({ path: '/event/detail', query: { id: event.eventNo } })
    },
    handleDispatchClick(task) {
      this.$router.push({ path: '/dispatch/detail', query: { id: task.id } })
    },
    handleTodoClick(todo) {
      const routeMap = {
        approval: '/plan/approval',
        warning: '/resource/inventory',
        alert: '/resource/status',
        system: '/system/alerts'
      }
      this.$router.push({ path: routeMap[todo.type] || '/dashboard' })
    }
  }
}
</script>

<style lang="scss" scoped>
.ec-command-dashboard {
  padding: 20px 20px 28px;
  background: linear-gradient(180deg, #f1f5f9 0%, #e2e8f0 100%);
  min-height: 100%;
  box-sizing: border-box;
  font-family: 'Geist Variable', 'Geist', 'Noto Sans SC', sans-serif;
}

.kpi-col {
  margin-bottom: 16px;
}

.dashboard-charts {
  margin-bottom: 8px;
}

.chart-row {
  margin-bottom: 20px;
}

.chart-card {
  height: 100%;
  min-height: 360px;
  border-radius: 12px;
  display: flex;
  flex-direction: column;
  transition: transform 0.25s ease, box-shadow 0.25s ease;

  &:hover {
    transform: translateY(-2px);
  }

  ::v-deep .el-card__body {
    flex: 1;
    display: flex;
    flex-direction: column;
  }
}

.chart-sub {
  margin: 0 0 8px 0;
  font-size: 12px;
  color: #64748b;
  line-height: 1.4;
}

.chart-pad {
  flex: 1;
  min-height: 240px;
}

.narrow-card.scroll-card {
  min-height: 400px;
  max-height: 56vh;
}

.card-header {
  font-size: 16px;
  font-weight: 600;
  color: #0f172a;
  letter-spacing: 0.02em;
}

.dashboard-row-2a {
  margin-bottom: 20px;
  .el-col {
    margin-bottom: 16px;
  }
  .scroll-card {
    height: 420px;
    border-radius: 12px;
    display: flex;
    flex-direction: column;
    ::v-deep .el-card__body {
      flex: 1;
      overflow: hidden;
      display: flex;
      flex-direction: column;
    }
  }
}

.dashboard-row-2 {
  margin-bottom: 20px;
  .module-card {
    border-radius: 12px;
  }
  .module-item {
    text-align: center;
    padding: 20px 12px 16px;
    margin-bottom: 16px;
    background: #fff;
    border-radius: 12px;
    border: 1px solid #e2e8f0;
    box-shadow: 0 2px 8px rgba(15, 23, 42, 0.06);
    transition: all 0.3s;
    min-height: 180px;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    &:hover {
      box-shadow: 0 8px 24px rgba(79, 70, 229, 0.12);
      border-color: rgba(79, 70, 229, 0.25);
      transform: translateY(-3px);
    }
    .module-icon i {
      font-size: 44px;
      color: #4f46e5;
    }
    .module-name {
      font-size: 16px;
      font-weight: 600;
      color: #0f172a;
      margin: 10px 0 6px;
    }
    .module-desc {
      font-size: 12px;
      color: #64748b;
      flex: 1;
    }
  }
}

.dashboard-row-3 {
  margin-bottom: 20px;
  .el-col { margin-bottom: 16px; }
  .scroll-card {
    min-height: 500px;
    height: 520px;
    border-radius: 12px;
    display: flex;
    flex-direction: column;
    ::v-deep .el-card__body {
      flex: 1;
      overflow: hidden;
      display: flex;
      flex-direction: column;
    }
  }
}

.dashboard-footer {
  .el-col { margin-bottom: 16px; }
  .info-card {
    min-height: 400px;
    height: 400px;
    border-radius: 12px;
    display: flex;
    flex-direction: column;
    ::v-deep .el-card__body {
      flex: 1;
      overflow: hidden;
      display: flex;
      flex-direction: column;
    }
  }
  .announce-wrapper { display: flex; flex-direction: column; height: 100%; }
  .announce-list { flex: 1; overflow-y: auto; }
  .announce-item { padding: 8px 0; border-bottom: 1px dashed #ebeef5; }
  .announce-title { font-size: 14px; color: #0f172a; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .announce-time { font-size: 12px; color: #94a3b8; }
  .timeline-wrapper { flex: 1; overflow-y: auto; }
  .log-title { font-size: 14px; color: #0f172a; }
  .log-meta { font-size: 12px; color: #94a3b8; margin-top: 4px; }
  .quick-btn {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 10px;
  }
  .quick-btn i { margin-right: 6px; }
  .help-links { margin-top: auto; text-align: center; color: #94a3b8; }
}

.empty-state { text-align: center; color: #94a3b8; padding: 20px; }
</style>

<style>
@media (max-width: 992px) {
  .ec-command-dashboard .scroll-card { height: auto; min-height: 280px; max-height: none; }
  .ec-command-dashboard .dashboard-row-3 .scroll-card { height: auto; }
  .ec-command-dashboard .dashboard-footer .info-card { height: auto; min-height: 320px; }
}
</style>
