<template>
  <div class="connection-pool-page">
    <v-card class="hero-card" elevation="2">
      <div class="hero-content d-flex align-center">
        <div class="hero-icon d-flex align-center justify-center">
          <v-icon color="primary" size="30">mdi-database-sync-outline</v-icon>
        </div>
        <div class="hero-copy">
          <h1>外部数据源连接池</h1>
          <p>
            统一查看 PostgreSQL 与 MySQL 数据源的连接复用、占用和故障隔离状态。
            连接池按业务访问惰性创建，不包含平台自身数据库。
          </p>
        </div>
        <v-spacer />
        <div class="hero-actions d-flex align-center">
          <v-btn
            outlined
            color="primary"
            class="mr-3"
            @click="$router.push('/data-governance/data-source')"
          >
            <v-icon left>mdi-database-cog-outline</v-icon>
            数据源管理
          </v-btn>
          <v-btn
            color="primary"
            :loading="loading"
            @click="loadData"
          >
            <v-icon left>mdi-refresh</v-icon>
            立即刷新
          </v-btn>
        </div>
      </div>
    </v-card>

    <v-row class="summary-row" dense>
      <v-col
        v-for="item in summaryItems"
        :key="item.label"
        cols="12"
        sm="6"
        lg="3"
      >
        <v-card class="summary-card" elevation="2">
          <div
            class="summary-icon d-flex align-center justify-center"
            :class="item.tone"
          >
            <v-icon size="25">{{ item.icon }}</v-icon>
          </div>
          <div>
            <div class="summary-label">{{ item.label }}</div>
            <div class="summary-value">{{ item.value }}</div>
            <div class="summary-hint">{{ item.hint }}</div>
          </div>
        </v-card>
      </v-col>
    </v-row>

    <v-card class="management-card" elevation="2">
      <div class="toolbar d-flex align-center flex-wrap">
        <v-text-field
          v-model="searchText"
          class="toolbar-control"
          label="数据源名称或地址"
          prepend-inner-icon="mdi-magnify"
          outlined
          dense
          clearable
          hide-details
        />
        <v-select
          v-model="typeFilter"
          class="toolbar-control"
          :items="databaseTypes"
          label="数据库类型"
          outlined
          dense
          clearable
          hide-details
        />
        <v-select
          v-model="stateFilter"
          class="toolbar-control"
          :items="poolStates"
          label="连接池状态"
          outlined
          dense
          clearable
          hide-details
        />
        <v-spacer />
        <div class="refresh-control d-flex align-center">
          <span class="refresh-time">更新于 {{ refreshedAt || '--:--:--' }}</span>
          <v-switch
            v-model="autoRefresh"
            class="ml-4 mt-0"
            color="primary"
            label="每 15 秒自动刷新"
            hide-details
          />
        </div>
      </div>

      <v-divider />

      <v-data-table
        class="pool-table"
        :headers="headers"
        :items="filteredItems"
        :loading="loading"
        :items-per-page="10"
        :footer-props="{
          itemsPerPageText: '每页行数',
          itemsPerPageOptions: [10, 20, 50]
        }"
        item-key="uid"
        loading-text="正在读取连接池状态..."
        no-data-text="暂无符合条件的数据源"
      >
        <template v-slot:[`item.source`]="{ item }">
          <div class="source-cell">
            <div class="source-name">{{ item.name_zh || item.name_en }}</div>
            <div class="source-meta">
              {{ item.name_en }}
              <span v-if="item.database">· {{ item.database }}</span>
            </div>
            <div class="source-endpoint">{{ item.host }}:{{ item.port }}</div>
          </div>
        </template>

        <template v-slot:[`item.type`]="{ item }">
          <div class="database-type">
            <v-icon
              size="19"
              :color="item.type === 'postgresql' ? 'primary' : 'warning'"
              class="mr-2"
            >
              mdi-database-outline
            </v-icon>
            {{ databaseTypeLabel(item.type) }}
          </div>
        </template>

        <template v-slot:[`item.pool_state`]="{ item }">
          <v-chip
            small
            label
            :color="stateMeta(item.pool_state).color"
            :outlined="item.pool_state === 'lazy'"
            :dark="item.pool_state !== 'lazy'"
          >
            <v-icon left x-small>{{ stateMeta(item.pool_state).icon }}</v-icon>
            {{ stateMeta(item.pool_state).label }}
          </v-chip>
          <div
            v-if="item.pool_state === 'lazy'"
            class="state-caption"
          >
            首次业务访问时创建
          </div>
        </template>

        <template v-slot:[`item.usage`]="{ item }">
          <div v-if="item.has_pool" class="usage-cell">
            <div class="d-flex justify-space-between usage-label">
              <span>{{ item.checked_out }} 已借出</span>
              <span>{{ item.checked_in }} 空闲</span>
            </div>
            <v-progress-linear
              :value="usagePercent(item)"
              :color="usageColor(item)"
              height="6"
              rounded
            />
          </div>
          <span v-else class="muted-text">尚无运行实例</span>
        </template>

        <template v-slot:[`item.capacity`]="{ item }">
          <div class="capacity-value">
            {{ item.pool_size || item.configured_pool_size || 2 }}
            <span class="capacity-overflow">
              + {{ item.configured_max_overflow || 3 }}
            </span>
          </div>
          <div class="state-caption">基础 + 临时溢出</div>
        </template>

        <template v-slot:[`item.signals`]="{ item }">
          <template v-if="item.has_pool">
            <div>{{ formatNumber(item.checkout_wait_ms) }} ms 等待</div>
            <div class="state-caption">
              {{ item.query_total || 0 }} 次查询 · {{ item.pool_timeout_total || 0 }} 次超时
            </div>
          </template>
          <span v-else class="muted-text">暂无指标</span>
        </template>

        <template v-slot:[`item.actions`]="{ item }">
          <div class="action-cell">
            <v-btn text small color="primary" @click="openDetail(item)">
              详情
            </v-btn>
            <v-btn
              v-if="item.has_pool"
              text
              small
              color="warning"
              @click="confirmReset(item)"
            >
              安全重置
            </v-btn>
          </div>
        </template>

        <template #no-data>
          <div class="empty-state">
            <v-icon size="42" color="blue-grey lighten-2">
              mdi-database-off-outline
            </v-icon>
            <div class="empty-title">
              {{ items.length ? '暂无符合条件的数据源' : '暂无可管理的数据源' }}
            </div>
            <div class="empty-copy">
              {{
                items.length
                  ? '请调整名称、类型或状态筛选条件。'
                  : '请先在数据来源中新增 PostgreSQL 或 MySQL 数据源。'
              }}
            </div>
            <v-btn
              v-if="!items.length"
              text
              color="primary"
              @click="$router.push('/data-governance/data-source')"
            >
              前往数据源管理
            </v-btn>
          </div>
        </template>
      </v-data-table>
    </v-card>

    <v-navigation-drawer
      v-model="drawer"
      fixed
      right
      temporary
      :width="$vuetify.breakpoint.smAndDown ? '100%' : 520"
      class="pool-detail-drawer"
      style="z-index: var(--zIndex-drawers);"
    >
      <div v-if="selectedItem" class="detail-shell">
        <div class="detail-header d-flex align-center">
          <div>
            <div class="detail-eyebrow">连接池详情</div>
            <h2>{{ selectedItem.name_zh || selectedItem.name_en }}</h2>
          </div>
          <v-spacer />
          <v-btn icon aria-label="关闭详情" @click="drawer = false">
            <v-icon>mdi-close</v-icon>
          </v-btn>
        </div>

        <div class="detail-body">
          <div class="detail-status d-flex align-center">
            <div
              class="detail-status-icon d-flex align-center justify-center"
              :class="stateMeta(selectedItem.pool_state).tone"
            >
              <v-icon>{{ stateMeta(selectedItem.pool_state).icon }}</v-icon>
            </div>
            <div>
              <div class="detail-status-title">
                {{ stateMeta(selectedItem.pool_state).label }}
              </div>
              <div class="detail-status-copy">
                {{ stateMeta(selectedItem.pool_state).description }}
              </div>
            </div>
          </div>

          <section class="detail-section">
            <h3>数据源信息</h3>
            <dl class="definition-grid">
              <div>
                <dt>数据库类型</dt>
                <dd>{{ databaseTypeLabel(selectedItem.type) }}</dd>
              </div>
              <div>
                <dt>服务器地址</dt>
                <dd>{{ selectedItem.host }}:{{ selectedItem.port }}</dd>
              </div>
              <div>
                <dt>数据库 / Schema</dt>
                <dd>
                  {{ selectedItem.database || '-' }} /
                  {{ selectedItem.schema || '-' }}
                </dd>
              </div>
              <div>
                <dt>凭据版本</dt>
                <dd>
                  {{
                    selectedItem.credential_version
                      ? `v${selectedItem.credential_version}`
                      : '-'
                  }}
                </dd>
              </div>
            </dl>
          </section>

          <section class="detail-section">
            <h3>实时容量</h3>
            <div class="metric-grid">
              <div
                v-for="metric in detailMetrics"
                :key="metric.label"
                class="metric-item"
              >
                <div class="metric-value">{{ metric.value }}</div>
                <div class="metric-label">{{ metric.label }}</div>
              </div>
            </div>
          </section>

          <section class="detail-section">
            <h3>运行信号</h3>
            <v-simple-table dense>
              <tbody>
                <tr>
                  <td>累计创建连接</td>
                  <td class="text-right">
                    {{ selectedItem.connection_created_total || 0 }}
                  </td>
                </tr>
                <tr>
                  <td>连接失败</td>
                  <td class="text-right">
                    {{ selectedItem.connection_failed_total || 0 }}
                  </td>
                </tr>
                <tr>
                  <td>池等待超时</td>
                  <td class="text-right">
                    {{ selectedItem.pool_timeout_total || 0 }}
                  </td>
                </tr>
                <tr>
                  <td>连续失败</td>
                  <td class="text-right">
                    {{ selectedItem.consecutive_failures || 0 }}
                  </td>
                </tr>
                <tr>
                  <td>最近查询耗时</td>
                  <td class="text-right">
                    {{ formatNumber(selectedItem.last_query_duration_ms) }} ms
                  </td>
                </tr>
              </tbody>
            </v-simple-table>
          </section>

          <v-alert
            v-if="!selectedItem.has_pool"
            type="info"
            text
            dense
          >
            当前数据源尚未触发业务访问，因此没有创建运行连接池。这是正常的惰性创建状态。
          </v-alert>
          <v-alert
            v-else
            type="warning"
            text
            dense
          >
            安全重置会停止新连接借出，并等待正在使用的连接归还；下一次业务访问将按最新配置重新创建。
          </v-alert>

          <v-btn
            v-if="selectedItem.has_pool"
            block
            color="warning"
            dark
            :loading="resettingUid === selectedItem.uid"
            @click="confirmReset(selectedItem)"
          >
            <v-icon left>mdi-database-refresh-outline</v-icon>
            安全重置连接池
          </v-btn>
        </div>
      </div>
    </v-navigation-drawer>
  </div>
</template>

<script>
import {
  getDatasourceList,
  getDatasourcePools,
  invalidateDatasourcePool
} from '@/api/dataOrigin'

const STATE_META = {
  healthy: {
    label: '健康',
    color: 'success',
    tone: 'success-tone',
    icon: 'mdi-check-circle-outline',
    description: '连接池运行正常，可以持续复用外部数据库连接。'
  },
  degraded: {
    label: '性能下降',
    color: 'warning',
    tone: 'warning-tone',
    icon: 'mdi-alert-outline',
    description: '近期出现连接失败，请关注外部数据库网络和服务状态。'
  },
  open: {
    label: '已熔断',
    color: 'error',
    tone: 'error-tone',
    icon: 'mdi-shield-alert-outline',
    description: '连续连接失败触发了隔离保护，当前数据源暂时拒绝新请求。'
  },
  draining: {
    label: '排空中',
    color: 'info',
    tone: 'info-tone',
    icon: 'mdi-timer-sand',
    description: '连接池正在等待已借出连接归还，随后会被安全释放。'
  },
  lazy: {
    label: '未创建',
    color: 'blue-grey',
    tone: 'neutral-tone',
    icon: 'mdi-database-clock-outline',
    description: '连接池按需创建，首次业务访问后会自动进入运行状态。'
  }
}

export default {
  name: 'ConnectionPoolManagement',
  data () {
    return {
      loading: false,
      items: [],
      searchText: '',
      typeFilter: null,
      stateFilter: null,
      autoRefresh: true,
      refreshedAt: '',
      refreshTimer: null,
      drawer: false,
      selectedItem: null,
      resettingUid: null,
      databaseTypes: [
        { text: 'PostgreSQL', value: 'postgresql' },
        { text: 'MySQL', value: 'mysql' }
      ],
      poolStates: [
        { text: '健康', value: 'healthy' },
        { text: '性能下降', value: 'degraded' },
        { text: '已熔断', value: 'open' },
        { text: '排空中', value: 'draining' },
        { text: '未创建', value: 'lazy' }
      ],
      headers: [
        { text: '数据源', value: 'source', sortable: false, width: 190 },
        { text: '数据库类型', value: 'type', width: 105 },
        { text: '状态', value: 'pool_state', width: 120 },
        { text: '连接使用', value: 'usage', sortable: false, width: 140 },
        { text: '连接上限', value: 'capacity', sortable: false, width: 95 },
        { text: '运行信号', value: 'signals', sortable: false, width: 145 },
        { text: '操作', value: 'actions', sortable: false, width: 125 }
      ]
    }
  },
  computed: {
    summaryItems () {
      const activePools = this.items.filter(item => item.has_pool)
      const abnormalPools = activePools.filter(item => (
        ['degraded', 'open'].includes(item.pool_state)
      ))
      const checkedOut = activePools.reduce(
        (sum, item) => sum + Number(item.checked_out || 0),
        0
      )
      return [
        {
          label: '外部数据源',
          value: this.items.length,
          hint: 'PostgreSQL / MySQL',
          icon: 'mdi-database-outline',
          tone: 'primary-tone'
        },
        {
          label: '已创建连接池',
          value: activePools.length,
          hint: `${this.items.length - activePools.length} 个等待首次访问`,
          icon: 'mdi-connection',
          tone: 'info-tone'
        },
        {
          label: '当前借出连接',
          value: checkedOut,
          hint: '正在被业务任务使用',
          icon: 'mdi-swap-horizontal',
          tone: 'success-tone'
        },
        {
          label: '异常连接池',
          value: abnormalPools.length,
          hint: abnormalPools.length ? '需要管理员关注' : '当前运行稳定',
          icon: 'mdi-shield-check-outline',
          tone: abnormalPools.length ? 'error-tone' : 'success-tone'
        }
      ]
    },
    filteredItems () {
      const keyword = String(this.searchText || '').trim().toLowerCase()
      return this.items.filter(item => {
        const matchesKeyword = !keyword || [
          item.name_zh,
          item.name_en,
          item.host,
          item.database
        ].some(value => String(value || '').toLowerCase().includes(keyword))
        const matchesType = !this.typeFilter || item.type === this.typeFilter
        const matchesState = !this.stateFilter || (
          item.pool_state === this.stateFilter
        )
        return matchesKeyword && matchesType && matchesState
      })
    },
    detailMetrics () {
      if (!this.selectedItem) return []
      return [
        {
          label: '基础连接',
          value: this.selectedItem.pool_size ||
            this.selectedItem.configured_pool_size || 2
        },
        {
          label: '当前借出',
          value: this.selectedItem.checked_out || 0
        },
        {
          label: '当前空闲',
          value: this.selectedItem.checked_in || 0
        },
        {
          label: '借出峰值',
          value: this.selectedItem.checked_out_peak || 0
        },
        {
          label: '临时溢出',
          value: this.selectedItem.overflow || 0
        },
        {
          label: '活动租约',
          value: this.selectedItem.leases || 0
        }
      ]
    }
  },
  watch: {
    autoRefresh: {
      immediate: true,
      handler (enabled) {
        this.clearRefreshTimer()
        if (enabled) {
          this.refreshTimer = setInterval(this.loadData, 15000)
        }
      }
    }
  },
  created () {
    this.loadData()
  },
  beforeDestroy () {
    this.clearRefreshTimer()
  },
  methods: {
    async loadData () {
      this.loading = true
      try {
        const [sourceResponse, poolResponse] = await Promise.all([
          getDatasourceList({}),
          getDatasourcePools()
        ])
        const sources = sourceResponse.data.data_source || []
        const pools = poolResponse.data.pools || []
        const poolMap = pools.reduce((result, item) => {
          result[item.data_source_uid] = item
          return result
        }, {})
        const sourceUids = new Set(sources.map(item => item.uid))
        const merged = sources.map(source => {
          const pool = poolMap[source.uid]
          return {
            ...source,
            ...pool,
            uid: source.uid,
            has_pool: Boolean(pool),
            pool_state: pool ? pool.pool_state : 'lazy',
            configured_pool_size: source.pool_size,
            configured_max_overflow: source.max_overflow
          }
        })
        pools
          .filter(pool => !sourceUids.has(pool.data_source_uid))
          .forEach(pool => {
            merged.push({
              ...pool,
              uid: pool.data_source_uid,
              name_zh: '已移除的数据源定义',
              name_en: pool.data_source_uid,
              type: 'unknown',
              host: '-',
              port: '-',
              database: '-',
              has_pool: true
            })
          })
        this.items = merged
        if (this.selectedItem) {
          this.selectedItem = merged.find(
            item => item.uid === this.selectedItem.uid
          ) || this.selectedItem
        }
        this.refreshedAt = new Date().toLocaleTimeString('zh-CN', {
          hour12: false
        })
      } catch (error) {
        this.$snackbar.error(
          typeof error === 'string' ? error : '读取连接池状态失败'
        )
      } finally {
        this.loading = false
      }
    },
    stateMeta (state) {
      return STATE_META[state] || STATE_META.lazy
    },
    databaseTypeLabel (type) {
      const labels = {
        postgresql: 'PostgreSQL',
        mysql: 'MySQL'
      }
      return labels[type] || '未知'
    },
    usagePercent (item) {
      const capacity = Math.max(
        Number(item.pool_size || item.configured_pool_size || 2) +
          Number(item.configured_max_overflow || 3),
        1
      )
      return Math.min(100, Number(item.checked_out || 0) / capacity * 100)
    },
    usageColor (item) {
      const percent = this.usagePercent(item)
      if (percent >= 90) return 'error'
      if (percent >= 70) return 'warning'
      return 'primary'
    },
    formatNumber (value) {
      const number = Number(value || 0)
      return Number.isInteger(number) ? number : number.toFixed(1)
    },
    openDetail (item) {
      this.selectedItem = item
      this.drawer = true
    },
    confirmReset (item) {
      this.$confirm(
        '安全重置连接池',
        `确认重置“${item.name_zh || item.name_en}”的连接池吗？系统会等待正在使用的连接归还，下一次业务访问时自动重建。`
      ).then(() => this.resetPool(item))
    },
    async resetPool (item) {
      this.resettingUid = item.uid
      try {
        await invalidateDatasourcePool(item.uid)
        this.$snackbar.success('连接池已进入安全失效流程')
        await this.loadData()
      } catch (error) {
        this.$snackbar.error(
          typeof error === 'string' ? error : '连接池重置失败'
        )
      } finally {
        this.resettingUid = null
      }
    },
    clearRefreshTimer () {
      if (this.refreshTimer) {
        clearInterval(this.refreshTimer)
        this.refreshTimer = null
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.connection-pool-page {
  min-height: 100%;
  padding: 4px;
  color: #263238;
  font-size: 14px;
  box-sizing: border-box;
}

.hero-card {
  border-radius: 6px;
  border-top: 3px solid #1976d2;
}

.hero-content {
  min-height: 104px;
  padding: 20px 24px;
}

.hero-icon {
  width: 56px;
  height: 56px;
  flex: 0 0 56px;
  margin-right: 18px;
  border-radius: 12px;
  background: #e9f2fd;
}

.hero-copy {
  max-width: 720px;

  h1 {
    margin: 0 0 7px;
    color: #263238;
    font-size: 22px;
    font-weight: 600;
    line-height: 1.3;
  }

  p {
    margin: 0;
    color: #607d8b;
    font-size: 14px;
    line-height: 1.65;
  }
}

.summary-row {
  margin-top: 12px;
}

.summary-card {
  display: flex;
  min-height: 108px;
  padding: 19px 20px;
  align-items: center;
  border-radius: 6px;
}

.summary-icon {
  width: 46px;
  height: 46px;
  flex: 0 0 46px;
  margin-right: 15px;
  border-radius: 10px;
}

.summary-icon .v-icon {
  color: inherit !important;
}

.primary-tone {
  color: #1976d2;
  background: #e9f2fd;
}

.info-tone {
  color: #0288d1;
  background: #e4f4fb;
}

.success-tone {
  color: #2e7d32;
  background: #e8f5e9;
}

.warning-tone {
  color: #ef6c00;
  background: #fff3e0;
}

.error-tone {
  color: #c62828;
  background: #ffebee;
}

.neutral-tone {
  color: #607d8b;
  background: #eceff1;
}

.summary-label {
  color: #607d8b;
  font-size: 13px;
}

.summary-value {
  margin: 2px 0;
  color: #263238;
  font-size: 25px;
  font-weight: 600;
  line-height: 1.2;
}

.summary-hint {
  color: #90a4ae;
  font-size: 12px;
}

.management-card {
  margin-top: 12px;
  overflow: hidden;
  border-radius: 6px;
}

.toolbar {
  min-height: 76px;
  padding: 14px 18px;
  gap: 12px;
}

.toolbar-control {
  max-width: 200px;
  flex: 0 1 200px;
}

.refresh-control {
  flex-shrink: 0;
}

.refresh-time {
  color: #90a4ae;
  font-size: 12px;
}

.pool-table {
  font-size: 14px;
}

::v-deep .pool-table .v-data-table__wrapper {
  overflow-x: auto;
}

::v-deep .pool-table table {
  min-width: 920px;
}

::v-deep .pool-table thead th {
  height: 48px;
  color: #455a64 !important;
  background: #f5f8fb;
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
}

::v-deep .pool-table tbody td {
  height: 67px;
  color: #37474f;
  font-size: 13px;
}

.source-name {
  color: #263238;
  font-weight: 600;
}

.source-meta,
.state-caption,
.muted-text {
  margin-top: 3px;
  color: #90a4ae;
  font-size: 12px;
}

.source-endpoint {
  margin-top: 3px;
  color: #78909c;
  font-family: Menlo, Monaco, Consolas, monospace;
  font-size: 11px;
}

.database-type {
  display: flex;
  align-items: center;
  white-space: nowrap;
}

.usage-cell {
  width: 138px;
}

.usage-label {
  margin-bottom: 7px;
  color: #607d8b;
  font-size: 11px;
}

.capacity-value {
  color: #263238;
  font-size: 16px;
  font-weight: 600;
}

.capacity-overflow {
  color: #1976d2;
  font-size: 13px;
  font-weight: 500;
}

.action-cell {
  display: flex;
  white-space: nowrap;
}

.empty-state {
  padding: 42px 16px;
  text-align: center;
}

.empty-title {
  margin-top: 10px;
  color: #455a64;
  font-size: 15px;
  font-weight: 600;
}

.empty-copy {
  margin: 5px 0 4px;
  color: #90a4ae;
  font-size: 13px;
}

.pool-detail-drawer {
  font-size: 14px;
}

.detail-shell {
  min-height: 100%;
  padding-top: 70px;
  background: #f5f7fa;
}

.detail-header {
  min-height: 82px;
  padding: 18px 22px;
  background: #fff;
  border-bottom: 1px solid #e6ebf0;

  h2 {
    margin: 2px 0 0;
    color: #263238;
    font-size: 20px;
    font-weight: 600;
  }
}

.detail-eyebrow {
  color: #90a4ae;
  font-size: 12px;
}

.detail-body {
  padding: 18px;
}

.detail-status,
.detail-section {
  margin-bottom: 14px;
  padding: 18px;
  background: #fff;
  border: 1px solid #e8edf2;
  border-radius: 6px;
}

.detail-status-icon {
  width: 44px;
  height: 44px;
  flex: 0 0 44px;
  margin-right: 14px;
  border-radius: 10px;
}

.detail-status-title {
  color: #263238;
  font-size: 16px;
  font-weight: 600;
}

.detail-status-copy {
  margin-top: 2px;
  color: #78909c;
  font-size: 12px;
  line-height: 1.5;
}

.detail-section h3 {
  margin: 0 0 14px;
  color: #455a64;
  font-size: 14px;
  font-weight: 600;
}

.definition-grid {
  display: grid;
  margin: 0;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px 18px;

  dt {
    color: #90a4ae;
    font-size: 12px;
  }

  dd {
    margin: 4px 0 0;
    color: #37474f;
    font-size: 13px;
    word-break: break-all;
  }
}

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

.metric-item {
  padding: 12px 8px;
  text-align: center;
  background: #f6f9fc;
  border-radius: 4px;
}

.metric-value {
  color: #1976d2;
  font-size: 21px;
  font-weight: 600;
}

.metric-label {
  margin-top: 3px;
  color: #78909c;
  font-size: 11px;
}

@media (max-width: 960px) {
  .hero-content {
    align-items: flex-start !important;
    flex-wrap: wrap;
  }

  .hero-copy {
    width: calc(100% - 74px);
  }

  .hero-actions {
    width: 100%;
    margin-top: 18px;
    padding-left: 74px;
  }

  .refresh-control {
    width: 100%;
    justify-content: flex-end;
  }
}

@media (max-width: 600px) {
  .connection-pool-page {
    padding: 0;
  }

  .hero-content {
    padding: 18px;
  }

  .hero-icon {
    width: 46px;
    height: 46px;
    flex-basis: 46px;
    margin-right: 12px;
  }

  .hero-copy {
    width: calc(100% - 58px);

    h1 {
      font-size: 19px;
    }
  }

  .hero-actions {
    padding-left: 0;

    .v-btn {
      flex: 1;
      margin-right: 8px !important;
    }
  }

  .toolbar-control {
    max-width: none;
    flex-basis: 100%;
  }

  .refresh-control {
    justify-content: space-between;
  }

  .definition-grid {
    grid-template-columns: 1fr;
  }
}
</style>
