<template>
  <div class="app-container">
    <a-card :bordered="false" class="full-height-card">
      <template #title>
        <div class="header-actions">
          <div class="left">
            <span class="title">系统实时日志</span>
          </div>
          <div class="right">
            <a-switch
              v-model="debugMode"
              checked-color="#ff4d4f"
              unchecked-color="#14c9c9"
              @change="handleDebugModeChange"
              style="margin-right: 20px"
            >
              <template #checked>调试模式 ON</template>
              <template #unchecked>调试模式 OFF</template>
            </a-switch>

            <a-select v-model="currentFile" placeholder="选择日志文件" style="width: 200px; margin-right: 10px" @change="fetchLogs">
              <a-option
                v-for="file in logFiles"
                :key="file"
                :label="file"
                :value="file"
              />
            </a-select>
            
            <a-input-search
              v-model="searchKeyword"
              placeholder="关键字搜索 (INFO/ERROR...)"
              style="width: 250px; margin-right: 10px"
              allow-clear
              search-button
              @search="fetchLogs"
              @press-enter="fetchLogs"
              @clear="fetchLogs"
            />

            <a-switch
              v-model="autoRefresh"
              @change="handleAutoRefresh"
            >
              <template #checked>实时刷新</template>
              <template #unchecked>手动刷新</template>
            </a-switch>
          </div>
        </div>
      </template>

      <div class="log-container" ref="logContainerRef">
        <div v-if="loading && !logs.length" class="loading-state">
           <a-spin dot /> 加载中...
        </div>
        <div v-else-if="logs.length === 0" class="empty-state">
           <a-empty description="暂无日志数据" />
        </div>
        <div v-else class="log-content">
          <div v-for="(line, index) in logs" :key="index" class="log-line" :class="getLineClass(line)">
            <span class="line-num">{{ index + 1 }}</span>
            <span class="line-text">{{ line }}</span>
          </div>
        </div>
      </div>
      
      <div class="footer-info">
        共加载 {{ logs.length }} 行日志 (仅显示最后 5000 行)
      </div>
    </a-card>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, nextTick } from 'vue';
import api from '../../api';
import { Message } from '@arco-design/web-vue';

const logFiles = ref<string[]>([]);
const currentFile = ref('');
const logs = ref<string[]>([]);
const searchKeyword = ref('');
const autoRefresh = ref(false);
const debugMode = ref(false);
const loading = ref(false);
const logContainerRef = ref<HTMLElement | null>(null);
let timer: any = null;

// 切换调试模式
const handleDebugModeChange = async (val: boolean | string | number) => {
  const enabled = val === true;
  try {
    await api.post('/system/debug-log', { enabled });
    Message.success(`调试模式已${enabled ? '开启' : '关闭'}`);
  } catch (error) {
    console.error('Failed to set debug mode', error);
    debugMode.value = !enabled; // 失败回滚状态
    Message.error('设置失败');
  }
};

// 获取日志文件列表
const fetchLogFiles = async () => {
  try {
    const res: any = await api.get('/ops/logs/files');
    // Arco design response handling might differ, usually check res.data if not intercepted
    // Assuming api interceptor returns data directly based on previous files
    logFiles.value = res.data || res || [];
    if (logFiles.value.length > 0 && !currentFile.value) {
      currentFile.value = logFiles.value[0]; // 默认选中最新的
      fetchLogs();
    }
  } catch (error) {
    console.error('Failed to fetch log files', error);
  }
};

// 获取日志内容
const fetchLogs = async () => {
  if (!currentFile.value) return;
  
  // 如果不是自动刷新，显示loading
  if (!autoRefresh.value) {
      loading.value = true;
  }

  try {
    const res: any = await api.get('/ops/logs/content', {
      params: {
        filename: currentFile.value,
        keyword: searchKeyword.value
      }
    });
    
    const data = res.data || res;
    const newLogs = data.content || [];
    const isAtBottom = checkScrollBottom();
    
    logs.value = newLogs;

    // 如果之前在底部，或者刚加载，则自动滚动到底部
    if (isAtBottom || !timer) {
       scrollToBottom();
    }
  } catch (error) {
    console.error('Failed to fetch logs', error);
  } finally {
    loading.value = false;
  }
};

// 处理自动刷新
const handleAutoRefresh = (val: boolean | string | number) => {
  if (val) {
    fetchLogs();
    timer = setInterval(fetchLogs, 3000); // 3秒刷新一次
  } else {
    if (timer) clearInterval(timer);
    timer = null;
  }
};

// 辅助样式：高亮 ERROR 和 WARN
const getLineClass = (line: string) => {
  if (line.includes('[ERROR]') || line.includes('level=error')) return 'line-error';
  if (line.includes('[WARN]') || line.includes('level=warn')) return 'line-warn';
  return '';
};

// 滚动到底部
const scrollToBottom = () => {
  nextTick(() => {
    if (logContainerRef.value) {
      logContainerRef.value.scrollTop = logContainerRef.value.scrollHeight;
    }
  });
};

// 检查是否滚动到底部（用于决定刷新后是否自动滚动）
const checkScrollBottom = () => {
    if (!logContainerRef.value) return true;
    const { scrollTop, scrollHeight, clientHeight } = logContainerRef.value;
    // 允许 50px 的误差
    return scrollHeight - scrollTop - clientHeight < 50;
};

onMounted(() => {
  fetchLogFiles();
});

onUnmounted(() => {
  if (timer) clearInterval(timer);
});
</script>

<style scoped>
.app-container {
  padding: 20px;
  height: calc(100vh - 84px); /* 减去顶部导航栏高度 */
  display: flex;
  flex-direction: column;
}

.full-height-card {
  flex: 1;
  display: flex;
  flex-direction: column;
  height: 100%; /* 确保卡片撑满父容器 */
}

:deep(.arco-card-body) {
  flex: 1;
  overflow: hidden;
  padding: 0;
  display: flex;
  flex-direction: column;
  height: 0; /* 关键：让 flex 子元素正确计算高度 */
}

.header-actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
}

.right {
    display: flex;
    align-items: center;
}

.title {
  font-weight: bold;
  font-size: 16px;
}

.log-container {
  flex: 1;
  background-color: #1e1e1e;
  color: #d4d4d4;
  overflow-y: auto;
  padding: 10px;
  font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
  font-size: 13px;
  line-height: 1.5;
  position: relative;
  scroll-behavior: smooth; /* 添加平滑滚动 */
}

.loading-state {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100%;
    color: #888;
    gap: 10px;
}

.empty-state {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100%;
}

.log-line {
  white-space: pre-wrap;
  word-break: break-all;
  display: flex;
}

.line-num {
  color: #6e7681;
  min-width: 40px;
  text-align: right;
  margin-right: 15px;
  user-select: none;
}

.line-error {
  color: #f56c6c;
}

.line-warn {
  color: #e6a23c;
}

.footer-info {
  padding: 8px 15px;
  background: var(--color-fill-2);
  border-top: 1px solid var(--color-border);
  font-size: 12px;
  color: var(--color-text-3);
  flex-shrink: 0; /* 防止底部信息被压缩 */
}
</style>
