<template>
  <AdminLayout title="新闻爬虫" subtitle="新闻爬虫配置">
    <div class="news-crawler">
      <div class="header">
        <h2>新闻爬虫配置</h2>
        <el-button type="primary" @click="handleAdd">
          <el-icon><Plus /></el-icon>
          新增爬虫
        </el-button>
      </div>

      <!-- 说明卡片 -->
      <el-alert
        title="新闻爬虫说明"
        type="info"
        :closable="false"
        style="margin-bottom: 20px"
      >
        <p>新闻爬虫配置允许系统自动从指定的新闻源抓取最新新闻内容。</p>
        <p>配置完成后，系统会按照设定的Cron表达式定时执行爬取任务。</p>
      </el-alert>

      <!-- 搜索筛选区域 -->
      <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-select 
            v-model="searchForm.status" 
            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-empty 
        v-if="!loading && crawlerList.length === 0" 
        description="暂无爬虫配置"
        style="margin-top: 40px"
      />
      <!-- 爬虫配置列表 -->
      <div v-else class="crawler-list">
        <el-row :gutter="20">
          <el-col :span="8" v-for="crawler in crawlerList" :key="crawler.taskId">
            <el-card class="crawler-card" shadow="hover">
              <template #header>
                <div class="card-header">
                  <div class="card-title">
                    <el-icon class="title-icon"><DocumentCopy /></el-icon>
                    <span>{{ crawler.taskName }}</span>
                  </div>
                  <el-tag 
                    :type="crawler.status === 1 ? 'success' : 'info'" 
                    size="small"
                  >
                    {{ crawler.status === 1 ? '运行中' : '已暂停' }}
                  </el-tag>
                </div>
              </template>

              <div class="card-content">
                <div class="info-item">
                  <span class="info-label">Bean名称：</span>
                  <span class="info-value">{{ crawler.beanName }}</span>
                </div>
                <div class="info-item">
                  <span class="info-label">方法名称：</span>
                  <span class="info-value">{{ crawler.methodName }}</span>
                </div>
                <div class="info-item">
                  <span class="info-label">执行周期：</span>
                  <span class="info-value">{{ crawler.cronExpression }}</span>
                </div>
                <div class="info-item" v-if="crawler.description">
                  <span class="info-label">描述：</span>
                  <span class="info-value">{{ crawler.description }}</span>
                </div>
              </div>

              <template #footer>
                <div class="card-actions">
                  <el-button 
                    v-if="crawler.status === 0"
                    type="success" 
                    size="small" 
                    @click="handleStart(crawler)"
                  >
                    <el-icon><VideoPlay /></el-icon>
                    启动
                  </el-button>
                  <el-button 
                    v-else
                    type="warning" 
                    size="small" 
                    @click="handlePause(crawler)"
                  >
                    <el-icon><VideoPause /></el-icon>
                    暂停
                  </el-button>
                  <el-button 
                    type="primary" 
                    size="small" 
                    @click="handleExecute(crawler)"
                  >
                    <el-icon><Promotion /></el-icon>
                    执行一次
                  </el-button>
                  <el-button 
                    type="primary" 
                    size="small" 
                    @click="handleEdit(crawler)"
                  >
                    <el-icon><Edit /></el-icon>
                    编辑
                  </el-button>
                  <el-button 
                    type="danger" 
                    size="small" 
                    @click="handleDelete(crawler)"
                  >
                    <el-icon><Delete /></el-icon>
                    删除
                  </el-button>
                </div>
              </template>
            </el-card>
          </el-col>
        </el-row>
      </div>

      <!-- 分页 -->
      <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="dialogVisible"
        :title="isEdit ? '编辑爬虫' : '新增爬虫'"
        width="700px"
        @close="resetForm"
      >
        <div class="form-content">
          <div class="form-item">
            <span class="form-label required">爬虫名称</span>
            <el-input
              v-model="formData.taskName"
              placeholder="请输入爬虫名称"
              clearable
            />
          </div>

          <!-- 爬虫模板选择 -->
          <div class="form-item">
            <span class="form-label required">爬虫模板</span>
            <el-select
              v-model="selectedTemplate"
              placeholder="请选择爬虫模板"
              style="width: 100%"
              
            >
              <el-option
                v-for="template in crawlerTemplates"
                :key="template.name"
                :label="template.name"
                :value="template"
              />
            </el-select>
            <span class="form-tip">
              选择要使用的新闻爬虫类型
            </span>
          </div>

          <!-- 爬取方法选择 -->
          <div class="form-item" v-if="selectedTemplate">
            <span class="form-label required">爬取方法</span>
            <el-select
              v-model="selectedMethodId"
              placeholder="请选择爬取方法"
              style="width: 100%"
              
            >
              <el-option
                v-for="method in selectedTemplate.methods"
                :key="method.metaId"
                :label="method.name"
                :value="method.metaId"
              />
            </el-select>
            <span class="form-tip">
              选择具体的爬取方式
            </span>
          </div>

          <!-- 动态参数表单 -->
          <div class="form-item" v-if="selectedMethod && selectedMethod.params && selectedMethod.params.length > 0">
            <span class="form-label">方法参数</span>
            <div class="params-container">
              <div v-for="param in selectedMethod.params" :key="param.name" class="param-item">
                <span class="param-label">
                  {{ param.description }}
                  <span class="param-type">({{ param.type }})</span>
                </span>
                <el-input
                  v-if="param.type === 'String'"
                  v-model="dynamicParams[param.name]"
                  :placeholder="`请输入${param.description}`"
                  clearable
                />
                <el-input-number
                  v-else-if="param.type === 'Integer'"
                  v-model="dynamicParams[param.name]"
                  :placeholder="`请输入${param.description}`"
                  controls-position="right"
                  style="width: 100%"
                />
                <el-switch
                  v-else-if="param.type === 'Boolean'"
                  v-model="dynamicParams[param.name]"
                  active-text="是"
                  inactive-text="否"
                />
              </div>
            </div>
          </div>

          <div class="form-item">
            <span class="form-label required">Cron表达式</span>
            <el-input
              v-model="formData.cronExpression"
              placeholder="请输入Cron表达式"
              clearable
            >
              <template #append>
                <el-button @click="validateCron">验证</el-button>
              </template>
            </el-input>
            <span class="form-tip">
              常用示例：<br/>
              - 0 0 */6 * * ? （每6小时执行一次）<br/>
              - 0 0 8,12,18 * * ? （每天8点、12点、18点执行）<br/>
              - 0 0/30 * * * ? （每30分钟执行一次）
            </span>
          </div>
          <div class="form-item">
            <span class="form-label">爬虫描述</span>
            <el-input
              v-model="formData.description"
              type="textarea"
              :rows="3"
              placeholder="请输入爬虫描述"
            />
          </div>

          <!-- 邮件接收人配置 -->
          <div class="form-item">
            <span class="form-label">邮件通知</span>
            <el-checkbox v-model="useDefaultRecipients">
              使用默认接收人
            </el-checkbox>
            <span class="form-tip" v-if="useDefaultRecipients && defaultRecipients.length > 0">
              默认接收人：{{ defaultRecipients.map(r => r.username).join('、') }}
            </span>
            <span class="form-tip" v-else-if="useDefaultRecipients && defaultRecipients.length === 0">
              该任务模板暂无默认接收人
            </span>
          </div>

          <div class="form-item">
            <span class="form-label">额外接收人</span>
            <div class="recipient-list">
              <el-tag
                v-for="recipient in additionalRecipients"
                :key="recipient.userId"
                closable
                @close="removeRecipient(recipient)"
                style="margin-right: 8px; margin-bottom: 8px;"
              >
                {{ recipient.username }}
              </el-tag>
            </div>
            <el-button 
              @click="showRecipientSelector" 
              size="small"
              style="margin-top: 8px;"
            >
              选择接收人
            </el-button>
            <!-- TODO: 在这里添加自定义的用户选择组件 -->
          </div>
        </div>

        <template #footer>
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button
            type="primary"
            @click="handleSubmit"
            :loading="submitting"
          >
            确定
          </el-button>
        </template>
      </el-dialog>
      <GenericSelector
        v-model:visible="showUserSelector"
        title="选择邮件接收人"
        left-title="可选人员"
        right-title="已选人员"
        :fetch-available-api="fetchAllUsers"
        :initialTargetItems="selectedRecipients"
        :filter-selected="filterUsers"
        :item-config="{ id: 'userId', label: 'username', sublabel: 'userEmail' }"
        :use-tree="true"
        :tree-transform="transformUserToTree"
        :tree-props="{ children: 'children', label: 'username', id: 'userId' }"
        :only-leaf-selectable="true"
        unit-name="人"
        search-placeholder="搜索用户姓名或邮箱..."
        @confirm="handleUserConfirm"
        @cancel="resetUserSelector"
      />

    </div>
  </AdminLayout>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, watch, computed } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import { Plus, Search, Refresh, DocumentCopy, VideoPlay, VideoPause, Promotion, Edit, Delete } from '@element-plus/icons-vue';
import { crontabApi } from '@/apis/crontab';
import { userApi } from '@/apis/system/user';
import type { CrontabTask, TaskMeta, CrontabItem, CrontabMethod, CrontabParam, PageParam, CreateTaskRequest, RecipientUserInfo, UserVO, ResultDomain, EmailDefault } from '@/types';
import { AdminLayout } from '@/views/admin';
import { GenericSelector } from '@/components';
defineOptions({
  name: 'NewsCrawlerView'
});
// 数据状态
const loading = ref(false);
const submitting = ref(false);
const crawlerList = ref<CrontabTask[]>([]);
const total = ref(0);

// 爬虫元数据
const taskMetaList = ref<TaskMeta[]>([]);
const crawlerTemplates = ref<CrontabItem[]>([]);  // 转换后的模板结构
const selectedTemplate = ref<CrontabItem | null>(null);
const selectedMethodId = ref<string>('');  // 选中的方法ID(metaId)
const selectedMetaId = ref<string>('');  // 选中的元数据ID
const dynamicParams = ref<Record<string, any>>({});

// 邮件接收人相关
const useDefaultRecipients = ref<boolean>(false);
const defaultRecipients = ref<RecipientUserInfo[]>([]);
const additionalRecipients = ref<RecipientUserInfo[]>([]);
const showUserSelector = ref<boolean>(false);
// 所有用户列表（带部门信息），供 selectedRecipients 反查使用
const allUsers = ref<any[]>([]);

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

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

// 对话框状态
const dialogVisible = ref(false);
const isEdit = ref(false);

// 表单数据
const formData = reactive<Partial<CrontabTask>>({
  taskName: '',
  taskGroup: '',
  beanName: '',
  methodName: '',
  methodParams: '',
  cronExpression: '',
  status: 0,
  concurrent: 0,
  misfirePolicy: 3,
  description: ''
});

// 根据selectedMethodId获取完整的method对象
const selectedMethod = computed(() => {
  if (!selectedTemplate.value || !selectedMethodId.value) {
    return null;
  }
  return selectedTemplate.value.methods.find(m => m.metaId === selectedMethodId.value) || null;
});

// 计算已选接收人（包括默认接收人+额外接收人），并转换为带部门信息的完整用户对象
const selectedRecipients = computed(() => {
  // 先根据开关计算出合并后的接收人（RecipientUserInfo）列表
  let baseList: RecipientUserInfo[];
  if (useDefaultRecipients.value) {
    const all = [...defaultRecipients.value, ...additionalRecipients.value];
    const uniqueMap = new Map<string, RecipientUserInfo>();
    all.forEach(r => uniqueMap.set(r.userId, r));
    baseList = Array.from(uniqueMap.values());
  } else {
    baseList = additionalRecipients.value;
  }

  // 用 userId 建索引，按 userId 反查完整用户信息（含 deptID / deptName / parentID）
  const userMap = new Map<string, any>(
    allUsers.value.map(user => [user.userId, user])
  );

  const result = baseList.map(item => {
    const userId = item.userId;
    const user = userMap.get(userId);

    if (user) {
      return {
        ...user,
        isDept: false
      };
    }

    // 找不到对应用户时，至少保证选择器可用
    return {
      userId: item.userId,
      username: item.username,
      userEmail: item.userEmail,
      isDept: false
    };
  });

  return result;
});

// 监听模板选择变化
watch(selectedTemplate, (newTemplate, oldTemplate) => {
  // 只在用户手动切换模板时重置（oldTemplate存在且不为null时才重置）
  // 编辑回填时oldTemplate为null，不会触发重置
  if (newTemplate && oldTemplate) {
    selectedMethodId.value = '';
    dynamicParams.value = {};
  }
});

// 监听方法选择变化
watch(selectedMethodId, (newMethodId) => {
  if (newMethodId && selectedMethod.value) {
    // 保存metaId
    selectedMetaId.value = newMethodId;
    
    dynamicParams.value = {};
    // 遍历params数组提取默认值
    if (selectedMethod.value.params && Array.isArray(selectedMethod.value.params)) {
      selectedMethod.value.params.forEach((param: CrontabParam) => {
        dynamicParams.value[param.name] = param.value;
      });
    }
    
    // 加载该任务模板的默认接收人
    if (selectedMetaId.value) {
      loadDefaultRecipients(selectedMetaId.value);
    }
    
  }
});

// ==================== 人员选择器相关 ====================

/**
 * 1. 获取所有人员列表的接口方法
 */
async function fetchAllUsers(): Promise<ResultDomain<any>> {
  try {
    const result = await userApi.getUserList({});
    if (result.success && result.dataList) {
      // 转换为 GenericSelector 需要的格式
      const users = result.dataList.map((user: UserVO) => ({
        userId: user.id || '',
        username: user.username || user.email || 'Unknown',
        userEmail: user.email || '',
        deptID: user.deptID,
        deptName: user.deptName,
        parentID: user.parentID
      }));

      // 缓存完整用户列表，给 selectedRecipients 使用
      allUsers.value = users;

      return {
        ...result,
        dataList: users
      };
    }
    return result;
  } catch (error) {
    ElMessage.error('获取用户列表失败');
    return {
      code: 500,
      success: false,
      login: true,
      auth: true,
      message: '获取用户列表失败',
      dataList: []
    } as ResultDomain<any>;
  }
}

/**
 * 2. 过滤方法：从可选项中移除已选项
 */
function filterUsers(available: any[], selected: any[]): any[] {
  const selectedIds = new Set(selected.map(item => item.userId));
  return available.filter(item => !selectedIds.has(item.userId));
}

/**
 * 3. 构建多级部门树的方法
 */
function transformUserToTree(flatData: any[]): any[] {
  if (!flatData || flatData.length === 0) {
    return [];
  }
    
  // 第一步：按部门分组，收集每个部门下的用户
  const deptMap = new Map<string, any>();
  const tree: any[] = [];
  
  flatData.forEach(item => {
    if (!item.deptID) return;
    
    if (!deptMap.has(item.deptID)) {
      // 创建部门节点
      deptMap.set(item.deptID, {
        userId: `dept_${item.deptID}`,
        username: item.deptName || '未分配部门',
        userEmail: '',
        deptID: item.deptID,
        deptName: item.deptName,
        parentID: item.parentID,
        children: [],
        isDept: true // 标记这是部门节点
      });
    }
    
    // 添加用户到部门的children中
    const deptNode = deptMap.get(item.deptID);
    if (deptNode) {
      deptNode.children.push({
        ...item,
        isDept: false // 标记这是用户节点
      });
    }
  });
  
  // 第二步：构建部门层级关系
  const allDepts = Array.from(deptMap.values());
  const deptTreeMap = new Map<string, any>();
  
  // 初始化所有部门节点（创建副本）
  allDepts.forEach(dept => {
    deptTreeMap.set(dept.deptID, { ...dept });
  });
  
  // 第三步：建立部门的父子关系
  allDepts.forEach(dept => {
    const node = deptTreeMap.get(dept.deptID);
    if (!node) return;
    
    if (!dept.parentID || dept.parentID === '0' || dept.parentID === '') {
      // 根部门
      tree.push(node);
    } else {
      // 子部门
      const parent = deptTreeMap.get(dept.parentID);
      if (parent) {
        if (!parent.children) {
          parent.children = [];
        }
        // 保存当前节点的用户列表
        const users = node.children || [];
        node.children = [];
        // 将部门节点添加到父部门
        parent.children.push(node);
        // 恢复用户列表
        node.children = users;
      } else {
        // 找不到父节点，作为根节点
        tree.push(node);
      }
    }
  });

  return tree;
}

/**
 * 4. 显示用户选择器
 */
function showRecipientSelector() {
  showUserSelector.value = true;
}

/**
 * 5. 确认选择用户
 */

function handleUserConfirm(selected: any[]) {
  // 过滤掉部门节点，只保留用户节点
  const userItems = selected.filter(item => item.isDept !== true && !defaultRecipients.value.find(r => r.userId === item.userId));
  additionalRecipients.value = userItems.map(item => ({
    userId: item.userId,
    username: item.username,
    userEmail: item.userEmail || ''
  }));
}

/**
 * 6. 取消/重置选择器
 */
function resetUserSelector() {
  console.log('❌ 取消选择');
  // 不做任何操作，保持原有选择
}



// 加载爬虫模板（从数据库加载TaskMeta，转换为CrontabItem结构）
async function loadCrawlerTemplates() {
  try {
    const result = await crontabApi.getEnabledCrontabList();
    if (result.success && result.dataList) {
      taskMetaList.value = result.dataList;
      
      // 将TaskMeta[]按category分组转换为CrontabItem[]
      const grouped = new Map<string, TaskMeta[]>();
      result.dataList.forEach((meta: TaskMeta) => {
        const category = meta.category || '未分类';
        if (!grouped.has(category)) {
          grouped.set(category, []);
        }
        grouped.get(category)!.push(meta);
      });
      
      // 转换为CrontabItem结构
      crawlerTemplates.value = Array.from(grouped.entries()).map(([category, metas]) => ({
        name: category,
        methods: metas.map(meta => ({
          name: meta.name || '',
          clazz: meta.beanName || '',
          excuete_method: meta.methodName || '',
          path: meta.scriptPath || '',
          metaId: meta.metaId || '',  // 保存metaId
          params: meta.paramSchema ? JSON.parse(meta.paramSchema) : []
        }))
      }));
      

    } else {
      ElMessage.error(result.message || '加载爬虫模板失败');
    }
  } catch (error) {
    ElMessage.error('加载爬虫模板失败');
  }
}

// 加载爬虫列表
async function loadCrawlerList() {
  loading.value = true;
  try {
    const filter: Partial<CrontabTask> = {
      taskGroup: ''
    };
    if (searchForm.taskName) filter.taskName = searchForm.taskName;
    if (searchForm.status !== undefined) filter.status = searchForm.status;

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

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

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

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

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

// 新增爬虫
function handleAdd() {
  isEdit.value = false;
  resetFormData();
  selectedTemplate.value = null;
  selectedMethodId.value = '';
  dynamicParams.value = {};
  dialogVisible.value = true;
}

// 编辑爬虫
async function handleEdit(row: CrontabTask) {
  isEdit.value = true;
  Object.assign(formData, row);

  // 重置选择
  selectedTemplate.value = null;
  selectedMethodId.value = '';
  dynamicParams.value = {};
  
  // 回填邮件接收人配置
  useDefaultRecipients.value = row.defaultRecipient || false;
  additionalRecipients.value = [];
  
  // 加载该任务的额外接收人
  if (row.taskId) {
    try {
      const recipientsResult = await crontabApi.getRecipientsByTaskId(row.taskId);
      if (recipientsResult.success && recipientsResult.dataList) {
        additionalRecipients.value = recipientsResult.dataList.map(item => ({
          userId: item.userId || '',
          username: item.name || '',
          userEmail: item.email || ''
        }));
      }
    } catch (error) {
      console.error('加载额外接收人失败:', error);
    }
  }

  // 通过metaId直接匹配
  if (row.metaId) {
    // 遍历所有模板和方法，找到匹配的metaId
    for (const template of crawlerTemplates.value) {
      const method = template.methods.find(m => m.metaId === row.metaId);
      if (method) {
        // 找到匹配的方法，设置template和method
        selectedTemplate.value = template;
        selectedMethodId.value = method.metaId || '';
        selectedMetaId.value = method.metaId || '';
        
        // 回填动态参数
        if (row.methodParams) {
          try {
            const params = JSON.parse(row.methodParams);
            // 排除系统参数
            const { scriptPath, taskId, logId, ...restParams } = params;
            // 延迟设置，确保watch先执行完
            setTimeout(() => {
              dynamicParams.value = restParams;
            }, 0);
          } catch (error) {
            console.error('解析methodParams失败:', error);
          }
        }
        break;
      }
    }
  }

  dialogVisible.value = true;
}

// 启动爬虫
async function handleStart(row: CrontabTask) {
  try {
    const result = await crontabApi.startTask(row.taskId!);
    if (result.success) {
      ElMessage.success('爬虫已启动');
      loadCrawlerList();
    } else {
      ElMessage.error(result.message || '启动失败');
    }
  } catch (error) {
    ElMessage.error('启动爬虫失败');
  }
}

// 暂停爬虫
async function handlePause(row: CrontabTask) {
  try {
    const result = await crontabApi.pauseTask(row.taskId!);
    if (result.success) {
      ElMessage.success('爬虫已暂停');
      loadCrawlerList();
    } else {
      ElMessage.error(result.message || '暂停失败');
    }
  } catch (error) {
    ElMessage.error('暂停爬虫失败');
  }
}

// 执行一次
async function handleExecute(row: CrontabTask) {
  try {
    await ElMessageBox.confirm(
      `确定立即执行爬虫"${row.taskName}"吗？`,
      '确认执行',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    );

    // 异步执行，不等待任务完成
    crontabApi.executeTaskOnce(row.taskId!).then(result => {
      if (result.success) {
        ElMessage.success('任务已提交执行，请稍后查看执行日志');
      } else {
        ElMessage.error(result.message || '提交执行失败');
      }
    }).catch(() => {
      ElMessage.error('提交执行失败');
    });
    
    // 立即提示用户任务已触发
    ElMessage.info('任务执行已触发，正在后台运行...');
  } catch (error: any) {
    if (error !== 'cancel') {
      ElMessage.error('执行爬虫失败');
    }
  }
}

// 删除爬虫
async function handleDelete(row: CrontabTask) {
  try {
    await ElMessageBox.confirm(
      `确定要删除爬虫"${row.taskName}"吗？`,
      '删除确认',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    );

    const result = await crontabApi.deleteTask(row);
    if (result.success) {
      ElMessage.success('删除成功');
      loadCrawlerList();
    } else {
      ElMessage.error(result.message || '删除失败');
    }
  } catch (error: any) {
    if (error !== 'cancel') {
      ElMessage.error('删除爬虫失败');
    }
  }
}

// 验证Cron表达式
async function validateCron() {
  if (!formData.cronExpression) {
    ElMessage.warning('请输入Cron表达式');
    return;
  }

  try {
    const result = await crontabApi.validateCronExpression(formData.cronExpression);
    if (result.success) {
      ElMessage.success('Cron表达式验证通过');
    } else {
      ElMessage.error(result.message || 'Cron表达式格式错误');
    }
  } catch (error) {
    ElMessage.error('验证失败');
  }
}

// 提交表单
async function handleSubmit() {
  // 表单验证
  if (!formData.taskName) {
    ElMessage.warning('请输入爬虫名称');
    return;
  }
  if (!selectedTemplate.value || !selectedMethod.value) {
    ElMessage.warning('请选择爬虫模板和爬取方法');
    return;
  }
  if (!formData.cronExpression) {
    ElMessage.warning('请输入Cron表达式');
    return;
  }
  // 校验additionRecipients的email存在
  const recipientWithoutEmail = additionalRecipients.value.find(recipient => !recipient.userEmail);
  if (recipientWithoutEmail) {
    ElMessage.warning(`${recipientWithoutEmail.username} 邮箱不能为空`);
    return;
  }

  // 验证必填参数
  if (selectedMethod.value.params && Array.isArray(selectedMethod.value.params)) {
    for (const param of selectedMethod.value.params) {
      const value = dynamicParams.value[param.name];

      if (param.required && param.type === 'String' && (!value || value.trim() === '')) {
        ElMessage.warning(`请输入${param.description}`);
        return;
      }
      if (param.required && param.type === 'Integer' && (value === undefined || value === null || value === '')) {
        ElMessage.warning(`请输入${param.description}`);
        return;
      }
    }
  }

  submitting.value = true;
  try {
    // 构建CreateTaskRequest
    const requestData: CreateTaskRequest = {
      metaId: selectedMetaId.value,
      task: {
        ...formData,
        defaultRecipient: useDefaultRecipients.value,
        methodParams: JSON.stringify({
          ...dynamicParams.value
        })
      } as CrontabTask,
      additionalRecipients: additionalRecipients.value
    };

    let result;
    if (isEdit.value) {
      result = await crontabApi.updateTask(requestData);
    } else {
      result = await crontabApi.createTask(requestData);
    }

    if (result.success) {
      ElMessage.success(isEdit.value ? '更新成功' : '创建成功');
      dialogVisible.value = false;
      loadCrawlerList();
    } else {
      ElMessage.error(result.message || (isEdit.value ? '更新失败' : '创建失败'));
    }
  } catch (error) {
    ElMessage.error('提交失败');
  } finally {
    submitting.value = false;
  }
}

// 重置表单
function resetForm() {
  resetFormData();
}

// 重置表单数据
function resetFormData() {
  Object.assign(formData, {
    taskName: '',
    taskGroup: '',
    beanName: '',
    methodName: '',
    methodParams: '',
    cronExpression: '',
    status: 0,
    concurrent: 0,
    misfirePolicy: 3,
    description: '',
    defaultRecipient: false
  });
  useDefaultRecipients.value = false;
  defaultRecipients.value = [];
  additionalRecipients.value = [];
}

// 邮件接收人相关方法
async function loadDefaultRecipients(metaId: string) {
  try {
    const result = await crontabApi.getEmailDefaultByMetaId(metaId);
    
    if (result.success && result.dataList && result.dataList.length > 0) {
      defaultRecipients.value = result.dataList
        .map(item => ({
          userId: item.userId!,
          username: item.username!,
          userEmail: item.userEmail!
        }));
    } else {
      defaultRecipients.value = [];
    }
  } catch (error) {
    defaultRecipients.value = [];
  }
}

// TODO: 用户可以在这里添加自定义的邮件接收人选择逻辑

function removeRecipient(recipient: RecipientUserInfo) {
  const index = additionalRecipients.value.findIndex(r => r.userId === recipient.userId);
  if (index > -1) {
    additionalRecipients.value.splice(index, 1);
  }
}

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

<style scoped lang="scss">
.news-crawler {
  padding: 20px;
  background-color: #fff;
  border-radius: 4px;
  max-height: 50%;
  overflow: auto;
  .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;
    }
  }

  .crawler-list {
    min-height: 400px;

    .crawler-card {
      margin-bottom: 20px;
      transition: all 0.3s;

      &:hover {
        transform: translateY(-4px);
      }

      .card-header {
        display: flex;
        justify-content: space-between;
        align-items: center;

        .card-title {
          display: flex;
          align-items: center;
          gap: 8px;
          font-size: 16px;
          font-weight: 600;
          color: #303133;

          .title-icon {
            font-size: 20px;
            color: #409eff;
          }
        }
      }

      .card-content {
        .info-item {
          display: flex;
          margin-bottom: 12px;
          font-size: 14px;

          .info-label {
            min-width: 80px;
            color: #909399;
          }

          .info-value {
            flex: 1;
            color: #606266;
            word-break: break-all;
          }
        }
      }

      .card-actions {
        display: flex;
        gap: 8px;
        flex-wrap: wrap;
      }
    }
  }

  .form-content {
    .form-item {
      margin-bottom: 20px;

      .form-label {
        display: block;
        margin-bottom: 8px;
        font-size: 14px;
        color: #606266;
        font-weight: 500;

        &.required::before {
          content: '*';
          color: #f56c6c;
          margin-right: 4px;
        }
      }

      .form-tip {
        display: block;
        margin-top: 4px;
        font-size: 12px;
        color: #909399;
        line-height: 1.6;
      }

      .params-container {
        padding: 12px;
        background-color: #f8f9fa;
        border-radius: 4px;
        border: 1px solid #e4e7ed;

        .param-item {
          margin-bottom: 16px;

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

          .param-label {
            display: block;
            margin-bottom: 8px;
            font-size: 13px;
            color: #606266;
            font-weight: 500;

            .param-type {
              color: #909399;
              font-weight: normal;
              font-size: 12px;
            }
          }
        }
      }
    }
  }
}
</style>

