<script lang="ts" setup>
import type {
  AgentListItem,
  KnowledgeBaseListItem,
  WorkflowListItem,
  WorkflowRunListItem,
} from '#/api/ai-platform/ai-platform';
import type { AnnouncementListItem } from '#/api/core/announcement';
import type { Message } from '#/api/core/message';

import { computed, onMounted, onUnmounted, ref } from 'vue';
import { useRouter } from 'vue-router';

import {
  Activity,
  Bell,
  BookOpen,
  Bot,
  CalendarDays,
  Cpu,
  Gauge,
  HardDrive,
  KeyRound,
  Megaphone,
  Menu,
  MessageSquare,
  Monitor,
  Network,
  Play,
  Plus,
  RefreshCw,
  Settings,
  ShieldCheck,
  Users,
  Workflow,
} from '@vben/icons';

import {
  ElButton,
  ElEmpty,
  ElProgress,
  ElSkeleton,
  ElSkeletonItem,
  ElTag,
} from 'element-plus';

import {
  getAgentListApi,
  getAllWorkflowRunsApi,
  getKnowledgeBaseListApi,
  getProviderListApi,
  getWorkflowListApi,
} from '#/api/ai-platform/ai-platform';
import { getAnnouncementListApi } from '#/api/core/announcement';
import { getMessageListApi, getUnreadCountApi } from '#/api/core/message';
import {
  getServerHealthOverviewApi,
  getServerHealthRealtimeApi,
} from '#/api/core/server-health';

defineOptions({ name: 'AiAgentHome' });

interface OverviewMetric {
  accent: string;
  hint: string;
  icon: any;
  label: string;
  route: string;
  value: number | string;
}

interface QuickLink {
  desc: string;
  icon: any;
  label: string;
  route: string;
  tone: string;
}

const router = useRouter();

const loading = ref(true);
const agentList = ref<AgentListItem[]>([]);
const workflowList = ref<WorkflowListItem[]>([]);
const knowledgeList = ref<KnowledgeBaseListItem[]>([]);
const runList = ref<WorkflowRunListItem[]>([]);
const announcements = ref<AnnouncementListItem[]>([]);
const messages = ref<Message[]>([]);
const unreadTotal = ref(0);
const providerTotal = ref(0);

const serverName = ref('AI Agent Admin');
const serverIp = ref('-');
const uptimeText = ref('-');
const cpuPercent = ref(0);
const memoryPercent = ref(0);
const memoryLabel = ref('-');
const diskReadSpeed = ref(0);
const diskWriteSpeed = ref(0);
const networkUploadSpeed = ref(0);
const networkDownloadSpeed = ref(0);

const now = ref(new Date());
let clockTimer: ReturnType<typeof window.setInterval> | undefined;

const aiLinks: QuickLink[] = [
  {
    desc: '角色、提示词、工具和知识库能力集中管理',
    icon: Bot,
    label: '智能体',
    route: '/ai-platform/agent',
    tone: 'blue',
  },
  {
    desc: '节点化编排多智能体协作、LLM 调用和人工确认',
    icon: Workflow,
    label: '流程编排',
    route: '/ai-platform/workflow',
    tone: 'green',
  },
  {
    desc: '文档分段、向量检索和问答命中质量治理',
    icon: BookOpen,
    label: '知识库',
    route: '/ai-platform/knowledge-base',
    tone: 'amber',
  },
  {
    desc: '供应商、LLM、Embedding、Rerank 能力维护',
    icon: Settings,
    label: '模型配置',
    route: '/ai-platform/model',
    tone: 'violet',
  },
];

const adminLinks: QuickLink[] = [
  {
    desc: '账号、身份和后台访问入口',
    icon: Users,
    label: '用户管理',
    route: '/system/user',
    tone: 'blue',
  },
  {
    desc: '角色授权和数据范围控制',
    icon: ShieldCheck,
    label: '角色管理',
    route: '/system/role',
    tone: 'green',
  },
  {
    desc: '菜单、按钮和接口权限维护',
    icon: KeyRound,
    label: '权限管理',
    route: '/system/new-permission',
    tone: 'amber',
  },
  {
    desc: '后台菜单结构和动态路由配置',
    icon: Menu,
    label: '菜单管理',
    route: '/system/menu',
    tone: 'violet',
  },
];

const serviceLinks: QuickLink[] = [
  {
    desc: '最新通知、发布范围和阅读统计',
    icon: Megaphone,
    label: '公告管理',
    route: '/message/announcement',
    tone: 'amber',
  },
  {
    desc: '系统消息、流程提醒和未读处理',
    icon: MessageSquare,
    label: '消息中心',
    route: '/message/list',
    tone: 'blue',
  },
  {
    desc: '工作流运行、耗时和失败原因回看',
    icon: Activity,
    label: '执行历史',
    route: '/ai-platform/workflow-runs',
    tone: 'green',
  },
];

const greetingText = computed(() => {
  const hour = now.value.getHours();
  if (hour < 6) return '凌晨好';
  if (hour < 12) return '上午好';
  if (hour < 18) return '下午好';
  return '晚上好';
});

const timeText = computed(() =>
  now.value.toLocaleTimeString('zh-CN', {
    hour12: false,
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit',
  }),
);

const dateText = computed(() =>
  new Intl.DateTimeFormat('zh-CN', {
    weekday: 'long',
    year: 'numeric',
    month: 'long',
    day: 'numeric',
  }).format(now.value),
);

const publishedAgents = computed(
  () => agentList.value.filter((item) => item.status === 'published').length,
);

const publishedWorkflows = computed(
  () => workflowList.value.filter((item) => item.status === 'published').length,
);

const activeRuns = computed(
  () =>
    runList.value.filter((item) =>
      ['pending', 'running', 'waiting'].includes(item.status),
    ).length,
);

const failedRuns = computed(
  () =>
    runList.value.filter((item) => ['failed', 'stopped'].includes(item.status))
      .length,
);

const metrics = computed<OverviewMetric[]>(() => [
  {
    accent: 'blue',
    hint: `${publishedAgents.value} 个已发布`,
    icon: Bot,
    label: '智能体',
    route: '/ai-platform/agent',
    value: agentList.value.length,
  },
  {
    accent: 'green',
    hint: `${publishedWorkflows.value} 个已发布`,
    icon: Workflow,
    label: '工作流',
    route: '/ai-platform/workflow',
    value: workflowList.value.length,
  },
  {
    accent: 'amber',
    hint: `${providerTotal.value} 个模型供应商`,
    icon: BookOpen,
    label: '知识库',
    route: '/ai-platform/knowledge-base',
    value: knowledgeList.value.length,
  },
  {
    accent: 'violet',
    hint: `${activeRuns.value} 个运行中，${failedRuns.value} 个异常`,
    icon: Activity,
    label: '执行记录',
    route: '/ai-platform/workflow-runs',
    value: runList.value.length,
  },
]);

const recentRuns = computed(() => runList.value.slice(0, 5));
const recentAnnouncements = computed(() => announcements.value.slice(0, 5));
const recentMessages = computed(() => messages.value.slice(0, 5));

function go(route: string) {
  router.push(route);
}

function normalizePercent(value: number) {
  if (!Number.isFinite(value)) return 0;
  return Math.max(0, Math.min(100, Math.round(value)));
}

function formatTime(value?: string) {
  if (!value) return '-';
  return value.replace('T', ' ').slice(0, 16);
}

function formatBytes(value?: number) {
  if (!value || value < 0) return '-';
  const units = ['B', 'KB', 'MB', 'GB', 'TB'];
  let size = value;
  let index = 0;
  while (size >= 1024 && index < units.length - 1) {
    size /= 1024;
    index += 1;
  }
  return `${size.toFixed(size >= 10 || index === 0 ? 0 : 1)} ${units[index]}`;
}

function formatGb(value?: number) {
  if (!value || value < 0) return '-';
  return `${value.toFixed(value >= 10 ? 0 : 1)} GB`;
}

function formatSpeed(value?: number) {
  const formatted = formatBytes(value);
  return formatted === '-' ? '-' : `${formatted}/s`;
}

function runStatusType(status: string) {
  if (status === 'completed') return 'success';
  if (status === 'failed' || status === 'stopped') return 'danger';
  if (status === 'running' || status === 'waiting') return 'warning';
  return 'info';
}

function runStatusLabel(status: string) {
  const labels: Record<string, string> = {
    completed: '已完成',
    failed: '失败',
    pending: '等待中',
    running: '运行中',
    stopped: '已停止',
    waiting: '等待输入',
  };
  return labels[status] || status;
}

function announcementType(priority?: number) {
  if (priority === 2) return 'danger';
  if (priority === 1) return 'warning';
  return 'info';
}

async function loadHomeData() {
  loading.value = true;
  try {
    const results = await Promise.allSettled([
      getAgentListApi({ page: 1, pageSize: 8 }),
      getWorkflowListApi({ page: 1, pageSize: 8 }),
      getKnowledgeBaseListApi({ page: 1, pageSize: 8 }),
      getAllWorkflowRunsApi({ page: 1, pageSize: 8 }),
      getAnnouncementListApi({ page: 1, pageSize: 6, status: 'published' }),
      getMessageListApi({ page: 1, pageSize: 6, status: 'unread' }),
      getUnreadCountApi(),
      getProviderListApi({ page: 1, pageSize: 1 }),
      getServerHealthOverviewApi(),
      getServerHealthRealtimeApi(),
    ] as const);

    const [
      agentRes,
      workflowRes,
      knowledgeRes,
      runRes,
      announcementRes,
      messageRes,
      unreadRes,
      providerRes,
      overviewRes,
      realtimeRes,
    ] = results;

    if (agentRes.status === 'fulfilled') {
      agentList.value = agentRes.value.items || [];
    }
    if (workflowRes.status === 'fulfilled') {
      workflowList.value = workflowRes.value.items || [];
    }
    if (knowledgeRes.status === 'fulfilled') {
      knowledgeList.value = knowledgeRes.value.items || [];
    }
    if (runRes.status === 'fulfilled') {
      runList.value = runRes.value.items || [];
    }
    if (announcementRes.status === 'fulfilled') {
      announcements.value = announcementRes.value.items || [];
    }
    if (messageRes.status === 'fulfilled') {
      messages.value = messageRes.value.items || [];
    }
    if (unreadRes.status === 'fulfilled') {
      unreadTotal.value = unreadRes.value.total || 0;
    }
    if (providerRes.status === 'fulfilled') {
      providerTotal.value = providerRes.value.total || 0;
    }
    if (overviewRes.status === 'fulfilled') {
      const overview = overviewRes.value;
      serverName.value = overview.basic_info?.hostname || serverName.value;
      serverIp.value = overview.basic_info?.ip_address || '-';
      uptimeText.value = overview.boot_time?.uptime_formatted || '-';
      cpuPercent.value = overview.cpu_info?.cpu_percent || 0;
      memoryPercent.value = overview.memory_info?.virtual?.percent || 0;
      memoryLabel.value = `${formatGb(
        overview.memory_info?.virtual?.used,
      )} / ${formatGb(overview.memory_info?.virtual?.total)}`;
    }
    if (realtimeRes.status === 'fulfilled') {
      const realtime = realtimeRes.value;
      cpuPercent.value = realtime.cpu_percent || cpuPercent.value;
      memoryPercent.value = realtime.memory_percent || memoryPercent.value;
      memoryLabel.value = `${formatGb(realtime.memory_details?.used)} / ${formatGb(
        realtime.memory_details?.total,
      )}`;
      diskReadSpeed.value = realtime.disk_io?.read_speed || 0;
      diskWriteSpeed.value = realtime.disk_io?.write_speed || 0;
      networkUploadSpeed.value = realtime.network_io?.upload_speed || 0;
      networkDownloadSpeed.value = realtime.network_io?.download_speed || 0;
    }
  } finally {
    loading.value = false;
  }
}

onMounted(() => {
  clockTimer = window.setInterval(() => {
    now.value = new Date();
  }, 1000);
  loadHomeData();
});

onUnmounted(() => {
  if (clockTimer) {
    window.clearInterval(clockTimer);
  }
});
</script>

<template>
  <div class="ai-agent-home">
    <ElSkeleton v-if="loading" animated>
      <template #template>
        <div class="skeleton-grid">
          <ElSkeletonItem v-for="item in 10" :key="item" variant="rect" />
        </div>
      </template>
    </ElSkeleton>

    <template v-else>
      <section class="top-grid">
        <article class="panel-block greeting-card">
          <div class="avatar">超</div>
          <div class="greeting-copy">
            <div class="greeting-title">
              {{ greetingText }}，超级管理员，欢迎回来
            </div>
            <div class="greeting-subtitle">
              AI Agent Admin 已保留基础治理与 AI
              协作入口，在线开发模块已从运行菜单中移除。
            </div>
          </div>
          <div class="clock-card">
            <CalendarDays class="size-4" />
            <strong>{{ timeText }}</strong>
            <span>{{ dateText }}</span>
          </div>
        </article>

        <article class="panel-block operation-card">
          <div class="panel-head compact">
            <div>
              <h2>今日重点</h2>
              <p>优先处理运行异常、未读消息和模型配置。</p>
            </div>
            <ElButton
              :icon="RefreshCw"
              link
              type="primary"
              @click="loadHomeData"
            >
              刷新
            </ElButton>
          </div>
          <div class="focus-grid">
            <button type="button" @click="go('/ai-platform/workflow-runs')">
              <Activity class="size-4" />
              <span>运行中</span>
              <strong>{{ activeRuns }}</strong>
            </button>
            <button type="button" @click="go('/message/list')">
              <Bell class="size-4" />
              <span>未读消息</span>
              <strong>{{ unreadTotal }}</strong>
            </button>
            <button type="button" @click="go('/ai-platform/model')">
              <Settings class="size-4" />
              <span>模型供应商</span>
              <strong>{{ providerTotal }}</strong>
            </button>
          </div>
        </article>
      </section>

      <section class="metric-grid">
        <button
          v-for="metric in metrics"
          :key="metric.label"
          class="metric-card"
          :class="`tone-${metric.accent}`"
          type="button"
          @click="go(metric.route)"
        >
          <span class="metric-icon">
            <component :is="metric.icon" class="size-5" />
          </span>
          <span class="metric-label">{{ metric.label }}</span>
          <strong>{{ metric.value }}</strong>
          <small>{{ metric.hint }}</small>
        </button>
      </section>

      <section class="content-grid">
        <article class="panel-block span-8">
          <div class="panel-head">
            <div>
              <h2>AI 协作入口</h2>
              <p>围绕智能体、流程编排、LLM 和知识库的核心工作台。</p>
            </div>
            <ElButton
              type="primary"
              :icon="Plus"
              @click="go('/ai-platform/agent')"
            >
              新建智能体
            </ElButton>
          </div>
          <div class="app-grid">
            <button
              v-for="link in aiLinks"
              :key="link.route"
              class="app-item"
              :class="`tone-${link.tone}`"
              type="button"
              @click="go(link.route)"
            >
              <span class="app-icon">
                <component :is="link.icon" class="size-5" />
              </span>
              <span>{{ link.label }}</span>
              <small>{{ link.desc }}</small>
            </button>
          </div>
        </article>

        <article class="panel-block span-4">
          <div class="panel-head">
            <div>
              <h2>服务器信息</h2>
              <p>{{ serverName }} ({{ serverIp }})</p>
            </div>
            <Monitor class="head-icon size-5" />
          </div>
          <div class="server-list">
            <div class="server-row">
              <div class="row-label">
                <Cpu class="size-4" />
                <span>CPU</span>
              </div>
              <strong>{{ normalizePercent(cpuPercent) }}%</strong>
              <ElProgress
                :percentage="normalizePercent(cpuPercent)"
                :stroke-width="8"
              />
            </div>
            <div class="server-row">
              <div class="row-label">
                <Gauge class="size-4" />
                <span>内存</span>
              </div>
              <strong>{{ normalizePercent(memoryPercent) }}%</strong>
              <ElProgress
                :percentage="normalizePercent(memoryPercent)"
                :stroke-width="8"
                color="#16a34a"
              />
              <small>{{ memoryLabel }}</small>
            </div>
            <div class="io-grid">
              <div>
                <HardDrive class="size-4" />
                <span>磁盘读取</span>
                <strong>{{ formatSpeed(diskReadSpeed) }}</strong>
              </div>
              <div>
                <HardDrive class="size-4" />
                <span>磁盘写入</span>
                <strong>{{ formatSpeed(diskWriteSpeed) }}</strong>
              </div>
              <div>
                <Network class="size-4" />
                <span>上传</span>
                <strong>{{ formatSpeed(networkUploadSpeed) }}</strong>
              </div>
              <div>
                <Network class="size-4" />
                <span>下载</span>
                <strong>{{ formatSpeed(networkDownloadSpeed) }}</strong>
              </div>
            </div>
            <div class="uptime-row">
              <span>运行时间</span>
              <strong>{{ uptimeText }}</strong>
            </div>
          </div>
        </article>

        <article class="panel-block span-5">
          <div class="panel-head">
            <div>
              <h2>最近执行</h2>
              <p>定位失败、等待输入和最近运行的工作流。</p>
            </div>
            <ElButton
              link
              type="primary"
              @click="go('/ai-platform/workflow-runs')"
            >
              更多
            </ElButton>
          </div>
          <div v-if="recentRuns.length > 0" class="run-list">
            <button
              v-for="run in recentRuns"
              :key="run.id"
              class="line-item"
              type="button"
              @click="go('/ai-platform/workflow-runs')"
            >
              <span>{{ run.workflow_name || run.id }}</span>
              <ElTag :type="runStatusType(run.status)" size="small">
                {{ runStatusLabel(run.status) }}
              </ElTag>
              <small>{{ formatTime(run.started_at) }}</small>
            </button>
          </div>
          <ElEmpty v-else description="暂无执行记录" />
        </article>

        <article class="panel-block span-4">
          <div class="panel-head">
            <div>
              <h2>最新公告</h2>
              <p>管理端发布的系统公告。</p>
            </div>
            <ElButton link type="primary" @click="go('/message/announcement')">
              更多
            </ElButton>
          </div>
          <div v-if="recentAnnouncements.length > 0" class="compact-list">
            <button
              v-for="item in recentAnnouncements"
              :key="item.id"
              type="button"
              @click="go('/message/announcement')"
            >
              <Megaphone class="size-4" />
              <span>{{ item.title }}</span>
              <ElTag :type="announcementType(item.priority)" size="small">
                {{
                  item.priority === 2
                    ? '紧急'
                    : item.priority === 1
                      ? '重要'
                      : '普通'
                }}
              </ElTag>
            </button>
          </div>
          <ElEmpty v-else description="暂无公告" />
        </article>

        <article class="panel-block span-3">
          <div class="panel-head">
            <div>
              <h2>消息通知</h2>
              <p>{{ unreadTotal }} 条未读。</p>
            </div>
            <ElButton link type="primary" @click="go('/message/list')">
              更多
            </ElButton>
          </div>
          <div v-if="recentMessages.length > 0" class="message-list">
            <button
              v-for="item in recentMessages"
              :key="item.id"
              type="button"
              @click="go('/message/list')"
            >
              <Bell class="size-4" />
              <span>{{ item.title }}</span>
              <small>{{ formatTime(item.created_at) }}</small>
            </button>
          </div>
          <ElEmpty v-else description="暂无数据" />
        </article>

        <article class="panel-block span-12">
          <div class="panel-head">
            <div>
              <h2>快捷入口</h2>
              <p>保留 zq_ai_admin 的基础后台治理能力，删除在线开发链路。</p>
            </div>
            <Play class="head-icon size-5" />
          </div>
          <div class="quick-grid">
            <button
              v-for="link in [...adminLinks, ...serviceLinks]"
              :key="link.route"
              :class="`tone-${link.tone}`"
              type="button"
              @click="go(link.route)"
            >
              <component :is="link.icon" class="size-4" />
              <span>{{ link.label }}</span>
              <small>{{ link.desc }}</small>
            </button>
          </div>
        </article>
      </section>
    </template>
  </div>
</template>

<style scoped>
.ai-agent-home {
  min-height: calc(100vh - 116px);
  padding: 16px;
  color: var(--el-text-color-primary);
  background: var(--el-bg-color-page);
}

.top-grid,
.content-grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: 14px;
}

.top-grid {
  margin-bottom: 14px;
}

.panel-block,
.metric-card {
  background: var(--el-bg-color);
  border: 1px solid var(--el-border-color-lighter);
  border-radius: 8px;
  box-shadow: 0 4px 14px rgb(15 23 42 / 5%);
}

.greeting-card {
  grid-column: span 8;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) 220px;
  gap: 16px;
  align-items: center;
  min-height: 124px;
  padding: 18px;
}

.operation-card {
  grid-column: span 4;
  padding: 18px;
}

.avatar {
  display: flex;
  width: 54px;
  height: 54px;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  color: #f8fafc;
  font-size: 24px;
  font-weight: 700;
  background: #2563eb;
}

.greeting-title {
  font-size: 20px;
  font-weight: 700;
}

.greeting-subtitle {
  max-width: 68ch;
  margin-top: 8px;
  color: var(--el-text-color-secondary);
  font-size: 13px;
  line-height: 1.65;
}

.clock-card {
  display: grid;
  gap: 5px;
  justify-items: end;
  color: var(--el-text-color-secondary);
}

.clock-card strong {
  color: var(--el-text-color-primary);
  font-size: 26px;
  line-height: 1;
}

.clock-card span {
  font-size: 12px;
}

.panel-head {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  justify-content: space-between;
  margin-bottom: 14px;
}

.panel-head.compact {
  margin-bottom: 12px;
}

.panel-head h2 {
  margin: 0 0 5px;
  font-size: 16px;
  font-weight: 700;
}

.panel-head p {
  margin: 0;
  color: var(--el-text-color-secondary);
  font-size: 12px;
  line-height: 1.5;
}

.head-icon {
  color: var(--el-color-primary);
}

.focus-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}

.focus-grid button {
  display: grid;
  gap: 5px;
  min-width: 0;
  padding: 10px;
  text-align: left;
  background: var(--el-fill-color-extra-light);
  border: 1px solid var(--el-border-color-lighter);
  border-radius: 8px;
  cursor: pointer;
}

.focus-grid svg {
  color: var(--el-color-primary);
}

.focus-grid span {
  color: var(--el-text-color-secondary);
  font-size: 12px;
}

.focus-grid strong {
  font-size: 22px;
  line-height: 1;
}

.metric-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px;
  margin-bottom: 14px;
}

.metric-card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 5px 12px;
  align-items: center;
  padding: 15px;
  text-align: left;
  cursor: pointer;
}

.metric-icon,
.app-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgb(var(--tone-color) / 10%);
  color: rgb(var(--tone-color));
  border-radius: 8px;
}

.metric-icon {
  width: 38px;
  height: 38px;
  grid-row: span 3;
}

.metric-label,
.app-item > span:not(.app-icon),
.quick-grid span {
  font-weight: 600;
}

.metric-card strong {
  font-size: 24px;
  line-height: 1;
}

.metric-card small,
.app-item small,
.quick-grid small,
.line-item small,
.message-list small {
  overflow: hidden;
  color: var(--el-text-color-secondary);
  font-size: 12px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.span-3 {
  grid-column: span 3;
}

.span-4 {
  grid-column: span 4;
}

.span-5 {
  grid-column: span 5;
}

.span-8 {
  grid-column: span 8;
}

.span-12 {
  grid-column: span 12;
}

.content-grid .panel-block {
  min-height: 260px;
  padding: 16px;
}

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

.app-item {
  display: grid;
  gap: 8px;
  min-height: 136px;
  padding: 14px;
  text-align: left;
  background: var(--el-fill-color-extra-light);
  border: 1px solid rgb(var(--tone-color) / 18%);
  border-radius: 8px;
  cursor: pointer;
}

.app-icon {
  width: 36px;
  height: 36px;
}

.app-item small {
  line-height: 1.55;
  white-space: normal;
}

.server-list {
  display: grid;
  gap: 13px;
}

.server-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 7px 10px;
  align-items: center;
}

.row-label {
  display: flex;
  gap: 7px;
  align-items: center;
  color: var(--el-text-color-secondary);
  font-size: 13px;
}

.server-row :deep(.el-progress) {
  grid-column: 1 / -1;
}

.server-row small {
  grid-column: 1 / -1;
  color: var(--el-text-color-secondary);
}

.io-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}

.io-grid div {
  display: grid;
  gap: 4px;
  padding: 10px;
  background: var(--el-fill-color-extra-light);
  border-radius: 8px;
}

.io-grid svg {
  color: var(--el-color-primary);
}

.io-grid span,
.uptime-row span {
  color: var(--el-text-color-secondary);
  font-size: 12px;
}

.io-grid strong {
  font-size: 13px;
}

.uptime-row {
  display: flex;
  justify-content: space-between;
  padding-top: 10px;
  border-top: 1px solid var(--el-border-color-lighter);
}

.run-list,
.compact-list,
.message-list {
  display: grid;
  gap: 9px;
}

.line-item,
.compact-list button,
.message-list button {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 5px 8px;
  align-items: center;
  padding: 10px 11px;
  text-align: left;
  background: var(--el-fill-color-extra-light);
  border: 1px solid var(--el-border-color-lighter);
  border-radius: 8px;
  cursor: pointer;
}

.compact-list button,
.message-list button {
  grid-template-columns: auto minmax(0, 1fr) auto;
}

.message-list button {
  grid-template-columns: auto minmax(0, 1fr);
}

.line-item span,
.compact-list span,
.message-list span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.line-item small,
.message-list small {
  grid-column: 1 / -1;
}

.compact-list svg,
.message-list svg {
  color: var(--el-color-primary);
}

.quick-grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 10px;
}

.quick-grid button {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 4px 8px;
  align-items: center;
  min-height: 72px;
  padding: 12px;
  text-align: left;
  background: var(--el-fill-color-extra-light);
  border: 1px solid rgb(var(--tone-color) / 16%);
  border-radius: 8px;
  cursor: pointer;
}

.quick-grid svg {
  color: rgb(var(--tone-color));
}

.quick-grid small {
  grid-column: 2;
}

.tone-blue {
  --tone-color: 37 99 235;
}

.tone-green {
  --tone-color: 22 163 74;
}

.tone-amber {
  --tone-color: 217 119 6;
}

.tone-violet {
  --tone-color: 124 58 237;
}

.metric-card:hover,
.app-item:hover,
.quick-grid button:hover,
.focus-grid button:hover,
.line-item:hover,
.compact-list button:hover,
.message-list button:hover {
  border-color: var(--el-color-primary-light-5);
  box-shadow: 0 8px 20px rgb(15 23 42 / 7%);
  transform: translateY(-1px);
}

.metric-card,
.app-item,
.quick-grid button,
.focus-grid button,
.line-item,
.compact-list button,
.message-list button {
  transition:
    border-color 0.18s ease,
    box-shadow 0.18s ease,
    transform 0.18s ease;
}

.skeleton-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px;
}

.skeleton-grid :deep(.el-skeleton__item) {
  height: 130px;
  border-radius: 8px;
}

@media (max-width: 1280px) {
  .greeting-card,
  .operation-card,
  .span-3,
  .span-4,
  .span-5,
  .span-8 {
    grid-column: span 12;
  }

  .app-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .quick-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (max-width: 760px) {
  .ai-agent-home {
    padding: 12px;
  }

  .greeting-card {
    grid-template-columns: auto minmax(0, 1fr);
  }

  .clock-card {
    grid-column: 1 / -1;
    justify-items: start;
  }

  .metric-grid,
  .app-grid,
  .quick-grid,
  .focus-grid,
  .io-grid,
  .skeleton-grid {
    grid-template-columns: 1fr;
  }
}
</style>
