<template>
  <div class="container">
    <a-row :gutter="16" class="stats-row">
      <a-col :xs="24" :sm="12" :lg="8" :xl="4">
        <a-card class="stats-card" :bordered="false">
          <div class="stats-content">
            <div class="stats-icon stats-icon-primary"><icon-code-square /></div>
            <div class="stats-info">
              <div class="stats-title">CPU使用率</div>
              <div class="stats-value">{{ formatPercent(summary.cpuUsage) }}</div>
              <div class="stats-desc">安全设备平均</div>
            </div>
          </div>
        </a-card>
      </a-col>
      <a-col :xs="24" :sm="12" :lg="8" :xl="4">
        <a-card class="stats-card" :bordered="false">
          <div class="stats-content">
            <div class="stats-icon stats-icon-cyan"><icon-drive-file /></div>
            <div class="stats-info">
              <div class="stats-title">内存使用率</div>
              <div class="stats-value">{{ formatPercent(summary.memoryUsage) }}</div>
              <div class="stats-desc">安全设备平均</div>
            </div>
          </div>
        </a-card>
      </a-col>
      <a-col :xs="24" :sm="12" :lg="8" :xl="4">
        <a-card class="stats-card" :bordered="false">
          <div class="stats-content">
            <div class="stats-icon stats-icon-warning"><icon-storage /></div>
            <div class="stats-info">
              <div class="stats-title">虚拟内存使用率</div>
              <div class="stats-value">{{ formatPercent(summary.swapUsage) }}</div>
              <div class="stats-desc">Swap 平均</div>
            </div>
          </div>
        </a-card>
      </a-col>
      <a-col :xs="24" :sm="12" :lg="8" :xl="4">
        <a-card class="stats-card" :bordered="false">
          <div class="stats-content">
            <div class="stats-icon stats-icon-success"><icon-storage /></div>
            <div class="stats-info">
              <div class="stats-title">硬盘空间使用率</div>
              <div class="stats-value">{{ formatPercent(summary.diskUsage) }}</div>
              <div class="stats-desc">安全设备平均</div>
            </div>
          </div>
        </a-card>
      </a-col>
      <a-col :xs="24" :sm="12" :lg="8" :xl="4">
        <a-card class="stats-card" :bordered="false">
          <div class="stats-content">
            <div class="stats-icon stats-icon-primary"><icon-thunderbolt /></div>
            <div class="stats-info">
              <div class="stats-title">磁盘IO吞吐</div>
              <div class="stats-value">{{ formatThroughput(summary.diskIoThroughput) }}</div>
              <div class="stats-desc">平均值</div>
            </div>
          </div>
        </a-card>
      </a-col>
      <a-col :xs="24" :sm="12" :lg="8" :xl="4">
        <a-card class="stats-card" :bordered="false">
          <div class="stats-content">
            <div class="stats-icon stats-icon-success"><icon-check-circle-fill /></div>
            <div class="stats-info">
              <div class="stats-title">可用率</div>
              <div class="stats-value">{{ formatPercent(summary.availability) }}</div>
              <div class="stats-desc">在线 {{ summary.onlineCount }}/{{ summary.totalCount }}</div>
            </div>
          </div>
        </a-card>
      </a-col>
    </a-row>

    <a-row :gutter="16" class="chart-row">
      <a-col :xs="24" :xl="14">
        <a-card title="设备资源指标对比" :bordered="false">
          <template #extra>
            <span class="text-muted">最多展示 10 台设备</span>
          </template>
          <div class="chart-container">
            <Chart :options="metricsCompareChartOptions" height="300px" />
          </div>
        </a-card>
      </a-col>
      <a-col :xs="24" :xl="10">
        <a-card title="控制器状态分布" :bordered="false" class="controller-card">
          <div class="controller-overview">
            <div class="controller-item">
              <div class="controller-label">在线控制器</div>
              <div class="controller-value text-success">{{ summary.onlineCount }}</div>
            </div>
            <div class="controller-item">
              <div class="controller-label">离线控制器</div>
              <div class="controller-value text-danger">{{ summary.offlineCount }}</div>
            </div>
            <div class="controller-item">
              <div class="controller-label">异常控制器</div>
              <div class="controller-value text-warning">{{ summary.errorCount }}</div>
            </div>
            <div class="controller-item">
              <div class="controller-label">未知状态</div>
              <div class="controller-value text-muted-strong">{{ summary.unknownCount }}</div>
            </div>
          </div>
        </a-card>
      </a-col>
    </a-row>

    <a-card title="控制器运行状态" :bordered="false">
      <template #extra>
        <a-space>
          <a-select v-model="filterType" placeholder="全部类型" style="width: 140px">
            <a-option value="">全部类型</a-option>
            <a-option value="firewall">防火墙</a-option>
            <a-option value="ids">IDS</a-option>
            <a-option value="ips">IPS</a-option>
            <a-option value="waf">WAF</a-option>
            <a-option value="vpn">VPN</a-option>
            <a-option value="other">其他</a-option>
          </a-select>
          <a-input-search v-model="keyword" placeholder="搜索名称/标识" style="width: 200px" allow-clear />
        </a-space>
      </template>

      <a-table :data="filteredDevices" :columns="columns" :loading="loading" :pagination="{ pageSize: 10 }" row-key="id">
        <template #status="{ record }">
          <a-tag :color="getStatusColor(record.status)">{{ getStatusText(record.status) }}</a-tag>
        </template>
        <template #controllerStatus="{ record }">
          <a-tag :color="getControllerStatusColor(record.controller_status)">{{ record.controller_status_text }}</a-tag>
        </template>
        <template #lastCheckTime="{ record }">
          {{ formatTime(record.last_check_time) }}
        </template>
      </a-table>
    </a-card>
  </div>
</template>

<script lang="ts" setup>
import { computed, onMounted, ref } from 'vue'
import { Message } from '@arco-design/web-vue'
import { IconCheckCircleFill, IconCodeSquare, IconDriveFile, IconStorage, IconThunderbolt } from '@arco-design/web-vue/es/icon'
import type { TableColumnData } from '@arco-design/web-vue/es/table/interface'
import Chart from '@/components/chart/index.vue'
import { fetchSecurityMetricsLatest, fetchSecurityServiceList, type SecurityMetric, type SecurityServiceItem } from '@/api/ops/security'

type ControllerStatus = 'online' | 'offline' | 'warning' | 'unknown'

interface DeviceMetricRow extends SecurityServiceItem {
  cpu_usage: number | null
  memory_usage: number | null
  swap_usage: number | null
  disk_usage: number | null
  disk_io_throughput: number | null
  availability: number | null
  controller_status: ControllerStatus
  controller_status_text: string
}

const loading = ref(false)
const filterType = ref('')
const keyword = ref('')
const devices = ref<DeviceMetricRow[]>([])

const metricNameAliases = {
  cpu_usage: ['cpu_usage'],
  memory_usage: ['memory_used_percent', 'memory_usage', 'mem_usage', 'memory_percent', 'used_percent'],
  swap_usage: ['swap_used_percent', 'swap_usage', 'virtual_memory_usage', 'memory_virt'],
  disk_usage: ['disk_used_percent', 'disk_usage', 'disk_space_used_percent'],
  disk_io_throughput: ['disk_io_throughput', 'disk_io', 'disk_io_bps', 'disk_io_mb_s'],
  availability: ['availability', 'success_rate', 'available_percent'],
}

const columns: TableColumnData[] = [
  { title: '设备名称', dataIndex: 'name', width: 150 },
  { title: '类型', dataIndex: 'type', width: 100 },
  { title: '服务标识', dataIndex: 'service_identity', width: 180 },
  { title: '控制器状态', dataIndex: 'controller_status', slotName: 'controllerStatus', width: 120, align: 'center' },
  { title: 'CPU使用率', dataIndex: 'cpu_usage', width: 110, render: ({ record }) => formatPercent(record.cpu_usage) },
  { title: '内存使用率', dataIndex: 'memory_usage', width: 110, render: ({ record }) => formatPercent(record.memory_usage) },
  { title: '虚拟内存使用率', dataIndex: 'swap_usage', width: 130, render: ({ record }) => formatPercent(record.swap_usage) },
  { title: '硬盘空间', dataIndex: 'disk_usage', width: 110, render: ({ record }) => formatPercent(record.disk_usage) },
  {
    title: '磁盘IO吞吐',
    dataIndex: 'disk_io_throughput',
    width: 120,
    render: ({ record }) => formatThroughput(record.disk_io_throughput),
  },
  { title: '可用率', dataIndex: 'availability', width: 100, render: ({ record }) => formatPercent(record.availability) },
  { title: '状态', dataIndex: 'status', slotName: 'status', width: 90, align: 'center' },
  { title: '最近检查', dataIndex: 'last_check_time', slotName: 'lastCheckTime', width: 170 },
]

const filteredDevices = computed(() => {
  const typeFiltered = filterType.value ? devices.value.filter((d) => d.type === filterType.value) : devices.value
  const text = keyword.value.trim().toLowerCase()
  if (!text) return typeFiltered
  return typeFiltered.filter((d) => d.name.toLowerCase().includes(text) || d.service_identity.toLowerCase().includes(text))
})

const summary = computed(() => {
  const totalCount = devices.value.length
  const onlineCount = devices.value.filter((d) => d.status === 'online').length
  const offlineCount = devices.value.filter((d) => d.status === 'offline').length
  const errorCount = devices.value.filter((d) => d.status === 'error').length
  const unknownCount = totalCount - onlineCount - offlineCount - errorCount
  return {
    cpuUsage: avgMetric(devices.value.map((d) => d.cpu_usage)),
    memoryUsage: avgMetric(devices.value.map((d) => d.memory_usage)),
    swapUsage: avgMetric(devices.value.map((d) => d.swap_usage)),
    diskUsage: avgMetric(devices.value.map((d) => d.disk_usage)),
    diskIoThroughput: avgMetric(devices.value.map((d) => d.disk_io_throughput)),
    availability: avgMetric(devices.value.map((d) => d.availability)) ?? (totalCount ? (onlineCount / totalCount) * 100 : null),
    totalCount,
    onlineCount,
    offlineCount,
    errorCount,
    unknownCount,
  }
})

const metricsCompareChartOptions = computed(() => {
  const sample = filteredDevices.value.slice(0, 10)
  return {
    tooltip: { trigger: 'axis' },
    legend: { top: 4 },
    grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
    xAxis: {
      type: 'category',
      data: sample.map((item) => item.name || item.service_identity),
      axisLabel: { interval: 0, rotate: 25 },
    },
    yAxis: { type: 'value', name: '%' },
    series: [
      { name: 'CPU', type: 'bar', data: sample.map((item) => toNum(item.cpu_usage)), itemStyle: { color: '#165DFF' } },
      { name: '内存', type: 'bar', data: sample.map((item) => toNum(item.memory_usage)), itemStyle: { color: '#14C9C9' } },
      { name: '虚拟内存', type: 'bar', data: sample.map((item) => toNum(item.swap_usage)), itemStyle: { color: '#F7BA1E' } },
      { name: '硬盘空间', type: 'bar', data: sample.map((item) => toNum(item.disk_usage)), itemStyle: { color: '#00B42A' } },
      { name: '可用率', type: 'line', smooth: true, data: sample.map((item) => toNum(item.availability)), itemStyle: { color: '#722ED1' } },
    ],
  }
})

const parseMetricsMap = (metrics: SecurityMetric[]) => {
  const map = new Map<string, number>()
  for (const metric of metrics || []) {
    map.set(metric.metric_name, Number(metric.metric_value))
  }
  return map
}

const pickMetricValue = (metricsMap: Map<string, number>, key: keyof typeof metricNameAliases) => {
  const aliases = metricNameAliases[key]
  for (const alias of aliases) {
    if (metricsMap.has(alias)) return metricsMap.get(alias) ?? null
  }
  return null
}

const getControllerStatus = (item: SecurityServiceItem, availability: number | null): ControllerStatus => {
  if (item.status === 'online') return 'online'
  if (item.status === 'offline') return 'offline'
  if (item.status === 'error') return 'warning'
  if (availability !== null) return availability >= 95 ? 'online' : 'warning'
  return 'unknown'
}

const controllerStatusTextMap: Record<ControllerStatus, string> = {
  online: '正常',
  offline: '离线',
  warning: '异常',
  unknown: '未知',
}

const fetchData = async () => {
  loading.value = true
  try {
    const response = await fetchSecurityServiceList({ page: 1, size: 100 })
    if (!response || response.code !== 0 || !response.details?.data) {
      Message.error(response?.message || '获取安全设备列表失败')
      devices.value = []
      return
    }

    const baseList = response.details.data
    const metricsRespList = await Promise.all(
      baseList.map((item) =>
        fetchSecurityMetricsLatest(item.service_identity).catch(() => ({
          code: -1,
          details: { metrics: [] as SecurityMetric[] },
        }))
      )
    )

    devices.value = baseList.map((item, idx) => {
      const latest = metricsRespList[idx]
      const metricsMap = parseMetricsMap(latest?.details?.metrics || [])
      const availability = pickMetricValue(metricsMap, 'availability')
      const controllerStatus = getControllerStatus(item, availability)
      return {
        ...item,
        cpu_usage: pickMetricValue(metricsMap, 'cpu_usage'),
        memory_usage: pickMetricValue(metricsMap, 'memory_usage'),
        swap_usage: pickMetricValue(metricsMap, 'swap_usage'),
        disk_usage: pickMetricValue(metricsMap, 'disk_usage'),
        disk_io_throughput: pickMetricValue(metricsMap, 'disk_io_throughput'),
        availability,
        controller_status: controllerStatus,
        controller_status_text: controllerStatusTextMap[controllerStatus],
      }
    })
  } catch (error: any) {
    Message.error(error?.message || '加载安全设备监控数据失败')
    devices.value = []
  } finally {
    loading.value = false
  }
}

const avgMetric = (values: Array<number | null>) => {
  const nums = values.filter((v): v is number => typeof v === 'number' && Number.isFinite(v))
  if (!nums.length) return null
  return nums.reduce((acc, cur) => acc + cur, 0) / nums.length
}

const toNum = (val: number | null) => (typeof val === 'number' && Number.isFinite(val) ? Number(val.toFixed(2)) : 0)

const formatPercent = (val: number | null) => {
  if (val === null || !Number.isFinite(val)) return '-'
  return `${val.toFixed(2)}%`
}

const formatThroughput = (val: number | null) => {
  if (val === null || !Number.isFinite(val)) return '-'
  return `${val.toFixed(2)}`
}

const formatTime = (time: string) => {
  if (!time) return '-'
  if (time.startsWith('0001-01-01')) return '-'
  const date = new Date(time)
  if (Number.isNaN(date.getTime())) return '-'
  if (date.getFullYear() <= 1970) return '-'
  return date.toLocaleString('zh-CN')
}

const getStatusColor = (status: string) => {
  const colorMap: Record<string, string> = {
    online: 'green',
    offline: 'gray',
    warning: 'orange',
    error: 'red',
    unknown: 'gray',
  }
  return colorMap[status] || 'gray'
}

const getControllerStatusColor = (status: ControllerStatus) => {
  const colorMap: Record<ControllerStatus, string> = {
    online: 'green',
    offline: 'gray',
    warning: 'orange',
    unknown: 'gray',
  }
  return colorMap[status]
}

const getStatusText = (status: string) => {
  const textMap: Record<string, string> = {
    online: '在线',
    offline: '离线',
    warning: '警告',
    error: '异常',
    unknown: '未知',
  }
  return textMap[status] || '未知'
}

onMounted(() => {
  fetchData()
})
</script>

<script lang="ts">
export default {
  name: 'SecurityMonitor',
}
</script>

<style scoped lang="less">
.container {
  padding: 16px;
}

.stats-row {
  margin-bottom: 16px;
}

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

.stats-card {
  height: 100%;

  :deep(.arco-card-body) {
    padding: 16px;
  }

  .stats-content {
    display: flex;
    align-items: flex-start;
    gap: 12px;
  }

  .stats-icon {
    width: 48px;
    height: 48px;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 24px;

    &-primary {
      background-color: rgba(22, 93, 255, 0.1);
      color: rgb(var(--primary-6));
    }

    &-success {
      background-color: rgba(0, 180, 42, 0.1);
      color: rgb(var(--success-6));
    }

    &-cyan {
      background-color: rgba(20, 201, 201, 0.1);
      color: #14c9c9;
    }

    &-warning {
      background-color: rgba(247, 186, 30, 0.12);
      color: #f7ba1e;
    }
  }

  .stats-info {
    flex: 1;
  }

  .stats-title {
    font-size: 14px;
    color: var(--color-text-3);
    margin-bottom: 4px;
  }

  .stats-value {
    font-size: 24px;
    font-weight: 600;
    color: var(--color-text-1);
    line-height: 1.2;
    margin-bottom: 4px;
  }

  .stats-desc {
    font-size: 12px;
    color: var(--color-text-3);
  }
}

.chart-container {
  height: 300px;
}

.controller-overview {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  min-height: 300px;
  grid-auto-rows: 1fr;
}

.controller-item {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 16px;
  border: 1px solid var(--color-border-2);
  border-radius: 8px;
}

.controller-label {
  font-size: 13px;
  color: var(--color-text-3);
  margin-bottom: 8px;
}

.controller-value {
  font-size: 24px;
  font-weight: 600;
  line-height: 1.2;
}

.text-success {
  color: rgb(var(--success-6));
}

.text-danger {
  color: rgb(var(--danger-6));
}

.text-warning {
  color: rgb(var(--warning-6));
}

.text-muted {
  color: var(--color-text-3);
}

.text-muted-strong {
  color: var(--color-text-2);
}
</style>
