<template>
  <AdminLayout title="执行日志" subtitle="执行日志管理">
    <div class="log-management">
      <div class="header">
        <h2>执行日志</h2>
        <el-button type="danger" @click="handleCleanLogs">
          <el-icon><Delete /></el-icon>
          清理日志
        </el-button>
      </div>

      <!-- 搜索筛选区域 -->
      <div class="search-bar">
        <div class="search-item">
          <span class="search-label">任务名称</span>
          <el-input 
            v-model="searchForm.taskName" 
            placeholder="请输入任务名称" 
            clearable
            @keyup.enter="handleSearch"
            style="width: 200px"
          />
        </div>
        <div class="search-item">
          <span class="search-label">任务分组</span>
          <el-input 
            v-model="searchForm.taskGroup" 
            placeholder="请输入任务分组" 
            clearable
            @keyup.enter="handleSearch"
            style="width: 200px"
          />
        </div>
        <div class="search-item">
          <span class="search-label">执行状态</span>
          <el-select 
            v-model="searchForm.executeStatus" 
            placeholder="请选择状态" 
            clearable
            style="width: 150px"
          >
            <el-option label="成功" :value="1" />
            <el-option label="失败" :value="0" />
          </el-select>
        </div>
        <div class="search-actions">
          <el-button type="primary" @click="handleSearch">
            <el-icon><Search /></el-icon>
            搜索
          </el-button>
          <el-button @click="handleReset">
            <el-icon><Refresh /></el-icon>
            重置
          </el-button>
        </div>
      </div>

      <!-- 日志列表 -->
      <el-table 
        :data="logList" 
        style="width: 100%" 
        v-loading="loading"
        border
        stripe
      >
        <el-table-column prop="taskName" label="任务名称" min-width="150" />
        <el-table-column prop="taskGroup" label="任务分组" width="120" />
        <el-table-column prop="beanName" label="Bean名称" min-width="150" />
        <el-table-column prop="methodName" label="方法名称" width="120" />
        <el-table-column label="执行状态" width="100">
          <template #default="{ row }">
            <el-tag :type="row.executeStatus === 1 ? 'success' : 'danger'" size="small">
              {{ row.executeStatus === 1 ? '成功' : '失败' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="executeDuration" label="执行时长" width="100">
          <template #default="{ row }">
            {{ row.executeDuration }}ms
          </template>
        </el-table-column>
        <el-table-column prop="startTime" label="开始时间" width="180" />
        <el-table-column prop="endTime" label="结束时间" width="180" />
        <el-table-column label="操作" width="150" fixed="right">
          <template #default="{ row }">
            <el-button 
              type="primary" 
              size="small" 
              @click="handleViewDetail(row)"
            >
              查看详情
            </el-button>
            <el-button 
              type="danger" 
              size="small" 
              @click="handleDelete(row)"
            >
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页 -->
      <div class="pagination-container" v-if="total > 0">
        <el-pagination
          v-model:current-page="pageParam.pageNumber"
          v-model:page-size="pageParam.pageSize"
          :page-sizes="[10, 20, 50, 100]"
          :total="total"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handleSizeChange"
          @current-change="handlePageChange"
        />
      </div>

      <!-- 详情对话框 -->
      <el-dialog
        v-model="detailDialogVisible"
        title="执行日志详情"
        width="900px"
        :close-on-click-modal="false"
      >
        <div class="detail-content" v-if="currentLog">
          <!-- 日志基本信息 -->
          <el-card class="detail-card" shadow="never">
            <template #header>
              <div class="card-header-title">
                <span>执行信息</span>
              </div>
            </template>
            <div class="detail-grid">
              <div class="detail-item">
                <span class="detail-label">任务名称：</span>
                <span class="detail-value">{{ currentLog.taskName }}</span>
              </div>
              <div class="detail-item">
                <span class="detail-label">任务分组：</span>
                <span class="detail-value">{{ currentLog.taskGroup }}</span>
              </div>
              <div class="detail-item">
                <span class="detail-label">Bean名称：</span>
                <span class="detail-value">{{ currentLog.beanName }}</span>
              </div>
              <div class="detail-item">
                <span class="detail-label">方法名称：</span>
                <span class="detail-value">{{ currentLog.methodName }}</span>
              </div>
              <div class="detail-item" v-if="currentLog.methodParams">
                <span class="detail-label">方法参数：</span>
                <span class="detail-value">{{ currentLog.methodParams }}</span>
              </div>
              <div class="detail-item">
                <span class="detail-label">执行状态：</span>
                <el-tag :type="currentLog.executeStatus === 1 ? 'success' : 'danger'" size="small">
                  {{ currentLog.executeStatus === 1 ? '成功' : '失败' }}
                </el-tag>
              </div>
              <div class="detail-item">
                <span class="detail-label">执行时长：</span>
                <span class="detail-value">{{ currentLog.executeDuration }}ms</span>
              </div>
              <div class="detail-item">
                <span class="detail-label">开始时间：</span>
                <span class="detail-value">{{ currentLog.startTime }}</span>
              </div>
              <div class="detail-item">
                <span class="detail-label">结束时间：</span>
                <span class="detail-value">{{ currentLog.endTime }}</span>
              </div>
              <div class="detail-item full-width" v-if="currentLog.executeMessage">
                <span class="detail-label">执行结果：</span>
                <div class="detail-message">{{ currentLog.executeMessage }}</div>
              </div>
              <div class="detail-item full-width" v-if="currentLog.exceptionInfo">
                <span class="detail-label">异常信息：</span>
                <div class="detail-exception">{{ currentLog.exceptionInfo }}</div>
              </div>
            </div>
          </el-card>

          <!-- 采集的新闻数据 -->
          <el-card class="detail-card" shadow="never" style="margin-top: 20px">
            <template #header>
              <div class="card-header-title">
                <span>采集数据</span>
                <el-tag size="small" type="info">共 {{ collectionItems.length }} 条</el-tag>
              </div>
            </template>

            <div v-loading="loadingItems">
              <!-- 无数据提示 -->
              <el-empty
                v-if="!loadingItems && collectionItems.length === 0"
                description="暂无采集数据"
                :image-size="80"
              />

              <!-- 新闻列表 -->
              <div v-else class="news-list">
                <div
                  v-for="(item, index) in collectionItems"
                  :key="item.id"
                  class="news-item"
                >
                  <div class="news-header">
                    <span class="news-index">#{{ index + 1 }}</span>
                    <el-tag
                      v-if="item.status === 0"
                      type="info"
                      size="small"
                    >
                      未处理
                    </el-tag>
                    <el-tag
                      v-else-if="item.status === 1"
                      type="success"
                      size="small"
                    >
                      已转换
                    </el-tag>
                    <el-tag
                      v-else
                      type="warning"
                      size="small"
                    >
                      已忽略
                    </el-tag>
                  </div>

                  <h4 class="news-title">{{ item.title }}</h4>

                  <div class="news-meta">
                    <span v-if="item.source">来源: {{ item.source }}</span>
                    <span v-if="item.author">作者: {{ item.author }}</span>
                    <span v-if="item.publishTime">发布: {{ item.publishTime }}</span>
                    <span v-if="item.category">分类: {{ item.category }}</span>
                  </div>

                  <div v-if="item.summary" class="news-summary">
                    {{ item.summary }}
                  </div>

                  <div class="news-footer">
                    <el-link
                      v-if="item.sourceUrl"
                      :href="item.sourceUrl"
                      target="_blank"
                      type="primary"
                      :underline="false"
                    >
                      查看原文
                    </el-link>
                    <span v-if="item.crawlTime" class="crawl-time">
                      采集时间: {{ item.crawlTime }}
                    </span>
                  </div>
                </div>
              </div>
            </div>
          </el-card>
        </div>

        <template #footer>
          <el-button @click="detailDialogVisible = false">关闭</el-button>
        </template>
      </el-dialog>

      <!-- 清理日志对话框 -->
      <el-dialog 
        v-model="cleanDialogVisible" 
        title="清理日志"
        width="400px"
      >
        <div class="clean-dialog-content">
          <el-alert 
            title="清理操作不可恢复，请谨慎操作！" 
            type="warning" 
            :closable="false"
            show-icon
          />
          <div class="clean-item">
            <span class="clean-label">保留天数：</span>
            <el-input-number 
              v-model="cleanDays" 
              :min="1"
              :max="365"
              controls-position="right"
            />
            <span class="clean-tip">天</span>
          </div>
          <div class="clean-desc">
            将删除 {{ cleanDays }} 天前的所有执行日志
          </div>
        </div>
        
        <template #footer>
          <el-button @click="cleanDialogVisible = false">取消</el-button>
          <el-button 
            type="danger" 
            @click="handleConfirmClean"
            :loading="submitting"
          >
            确定清理
          </el-button>
        </template>
      </el-dialog>
    </div>
  </AdminLayout>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import { Delete, Search, Refresh } from '@element-plus/icons-vue';
import { crontabApi } from '@/apis/crontab';
import type { CrontabLog, PageParam, DataCollectionItem } from '@/types';
import { AdminLayout } from '@/views/admin';
defineOptions({
  name: 'LogManagementView'
});
// 数据状态
const loading = ref(false);
const submitting = ref(false);
const logList = ref<CrontabLog[]>([]);
const total = ref(0);
const currentLog = ref<CrontabLog | null>(null);
const collectionItems = ref<DataCollectionItem[]>([]);
const loadingItems = ref(false);

// 搜索表单
const searchForm = reactive({
  taskName: '',
  taskGroup: '',
  executeStatus: undefined as number | undefined
});

// 分页参数
const pageParam = reactive<PageParam>({
  pageNumber: 1,
  pageSize: 20
});

// 对话框状态
const detailDialogVisible = ref(false);
const cleanDialogVisible = ref(false);
const cleanDays = ref(30);

// 加载日志列表
async function loadLogList() {
  loading.value = true;
  try {
    const filter: Partial<CrontabLog> = {};
    if (searchForm.taskName) filter.taskName = searchForm.taskName;
    if (searchForm.taskGroup) filter.taskGroup = searchForm.taskGroup;
    if (searchForm.executeStatus !== undefined) filter.executeStatus = searchForm.executeStatus;

    const result = await crontabApi.getLogPage(filter, pageParam);
    if (result.success) {
      // 根据后端返回结构处理数据
      if (result.pageDomain) {
        logList.value = result.pageDomain.dataList || [];
        total.value = result.pageDomain.pageParam?.totalElements || 0;
      } else if (result.dataList) {
        logList.value = result.dataList;
        total.value = result.pageParam?.totalElements || 0;
      } else {
        logList.value = [];
        total.value = 0;
      }
    } else {
      ElMessage.error(result.message || '加载日志列表失败');
      logList.value = [];
      total.value = 0;
    }
  } catch (error) {
    console.error('加载日志列表失败:', error);
    ElMessage.error('加载日志列表失败');
    logList.value = [];
    total.value = 0;
  } finally {
    loading.value = false;
  }
}

// 搜索
function handleSearch() {
  pageParam.pageNumber = 1;
  loadLogList();
}

// 重置搜索
function handleReset() {
  searchForm.taskName = '';
  searchForm.taskGroup = '';
  searchForm.executeStatus = undefined;
  pageParam.pageNumber = 1;
  loadLogList();
}

// 分页变化
function handlePageChange(page: number) {
  pageParam.pageNumber = page;
  loadLogList();
}

function handleSizeChange(size: number) {
  pageParam.pageSize = size;
  pageParam.pageNumber = 1;
  loadLogList();
}

// 查看详情
async function handleViewDetail(row: CrontabLog) {
  try {
    // 同时加载日志详情和采集项数据
    loadingItems.value = true;
    collectionItems.value = [];

    const [logResult, itemsResult] = await Promise.all([
      crontabApi.getLogById(row.id!),
      crontabApi.getCollectionItemsByLogId(row.id!)
    ]);

    if (logResult.success && logResult.data) {
      currentLog.value = logResult.data;
    } else {
      ElMessage.error(logResult.message || '获取日志详情失败');
      return;
    }

    if (itemsResult.success) {
      collectionItems.value = itemsResult.dataList || [];
    } else {
      console.warn('获取采集项失败:', itemsResult.message);
      // 即使采集项加载失败,也显示日志详情
      collectionItems.value = [];
    }

    detailDialogVisible.value = true;
  } catch (error) {
    console.error('获取日志详情失败:', error);
    ElMessage.error('获取日志详情失败');
  } finally {
    loadingItems.value = false;
  }
}

// 删除日志
async function handleDelete(row: CrontabLog) {
  try {
    await ElMessageBox.confirm(
      '确定要删除这条日志吗？',
      '删除确认',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    );

    const result = await crontabApi.deleteLog(row);
    if (result.success) {
      ElMessage.success('删除成功');
      loadLogList();
    } else {
      ElMessage.error(result.message || '删除失败');
    }
  } catch (error: any) {
    if (error !== 'cancel') {
      console.error('删除日志失败:', error);
      ElMessage.error('删除日志失败');
    }
  }
}

// 清理日志
function handleCleanLogs() {
  cleanDialogVisible.value = true;
}

// 确认清理
async function handleConfirmClean() {
  submitting.value = true;
  try {
    const result = await crontabApi.cleanLogs(cleanDays.value);
    if (result.success) {
      ElMessage.success(`已清理 ${result.data || 0} 条日志`);
      cleanDialogVisible.value = false;
      loadLogList();
    } else {
      ElMessage.error(result.message || '清理失败');
    }
  } catch (error) {
    console.error('清理日志失败:', error);
    ElMessage.error('清理日志失败');
  } finally {
    submitting.value = false;
  }
}

// 初始化
onMounted(() => {
  loadLogList();
});
</script>

<style scoped lang="scss">
.log-management {
  padding: 20px;
  background-color: #fff;
  border-radius: 4px;

  .header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;

    h2 {
      margin: 0;
      font-size: 24px;
      font-weight: 600;
      color: #141F38;
    }
  }

  .search-bar {
    display: flex;
    align-items: center;
    gap: 16px;
    margin-bottom: 20px;
    padding: 15px;
    background-color: #f8f9fa;
    border-radius: 8px;
    flex-wrap: wrap;

    .search-item {
      display: flex;
      align-items: center;
      gap: 8px;

      .search-label {
        font-size: 14px;
        color: #606266;
        white-space: nowrap;
      }
    }

    .search-actions {
      display: flex;
      gap: 8px;
      margin-left: auto;
    }
  }

  .detail-content {
    .detail-card {
      margin-bottom: 20px;

      .card-header-title {
        display: flex;
        justify-content: space-between;
        align-items: center;
        font-weight: 600;
        font-size: 16px;
        color: #303133;
      }
    }

    .detail-grid {
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      gap: 16px;

      .detail-item {
        display: flex;
        align-items: flex-start;
        font-size: 14px;

        &.full-width {
          grid-column: 1 / -1;
          flex-direction: column;

          .detail-label {
            margin-bottom: 8px;
          }
        }

        .detail-label {
          min-width: 100px;
          color: #606266;
          font-weight: 500;
        }

        .detail-value {
          flex: 1;
          color: #303133;
          word-break: break-all;
        }

        .detail-message,
        .detail-exception {
          width: 100%;
          padding: 12px;
          background-color: #f5f7fa;
          border-radius: 4px;
          font-family: 'Courier New', monospace;
          font-size: 13px;
          color: #303133;
          white-space: pre-wrap;
          word-break: break-all;
          max-height: 300px;
          overflow-y: auto;
        }

        .detail-exception {
          background-color: #fef0f0;
          color: #f56c6c;
        }
      }
    }

    .news-list {
      max-height: 500px;
      overflow-y: auto;

      .news-item {
        padding: 16px;
        margin-bottom: 16px;
        background-color: #f8f9fa;
        border-radius: 8px;
        border-left: 4px solid #409eff;
        transition: all 0.3s;

        &:hover {
          background-color: #ecf5ff;
          box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
        }

        &:last-child {
          margin-bottom: 0;
        }

        .news-header {
          display: flex;
          align-items: center;
          gap: 12px;
          margin-bottom: 12px;

          .news-index {
            font-size: 12px;
            font-weight: 600;
            color: #409eff;
            background-color: #ecf5ff;
            padding: 2px 8px;
            border-radius: 4px;
          }
        }

        .news-title {
          margin: 0 0 12px 0;
          font-size: 16px;
          font-weight: 600;
          color: #303133;
          line-height: 1.5;
        }

        .news-meta {
          display: flex;
          flex-wrap: wrap;
          gap: 16px;
          margin-bottom: 12px;
          font-size: 13px;
          color: #909399;

          span {
            display: inline-flex;
            align-items: center;

            &:not(:last-child)::after {
              content: '|';
              margin-left: 16px;
              color: #dcdfe6;
            }
          }
        }

        .news-summary {
          margin-bottom: 12px;
          padding: 12px;
          background-color: #fff;
          border-radius: 4px;
          font-size: 14px;
          color: #606266;
          line-height: 1.6;
          max-height: 80px;
          overflow: hidden;
          text-overflow: ellipsis;
          display: -webkit-box;
          -webkit-line-clamp: 3;
          -webkit-box-orient: vertical;
        }

        .news-footer {
          display: flex;
          justify-content: space-between;
          align-items: center;
          padding-top: 12px;
          border-top: 1px solid #e4e7ed;

          .crawl-time {
            font-size: 12px;
            color: #909399;
          }
        }
      }
    }
  }

  .clean-dialog-content {
    .clean-item {
      display: flex;
      align-items: center;
      gap: 12px;
      margin: 20px 0;

      .clean-label {
        font-size: 14px;
        color: #606266;
        font-weight: 500;
      }

      .clean-tip {
        font-size: 14px;
        color: #909399;
      }
    }

    .clean-desc {
      padding: 12px;
      background-color: #f5f7fa;
      border-radius: 4px;
      font-size: 13px;
      color: #606266;
    }
  }
}
</style>

