<template>
  <div class="system-health-container">
    <div class="health-card">
      <h1 class="page-title">系统健康状态</h1>
      
      <div class="action-buttons">
        <button 
          class="btn-refresh" 
          @click="fetchHealthStats" 
          :disabled="isLoading"
        >
          {{ isLoading ? '加载中...' : '刷新数据' }}
        </button>
        <div class="toggle-container">
          <label class="toggle-label">
            <input type="checkbox" v-model="includeSlowQueries">
            包含慢查询
          </label>
          <label class="toggle-label">
            <input type="checkbox" v-model="includeLongSessions">
            包含长会话
          </label>
        </div>
      </div>
      
      <div v-if="errorMessage" class="status-message status-error">
        {{ errorMessage }}
      </div>
      
      <div v-if="isLoading" class="loading-indicator">
        <div class="spinner"></div>
        <div>加载系统健康数据...</div>
      </div>
      
      <div v-if="healthData && !isLoading" class="health-data">
        <div class="health-grid">
          <!-- 连接池信息 -->
          <div class="data-section">
            <h2 class="section-title">数据库连接池</h2>
            <div class="data-grid">
              <div class="data-item">
                <div class="data-label">池大小</div>
                <div class="data-value">{{ healthData.connection_pool.pool_size }}</div>
              </div>
              <div class="data-item">
                <div class="data-label">已签入</div>
                <div class="data-value">{{ healthData.connection_pool.checkedin }}</div>
              </div>
              <div class="data-item">
                <div class="data-label">已签出</div>
                <div class="data-value">{{ healthData.connection_pool.checkedout }}</div>
              </div>
              <div class="data-item">
                <div class="data-label">溢出</div>
                <div class="data-value" :class="{'value-warning': healthData.connection_pool.overflow > 0}">
                  {{ healthData.connection_pool.overflow }}
                </div>
              </div>
            </div>
          </div>
          
          <!-- 会话信息 -->
          <div class="data-section">
            <h2 class="section-title">会话信息</h2>
            <div class="data-grid">
              <div class="data-item">
                <div class="data-label">活跃会话</div>
                <div class="data-value">{{ healthData.sessions.active_count }}</div>
              </div>
              <div class="data-item">
                <div class="data-label">长时间运行会话</div>
                <div class="data-value" :class="{'value-warning': healthData.sessions.long_running_count > 0}">
                  {{ healthData.sessions.long_running_count }}
                </div>
              </div>
              <div class="data-item">
                <div class="data-label">慢查询数量</div>
                <div class="data-value" :class="{'value-warning': healthData.performance_stats.slow_queries_count > 0}">
                  {{ healthData.performance_stats.slow_queries_count }}
                </div>
              </div>
            </div>
          </div>
        </div>
        
        <!-- 性能统计 -->
        <div class="data-section">
          <h2 class="section-title">性能统计</h2>
          <div class="stats-grid">
            <!-- 最慢端点 -->
            <div class="subsection">
              <h3 class="subsection-title">最慢端点</h3>
              <div class="table-container">
                <table class="data-table">
                  <thead>
                    <tr>
                      <th>端点</th>
                      <th>响应时间 (秒)</th>
                    </tr>
                  </thead>
                  <tbody>
                    <tr v-for="(endpoint, index) in healthData.performance_stats.top_slow_endpoints" :key="index">
                      <td>{{ endpoint[0] }}</td>
                      <td>{{ endpoint[1].toFixed(4) }}</td>
                    </tr>
                    <tr v-if="healthData.performance_stats.top_slow_endpoints.length === 0">
                      <td colspan="2" class="empty-message">无数据</td>
                    </tr>
                  </tbody>
                </table>
              </div>
            </div>
            
            <!-- 每小时请求 -->
            <div class="subsection">
              <h3 class="subsection-title">每小时请求数</h3>
              <div class="table-container">
                <table class="data-table">
                  <thead>
                    <tr>
                      <th>时间</th>
                      <th>请求数</th>
                    </tr>
                  </thead>
                  <tbody>
                    <tr v-for="(count, hour) in healthData.performance_stats.hourly_requests" :key="hour">
                      <td>{{ hour }}</td>
                      <td>{{ count }}</td>
                    </tr>
                    <tr v-if="Object.keys(healthData.performance_stats.hourly_requests).length === 0">
                      <td colspan="2" class="empty-message">无数据</td>
                    </tr>
                  </tbody>
                </table>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { ref, onMounted, onBeforeUnmount, watch } from 'vue'
import apiClient from '../services/api'

export default {
  name: 'SystemHealth',
  setup() {
    const healthData = ref(null)
    const isLoading = ref(false)
    const errorMessage = ref('')
    const includeSlowQueries = ref(false)
    const includeLongSessions = ref(false)
    
    // 获取健康统计数据
    const fetchHealthStats = async () => {
      isLoading.value = true
      errorMessage.value = ''
      
      try {
        const params = {
          include_slow_queries: includeSlowQueries.value,
          include_long_sessions: includeLongSessions.value
        }
        
        const response = await apiClient.get('/api/health/stats', { params })
        
        if (response.data && response.data.code === 200) {
          healthData.value = response.data.data
        } else {
          errorMessage.value = response.data?.message || '获取健康数据失败'
        }
      } catch (error) {
        console.error('获取健康数据失败:', error)
        
        if (error.code === 'ECONNABORTED') {
          errorMessage.value = '请求超时，请检查网络或稍后重试'
        } else {
          errorMessage.value = '获取健康数据失败，请重试'
        }
      } finally {
        isLoading.value = false
      }
    }
    
    // 监听过滤器变化，重新获取数据
    watch([includeSlowQueries, includeLongSessions], () => {
      fetchHealthStats()
    })
    
    onMounted(() => {
      document.title = '系统健康状态 - 蜂快到家'
      fetchHealthStats()
    })
    
    onBeforeUnmount(() => {
      document.title = '蜂快到家'
    })
    
    return {
      healthData,
      isLoading,
      errorMessage,
      includeSlowQueries,
      includeLongSessions,
      fetchHealthStats
    }
  }
}
</script>

<style scoped>
.system-health-container {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 15px;
  background: linear-gradient(to bottom, #FFCC00, #FFFFFF);
}

.health-card {
  width: 100%;
  max-width: 900px;
  background-color: #FFFFFF;
  border-radius: 15px;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1);
  padding: 20px 15px;
  margin-bottom: 15px;
}

.page-title {
  font-size: 20px;
  font-weight: bold;
  color: #333333;
  text-align: center;
  margin-bottom: 15px;
}

.action-buttons {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
}

.btn-refresh {
  padding: 8px 15px;
  border-radius: 6px;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.3s;
  text-align: center;
  border: none;
  background-color: #FFCC00;
  color: #333333;
}

.btn-refresh:hover {
  background-color: #FFD633;
}

.btn-refresh:disabled {
  background-color: #DDDDDD;
  color: #999999;
  cursor: not-allowed;
}

.toggle-container {
  display: flex;
  gap: 12px;
}

.toggle-label {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 13px;
  color: #666666;
  cursor: pointer;
}

.status-message {
  padding: 8px 12px;
  border-radius: 6px;
  font-size: 13px;
  margin-bottom: 15px;
  text-align: center;
}

.status-error {
  background-color: rgba(255, 87, 87, 0.1);
  color: #FF5757;
  border: 1px solid rgba(255, 87, 87, 0.3);
}

.loading-indicator {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 20px;
  color: #666666;
  gap: 10px;
}

.spinner {
  width: 30px;
  height: 30px;
  border: 3px solid rgba(255, 204, 0, 0.3);
  border-radius: 50%;
  border-top-color: #FFCC00;
  animation: spin 1s ease-in-out infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

.health-data {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.health-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 15px;
}

.data-section {
  border: 1px solid #EEEEEE;
  border-radius: 8px;
  padding: 15px;
  background-color: #FAFAFA;
}

.section-title {
  font-size: 16px;
  font-weight: bold;
  color: #333333;
  margin-bottom: 12px;
  padding-bottom: 8px;
  border-bottom: 1px solid #EEEEEE;
}

.stats-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 15px;
}

.subsection {
  margin-bottom: 0;
}

.subsection-title {
  font-size: 14px;
  font-weight: 600;
  color: #555555;
  margin-bottom: 8px;
}

.data-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
}

.data-item {
  background-color: #FFFFFF;
  border-radius: 6px;
  padding: 10px;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05);
}

.data-label {
  font-size: 12px;
  color: #666666;
  margin-bottom: 3px;
}

.data-value {
  font-size: 18px;
  font-weight: bold;
  color: #333333;
}

.value-warning {
  color: #FF5757;
}

.table-container {
  overflow-x: auto;
  margin-bottom: 0;
  max-height: 150px;
  overflow-y: auto;
}

.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
}

.data-table th {
  background-color: #F2F2F2;
  padding: 8px;
  text-align: left;
  font-weight: 600;
  color: #555555;
  position: sticky;
  top: 0;
  z-index: 1;
}

.data-table td {
  padding: 6px 8px;
  border-top: 1px solid #EEEEEE;
}

.data-table tr:hover td {
  background-color: rgba(255, 204, 0, 0.05);
}

.empty-message {
  text-align: center;
  color: #999999;
  padding: 10px;
}

@media (max-width: 768px) {
  .health-grid, .stats-grid {
    grid-template-columns: 1fr;
  }
  
  .data-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 480px) {
  .action-buttons {
    flex-direction: column;
    gap: 10px;
    align-items: stretch;
  }
  
  .toggle-container {
    justify-content: space-between;
  }
  
  .data-grid {
    grid-template-columns: 1fr;
  }
  
  .data-value {
    font-size: 16px;
  }
}
</style> 