<template>
  <div>
    <div class="page-header">
      <div>
        <h2>服务日志</h2>
        <p class="subtitle">查看各服务的运行日志，支持定时自动刷新。</p>
      </div>
    </div>

    <el-card style="margin-bottom: 12px">
      <el-skeleton v-if="loadingServices" :rows="1" animated style="margin-bottom:12px" />
      <template v-else-if="services.length === 0">
        <el-empty description="未检测到正在运行的服务" :image-size="60" />
      </template>
      <template v-else>
        <el-tabs v-model="activeService" type="card" class="service-tabs" @tab-change="onServiceChange">
          <el-tab-pane v-for="svc in services" :key="svc" :label="svc" :name="svc" />
        </el-tabs>

        <div class="controls">
          <div class="controls-left">
            <span class="control-label">显示行数</span>
            <el-select v-model="lineCount" style="width:100px" size="small" @change="fetchLogs">
              <el-option :value="100" label="100 行" />
              <el-option :value="200" label="200 行" />
              <el-option :value="500" label="500 行" />
              <el-option :value="1000" label="1000 行" />
            </el-select>

            <span class="control-label">刷新间隔</span>
            <el-select v-model="refreshInterval" style="width:110px" size="small" @change="onIntervalChange">
              <el-option :value="0" label="手动" />
              <el-option :value="5" label="5 秒" />
              <el-option :value="10" label="10 秒" />
              <el-option :value="30" label="30 秒" />
              <el-option :value="60" label="1 分钟" />
            </el-select>

            <el-button
              v-if="refreshInterval > 0"
              :type="autoRefreshing ? 'danger' : 'success'"
              size="small"
              @click="toggleAutoRefresh"
            >
              {{ autoRefreshing ? '停止刷新' : '开始刷新' }}
            </el-button>
          </div>

          <div class="controls-right">
            <el-checkbox v-model="autoScroll" size="small">自动滚动</el-checkbox>
            <el-button size="small" :loading="fetching" @click="fetchLogs">
              <el-icon><Refresh /></el-icon>
              刷新
            </el-button>
            <el-button size="small" @click="clearLog">清除</el-button>
          </div>
        </div>

        <div class="status-bar">
          <template v-if="lastFetchTime">
            <span>最后更新：{{ lastFetchTime }}</span>
            <span class="sep">·</span>
            <span>{{ lineCount }} 行</span>
            <span v-if="autoRefreshing" class="live-badge">
              <span class="live-dot" />
              实时刷新
            </span>
            <span v-if="fetchError" class="error-badge">{{ fetchError }}</span>
          </template>
          <template v-else-if="fetching">
            <span>加载中...</span>
          </template>
          <template v-else>
            <span style="color:#c0c4cc">尚未加载</span>
          </template>
        </div>
      </template>
    </el-card>

    <el-card v-if="services.length > 0" class="log-card">
      <div class="log-wrap">
        <pre ref="logEl" class="log-content">{{ logContent || (fetching ? '加载中...' : '暂无日志，点击刷新按钮获取。') }}</pre>
      </div>
    </el-card>
  </div>
</template>

<script setup lang="ts">
import { nextTick, onMounted, onUnmounted, ref, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { Refresh } from '@element-plus/icons-vue'
import { opsApi } from '@/api/ops'

const services = ref<string[]>([])
const activeService = ref('')
const loadingServices = ref(false)

const lineCount = ref(200)
const refreshInterval = ref(0)
const autoRefreshing = ref(false)
const autoScroll = ref(true)

const logContent = ref('')
const fetching = ref(false)
const lastFetchTime = ref('')
const fetchError = ref('')
const logEl = ref<HTMLPreElement | null>(null)

let refreshTimer: ReturnType<typeof setInterval> | null = null

onMounted(async () => {
  loadingServices.value = true
  try {
    const res = await opsApi.getRunningServices()
    services.value = res.data.data
    if (services.value.length > 0) {
      activeService.value = services.value[0]
      await fetchLogs()
    }
  } catch {
    ElMessage.error('获取服务列表失败')
  } finally {
    loadingServices.value = false
  }
})

onUnmounted(() => {
  stopAutoRefresh()
})

async function onServiceChange() {
  logContent.value = ''
  lastFetchTime.value = ''
  fetchError.value = ''
  if (autoRefreshing.value) {
    stopAutoRefresh()
    await fetchLogs()
    startAutoRefresh()
  } else {
    await fetchLogs()
  }
}

async function fetchLogs() {
  if (!activeService.value || fetching.value) return
  fetching.value = true
  fetchError.value = ''
  try {
    const res = await opsApi.fetchServiceLogs(activeService.value, lineCount.value)
    logContent.value = res.data as unknown as string
    lastFetchTime.value = new Date().toLocaleTimeString()
    if (autoScroll.value) {
      await nextTick()
      scrollToBottom()
    }
  } catch (e: any) {
    fetchError.value = e?.message ?? '获取失败'
  } finally {
    fetching.value = false
  }
}

function clearLog() {
  logContent.value = ''
  lastFetchTime.value = ''
  fetchError.value = ''
}

function scrollToBottom() {
  if (logEl.value) logEl.value.scrollTop = logEl.value.scrollHeight
}

function onIntervalChange() {
  stopAutoRefresh()
  if (refreshInterval.value > 0) startAutoRefresh()
}

function toggleAutoRefresh() {
  autoRefreshing.value ? stopAutoRefresh() : startAutoRefresh()
}

function startAutoRefresh() {
  if (refreshInterval.value <= 0) return
  autoRefreshing.value = true
  fetchLogs()
  refreshTimer = setInterval(fetchLogs, refreshInterval.value * 1000)
}

function stopAutoRefresh() {
  autoRefreshing.value = false
  if (refreshTimer !== null) {
    clearInterval(refreshTimer)
    refreshTimer = null
  }
}

watch(lineCount, () => {
  if (autoRefreshing.value) {
    stopAutoRefresh()
    startAutoRefresh()
  }
})
</script>

<style scoped>
.page-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px;
  margin-bottom: 16px;
}
.subtitle {
  margin: 6px 0 0;
  color: #606266;
}
.service-tabs {
  margin-bottom: 12px;
}
.service-tabs :deep(.el-tabs__header) {
  margin-bottom: 0;
}
.controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  flex-wrap: wrap;
  padding: 8px 0;
  border-top: 1px solid #f0f0f0;
  border-bottom: 1px solid #f0f0f0;
  margin-bottom: 8px;
}
.controls-left,
.controls-right {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.control-label {
  font-size: 13px;
  color: #606266;
  white-space: nowrap;
}
.status-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: #909399;
  min-height: 20px;
}
.sep { color: #dcdfe6; }
.live-badge {
  display: flex;
  align-items: center;
  gap: 4px;
  color: #67c23a;
  font-weight: 500;
}
.live-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #67c23a;
  animation: blink 1.2s ease-in-out infinite;
}
@keyframes blink {
  0%, 100% { opacity: 1; }
  50%       { opacity: 0.2; }
}
.error-badge { color: #f56c6c; }
.log-card :deep(.el-card__body) { padding: 0; }
.log-wrap {
  background: #0d1117;
  border-radius: 4px;
  overflow: hidden;
}
.log-content {
  margin: 0;
  padding: 14px 16px;
  font-family: 'JetBrains Mono', 'Fira Code', 'Cascadia Code', Consolas, monospace;
  font-size: 12px;
  line-height: 1.65;
  color: #c9d1d9;
  white-space: pre-wrap;
  word-break: break-all;
  height: 520px;
  overflow-y: auto;
}
</style>
