/* === Batch Task Management Page === */
function PageOperationBatch() {
  const [activeTab, setActiveTab] = React.useState("trigger");

  const tabs = [
    { id: "trigger", label: "触发管理" },
    { id: "taskGroup", label: "任务定义" },
    { id: "monitor", label: "执行监控" },
    { id: "logs", label: "任务日志" }
  ];

  return (
    <div className="page-operation">
      <div className="card operation-header-card">
        <div className="tab-container batch-tabs-wrapper">
          {tabs.map(tab => (
            <button
              key={tab.id}
              className={`tab-btn batch-tab ${activeTab === tab.id ? "active" : ""}`}
              onClick={() => setActiveTab(tab.id)}
            >
              {tab.label}
            </button>
          ))}
        </div>
        <div className="tab-content batch-content">
          {activeTab === "trigger" && <TriggerManagement />}
          {activeTab === "taskGroup" && <TaskGroupManagement />}
          {activeTab === "monitor" && <TaskMonitor />}
          {activeTab === "logs" && <TaskLogs />}
        </div>
      </div>
    </div>
  );
}

// 触发器管理组件
function TriggerManagement() {
  const [triggers, setTriggers] = React.useState([]);
  const [searchParams, setSearchParams] = React.useState({
    triggerName: "",
    status: ""
  });
  const [showModal, setShowModal] = React.useState(false);
  const [editingTrigger, setEditingTrigger] = React.useState(null);
  const [taskGroups, setTaskGroups] = React.useState([]);

  const fetchTriggers = async () => {
    try {
      const params = new URLSearchParams();
      if (searchParams.triggerName) params.append('trigger_name', searchParams.triggerName);
      if (searchParams.status !== "") params.append('status', searchParams.status);
      const data = await window.apiFetch(`/api/rule/trigger/list?${params}`);
      setTriggers(Array.isArray(data) ? data : (data.items || []));
    } catch (error) {
      console.error('获取触发器列表失败:', error);
    }
  };

  const fetchTaskGroups = async () => {
    try {
      const data = await window.apiFetch('/api/rule/taskGroup/list');
      setTaskGroups(Array.isArray(data) ? data : (data.items || []));
    } catch (error) {
      console.error('获取任务组列表失败:', error);
    }
  };

  React.useEffect(() => {
    fetchTriggers();
    fetchTaskGroups();
  }, []);

  const handleAdd = () => {
    setEditingTrigger(null);
    setShowModal(true);
  };

  const handleEdit = (trigger) => {
    setEditingTrigger(trigger);
    setShowModal(true);
  };

  const handleDelete = async (id) => {
    if (!confirm('确定要删除该触发器吗？')) return;
    try {
      await window.apiFetch(`/api/rule/trigger/delete?id=${id}`, { method: 'DELETE' });
      fetchTriggers();
    } catch (error) {
      alert('删除失败: ' + error.message);
    }
  };

  const handleExecute = async (id) => {
    if (!confirm('确定要立即执行该触发器吗？')) return;
    try {
      await window.apiFetch(`/api/rule/trigger/execute?id=${id}`, { method: 'POST' });
      alert('执行已启动');
    } catch (error) {
      alert('执行失败: ' + error.message);
    }
  };

  const handleToggle = async (id, status) => {
    try {
      await window.apiFetch(`/api/rule/trigger/toggle?id=${id}&status=${status}`, { method: 'POST' });
      fetchTriggers();
    } catch (error) {
      alert('操作失败: ' + error.message);
    }
  };

  const handleSave = async (formData) => {
    try {
      if (editingTrigger) {
        await window.apiFetch('/api/rule/trigger/update', {
          method: 'PUT',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ ...formData, id: editingTrigger.id })
        });
      } else {
        await window.apiFetch('/api/rule/trigger/add', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(formData)
        });
      }
      setShowModal(false);
      fetchTriggers();
    } catch (error) {
      alert('保存失败: ' + error.message);
    }
  };

  const getTaskGroupName = (groupId) => {
    const group = taskGroups.find(g => g.id === groupId);
    return group ? group.group_name : '-';
  };

  const statusText = { 1: '启用', 0: '禁用' };
  const typeText = { CRON: '定时', MANUAL: '手动', API: 'API', EVENT: '事件' };

  return (
    <div className="trigger-manager">
      <div className="filter-row" style={{ padding: '16px' }}>
        <div className="filter-item">
          <label>触发器名称</label>
          <input
            type="text"
            className="input"
            value={searchParams.triggerName}
            onChange={(e) => setSearchParams({ ...searchParams, triggerName: e.target.value })}
            placeholder="请输入触发器名称"
            style={{ width: 160 }}
          />
        </div>
        <div className="filter-item">
          <label>状态</label>
          <select 
            className="input"
            value={searchParams.status}
            onChange={(e) => setSearchParams({ ...searchParams, status: e.target.value })}
            style={{ width: 100 }}
          >
            <option value="">全部</option>
            <option value="1">启用</option>
            <option value="0">禁用</option>
          </select>
        </div>
        <button className="btn btn-primary" onClick={fetchTriggers}>查询</button>
        <button className="btn btn-default" onClick={handleAdd}>新增触发器</button>
      </div>

      <div className="batch-table-wrapper">
        <table className="batch-table">
          <thead>
            <tr>
              <th>触发器编码</th>
              <th>触发器名称</th>
              <th>类型</th>
              <th>CRON表达式</th>
              <th>绑定任务组</th>
              <th>状态</th>
              <th>创建时间</th>
              <th>操作</th>
            </tr>
          </thead>
          <tbody>
            {triggers.map(trigger => (
              <tr key={trigger.id}>
                <td><code className="batch-code">{trigger.trigger_code}</code></td>
                <td>{trigger.trigger_name}</td>
                <td><span className="badge-bt badge-bt-cron">{typeText[trigger.trigger_type] || trigger.trigger_type}</span></td>
                <td><code className="batch-code">{trigger.cron_expr || '-'}</code></td>
                <td>{getTaskGroupName(trigger.task_group_id)}</td>
                <td>
                  <span className={`badge-bt ${trigger.status === 1 ? 'badge-bt-enabled' : 'badge-bt-disabled'}`}>
                    {statusText[trigger.status]}
                  </span>
                </td>
                <td>{trigger.create_time?.split('T')[0]}</td>
                <td>
                  <div className="action-btns-bt">
                    <button className="action-btn-bt edit" onClick={() => handleEdit(trigger)}>编辑</button>
                    <button className="action-btn-bt delete" onClick={() => handleDelete(trigger.id)}>删除</button>
                    <button className="action-btn-bt" onClick={() => handleToggle(trigger.id, trigger.status === 1 ? 0 : 1)}>
                      {trigger.status === 1 ? '禁用' : '启用'}
                    </button>
                    {trigger.status === 1 && (
                      <button className="action-btn-bt execute" onClick={() => handleExecute(trigger.id)}>执行</button>
                    )}
                  </div>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      {showModal && (
        <TriggerModal
          trigger={editingTrigger}
          taskGroups={taskGroups}
          onClose={() => setShowModal(false)}
          onSave={handleSave}
        />
      )}
    </div>
  );
}

// 触发器弹窗组件
function TriggerModal({ trigger, taskGroups, onClose, onSave }) {
  const [formData, setFormData] = React.useState({
    trigger_code: "",
    trigger_name: "",
    trigger_type: "CRON",
    cron_expr: "",
    task_group_id: "",
    status: 1,
    remark: ""
  });

  React.useEffect(() => {
    if (trigger) {
      setFormData({
        trigger_code: trigger.trigger_code,
        trigger_name: trigger.trigger_name,
        trigger_type: trigger.trigger_type,
        cron_expr: trigger.cron_expr || "",
        task_group_id: trigger.task_group_id,
        status: trigger.status,
        remark: trigger.remark || ""
      });
    }
  }, [trigger]);

  const handleSubmit = (e) => {
    e.preventDefault();
    onSave(formData);
  };

  return (
    <div className="drawer-backdrop-bt" onClick={onClose}>
      <div className="batch-drawer" onClick={e => e.stopPropagation()}>
        <div className="batch-drawer-header">
          <div>
            <div className="batch-drawer-title">{trigger ? '编辑触发器' : '新增触发器'}</div>
          </div>
          <button className="batch-drawer-close" onClick={onClose}>×</button>
        </div>
        <div className="batch-drawer-body">
          <form onSubmit={handleSubmit}>
            <div className="batch-form-section">
              <div className="batch-form-section-title">基本信息</div>
              <div className="batch-form-grid">
                <div className="batch-form-group">
                  <label>触发器编码 <span className="required">*</span></label>
                  <input
                    type="text"
                    className="input"
                    value={formData.trigger_code}
                    onChange={(e) => setFormData({ ...formData, trigger_code: e.target.value })}
                    required
                    disabled={!!trigger}
                  />
                </div>
                <div className="batch-form-group">
                  <label>触发器名称 <span className="required">*</span></label>
                  <input
                    type="text"
                    className="input"
                    value={formData.trigger_name}
                    onChange={(e) => setFormData({ ...formData, trigger_name: e.target.value })}
                    required
                  />
                </div>
              </div>
              <div className="batch-form-grid">
                <div className="batch-form-group">
                  <label>触发器类型 <span className="required">*</span></label>
                  <select
                    className="input"
                    value={formData.trigger_type}
                    onChange={(e) => setFormData({ ...formData, trigger_type: e.target.value })}
                    required
                  >
                    <option value="CRON">定时触发</option>
                    <option value="MANUAL">手动触发</option>
                    <option value="API">API触发</option>
                    <option value="EVENT">事件触发</option>
                  </select>
                </div>
                <div className="batch-form-group">
                  <label>CRON表达式</label>
                  <input
                    type="text"
                    className="input"
                    value={formData.cron_expr}
                    onChange={(e) => setFormData({ ...formData, cron_expr: e.target.value })}
                    placeholder="0 30 18 * * ?"
                    disabled={formData.trigger_type !== 'CRON'}
                  />
                </div>
              </div>
            </div>
            <div className="batch-form-section">
              <div className="batch-form-section-title">关联配置</div>
              <div className="batch-form-grid">
                <div className="batch-form-group">
                  <label>绑定任务组 <span className="required">*</span></label>
                  <select
                    className="input"
                    value={formData.task_group_id}
                    onChange={(e) => setFormData({ ...formData, task_group_id: parseInt(e.target.value) })}
                    required
                  >
                    <option value="">请选择任务组</option>
                    {taskGroups.map(group => (
                      <option key={group.id} value={group.id}>{group.group_name}</option>
                    ))}
                  </select>
                </div>
                <div className="batch-form-group">
                  <label>状态</label>
                  <select
                    className="input"
                    value={formData.status}
                    onChange={(e) => setFormData({ ...formData, status: parseInt(e.target.value) })}
                  >
                    <option value="1">启用</option>
                    <option value="0">禁用</option>
                  </select>
                </div>
              </div>
            </div>
            <div className="batch-form-section">
              <div className="batch-form-section-title">备注信息</div>
              <div className="batch-form-group">
                <label>备注</label>
                <textarea
                  className="input"
                  rows="3"
                  value={formData.remark}
                  onChange={(e) => setFormData({ ...formData, remark: e.target.value })}
                />
              </div>
            </div>
          </form>
        </div>
        <div className="batch-drawer-footer">
          <button type="button" className="btn btn-ghost" onClick={onClose}>取消</button>
          <button type="submit" className="btn btn-primary" onClick={handleSubmit}>保存</button>
        </div>
      </div>
    </div>
  );
}

// 任务组管理组件
function TaskGroupManagement() {
  const [groups, setGroups] = React.useState([]);
  const [selectedGroup, setSelectedGroup] = React.useState(null);
  const [tasks, setTasks] = React.useState([]);
  const [showGroupModal, setShowGroupModal] = React.useState(false);
  const [showTaskModal, setShowTaskModal] = React.useState(false);
  const [editingGroup, setEditingGroup] = React.useState(null);
  const [editingTask, setEditingTask] = React.useState(null);

  const fetchGroups = async () => {
    try {
      const data = await window.apiFetch('/api/rule/taskGroup/list');
      const groupsData = Array.isArray(data) ? data : (data.items || []);
      setGroups(groupsData);
      if (groupsData.length > 0 && !selectedGroup) {
        setSelectedGroup(groupsData[0]);
      }
    } catch (error) {
      console.error('获取任务组失败:', error);
    }
  };

  const fetchTasks = async (groupId) => {
    if (!groupId) return;
    try {
      const data = await window.apiFetch(`/api/rule/taskDef/list?group_id=${groupId}`);
      setTasks(Array.isArray(data) ? data : (data.items || []));
    } catch (error) {
      console.error('获取子任务失败:', error);
    }
  };

  React.useEffect(() => {
    fetchGroups();
  }, []);

  React.useEffect(() => {
    if (selectedGroup) {
      fetchTasks(selectedGroup.id);
    }
  }, [selectedGroup]);

  const handleAddGroup = () => {
    setEditingGroup(null);
    setShowGroupModal(true);
  };

  const handleEditGroup = (group) => {
    setEditingGroup(group);
    setShowGroupModal(true);
  };

  const handleDeleteGroup = async (id) => {
    if (!confirm('确定要删除该任务组吗？')) return;
    try {
      await window.apiFetch(`/api/rule/taskGroup/delete?id=${id}`, { method: 'DELETE' });
      fetchGroups();
      if (selectedGroup?.id === id) setSelectedGroup(null);
    } catch (error) {
      alert('删除失败: ' + error.message);
    }
  };

  const handleSaveGroup = async (formData) => {
    try {
      if (editingGroup) {
        await window.apiFetch('/api/rule/taskGroup/update', {
          method: 'PUT',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ ...formData, id: editingGroup.id })
        });
      } else {
        await window.apiFetch('/api/rule/taskGroup/add', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(formData)
        });
      }
      setShowGroupModal(false);
      fetchGroups();
    } catch (error) {
      alert('保存失败: ' + error.message);
    }
  };

  const handleAddTask = () => {
    setEditingTask(null);
    setShowTaskModal(true);
  };

  const handleEditTask = (task) => {
    setEditingTask(task);
    setShowTaskModal(true);
  };

  const handleDeleteTask = async (id) => {
    if (!confirm('确定要删除该子任务吗？')) return;
    try {
      await window.apiFetch(`/api/rule/taskDef/delete?id=${id}`, { method: 'DELETE' });
      fetchTasks(selectedGroup.id);
    } catch (error) {
      alert('删除失败: ' + error.message);
    }
  };

  const handleSaveTask = async (formData) => {
    try {
      const data = { ...formData, group_id: selectedGroup.id };
      if (editingTask) {
        await window.apiFetch('/api/rule/taskDef/update', {
          method: 'PUT',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ ...data, id: editingTask.id })
        });
      } else {
        await window.apiFetch('/api/rule/taskDef/add', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(data)
        });
      }
      setShowTaskModal(false);
      fetchTasks(selectedGroup.id);
    } catch (error) {
      alert('保存失败: ' + error.message);
    }
  };

  const typeText = { SEQUENCE: '顺序', PARALLEL: '并行', MIXED: '混合' };
  const taskTypeText = { API: 'API', HTTP: 'HTTP', INNER: '内部' };

  return (
    <div className="task-group-manager">
      <div className="task-group-panel">
        <div className="task-group-list">
          <div className="task-group-list-header">
            <h4>任务组列表</h4>
            <button className="btn btn-sm btn-primary" onClick={handleAddGroup}>+</button>
          </div>
          <div className="task-group-items">
            {groups.map(group => (
              <div 
                key={group.id}
                className={`task-group-item ${selectedGroup?.id === group.id ? 'active' : ''}`}
                onClick={() => setSelectedGroup(group)}
              >
                <span className="task-group-name">{group.group_name}</span>
                <span className="task-group-badge">{typeText[group.group_type]}</span>
              </div>
            ))}
          </div>
        </div>

        <div className="task-panel-detail">
          {selectedGroup ? (
            <>
              <div className="task-panel-header">
                <div className="task-panel-title">
                  <h3>{selectedGroup.group_name}</h3>
                  <div className="task-panel-meta">
                    <span>编码: <code>{selectedGroup.group_code}</code></span>
                    <span>类型: <span className="badge-bt badge-bt-sequence">{typeText[selectedGroup.group_type]}</span></span>
                  </div>
                </div>
                <button className="btn-add-bt" onClick={handleAddTask}>+ 新增子任务</button>
              </div>

              <div className="batch-table-wrapper">
                <table className="batch-table">
                  <thead>
                    <tr>
                      <th style={{ width: '60px' }}>顺序</th>
                      <th>任务编码</th>
                      <th>任务名称</th>
                      <th>类型</th>
                      <th>URL</th>
                      <th>重试</th>
                      <th>超时</th>
                      <th>执行控制</th>
                      <th>操作</th>
                    </tr>
                  </thead>
                  <tbody>
                    {tasks.map(task => (
                      <tr key={task.id}>
                        <td><span className="order-badge">{task.task_order}</span></td>
                        <td><code className="batch-code">{task.task_code}</code></td>
                        <td>{task.task_name}</td>
                        <td><span className="badge-bt badge-bt-cron">{taskTypeText[task.task_type]}</span></td>
                        <td><span className="url-cell" title={task.url}>{task.url || '-'}</span></td>
                        <td>{task.retry_count}次</td>
                        <td>{task.timeout}秒</td>
                        <td>
                          {task.ignore_failure === 1 && <span className="ctrl-tag">忽略失败</span>}
                          {task.forced_execution === 1 && <span className="ctrl-tag ctrl-tag-force">强制执行</span>}
                        </td>
                        <td>
                          <div className="action-btns-bt">
                            <button className="action-btn-bt edit" onClick={() => handleEditTask(task)}>编辑</button>
                            <button className="action-btn-bt delete" onClick={() => handleDeleteTask(task.id)}>删除</button>
                          </div>
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
                {tasks.length === 0 && (
                  <div className="batch-empty small">
                    <div className="batch-empty-icon">📭</div>
                    <h3>暂无子任务</h3>
                    <p>该任务组下暂无子任务</p>
                    <button className="btn btn-primary" onClick={handleAddTask}>添加第一个子任务</button>
                  </div>
                )}
              </div>
            </>
          ) : (
            <div className="batch-empty" style={{ marginTop: '80px' }}>
              <div className="batch-empty-icon">📋</div>
              <h3>请选择任务组</h3>
              <p>请选择或创建一个任务组</p>
              <button className="btn btn-primary" onClick={handleAddGroup}>创建任务组</button>
            </div>
          )}
        </div>
      </div>

      {showGroupModal && (
        <TaskGroupModal
          group={editingGroup}
          onClose={() => setShowGroupModal(false)}
          onSave={handleSaveGroup}
        />
      )}

      {showTaskModal && (
        <TaskDefModal
          task={editingTask}
          groupId={selectedGroup?.id}
          existingTasks={tasks}
          onClose={() => setShowTaskModal(false)}
          onSave={handleSaveTask}
        />
      )}
    </div>
  );
}

// 任务组弹窗组件
function TaskGroupModal({ group, onClose, onSave }) {
  const [formData, setFormData] = React.useState({
    group_code: "",
    group_name: "",
    group_type: "SEQUENCE",
    remark: ""
  });

  React.useEffect(() => {
    if (group) {
      setFormData({
        group_code: group.group_code,
        group_name: group.group_name,
        group_type: group.group_type,
        remark: group.remark || ""
      });
    }
  }, [group]);

  const handleSubmit = (e) => {
    e.preventDefault();
    onSave(formData);
  };

  return (
    <div className="drawer-backdrop-bt" onClick={onClose}>
      <div className="batch-drawer" onClick={e => e.stopPropagation()}>
        <div className="batch-drawer-header">
          <div>
            <div className="batch-drawer-title">{group ? '编辑任务组' : '新增任务组'}</div>
          </div>
          <button className="batch-drawer-close" onClick={onClose}>×</button>
        </div>
        <div className="batch-drawer-body">
          <form onSubmit={handleSubmit}>
            <div className="batch-form-section">
              <div className="batch-form-section-title">基本信息</div>
              <div className="batch-form-grid">
                <div className="batch-form-group">
                  <label>任务组编码 <span className="required">*</span></label>
                  <input
                    type="text"
                    className="input"
                    value={formData.group_code}
                    onChange={(e) => setFormData({ ...formData, group_code: e.target.value })}
                    required
                    disabled={!!group}
                  />
                </div>
                <div className="batch-form-group">
                  <label>任务组名称 <span className="required">*</span></label>
                  <input
                    type="text"
                    className="input"
                    value={formData.group_name}
                    onChange={(e) => setFormData({ ...formData, group_name: e.target.value })}
                    required
                  />
                </div>
              </div>
              <div className="batch-form-group">
                <label>执行类型 <span className="required">*</span></label>
                <select
                  className="input"
                  value={formData.group_type}
                  onChange={(e) => setFormData({ ...formData, group_type: e.target.value })}
                  required
                >
                  <option value="SEQUENCE">顺序执行</option>
                  <option value="PARALLEL">并行执行</option>
                  <option value="MIXED">混合执行</option>
                </select>
              </div>
            </div>
            <div className="batch-form-section">
              <div className="batch-form-section-title">备注信息</div>
              <div className="batch-form-group">
                <label>备注</label>
                <textarea
                  className="input"
                  rows="3"
                  value={formData.remark}
                  onChange={(e) => setFormData({ ...formData, remark: e.target.value })}
                />
              </div>
            </div>
          </form>
        </div>
        <div className="batch-drawer-footer">
          <button type="button" className="btn btn-ghost" onClick={onClose}>取消</button>
          <button type="submit" className="btn btn-primary" onClick={handleSubmit}>保存</button>
        </div>
      </div>
    </div>
  );
}

// 子任务弹窗组件
function TaskDefModal({ task, groupId, existingTasks, onClose, onSave }) {
  const [formData, setFormData] = React.useState({
    task_code: "",
    task_name: "",
    task_type: "API",
    task_order: existingTasks.length + 1,
    url: "",
    method: "POST",
    request_body: "",
    retry_count: 0,
    timeout: 30,
    ignore_failure: 0,
    forced_execution: 0,
    dep_task_ids: [],
    dep_type: "SUCCESS",
    remark: ""
  });

  React.useEffect(() => {
    if (task) {
      setFormData({
        task_code: task.task_code,
        task_name: task.task_name,
        task_type: task.task_type,
        task_order: task.task_order,
        url: task.url || "",
        method: task.method || "POST",
        request_body: task.request_body ? JSON.stringify(task.request_body, null, 2) : "",
        retry_count: task.retry_count,
        timeout: task.timeout,
        ignore_failure: task.ignore_failure,
        forced_execution: task.forced_execution,
        dep_task_ids: task.dep_tasks?.map(t => t.id) || [],
        dep_type: "SUCCESS",
        remark: task.remark || ""
      });
    } else {
      setFormData({
        task_code: "",
        task_name: "",
        task_type: "API",
        task_order: existingTasks.length + 1,
        url: "",
        method: "POST",
        request_body: "",
        retry_count: 0,
        timeout: 30,
        ignore_failure: 0,
        forced_execution: 0,
        dep_task_ids: [],
        dep_type: "SUCCESS",
        remark: ""
      });
    }
  }, [task, existingTasks]);

  const handleSubmit = (e) => {
    e.preventDefault();
    const data = { ...formData };
    if (data.request_body) {
      try {
        data.request_body = JSON.parse(data.request_body);
      } catch {
        data.request_body = null;
      }
    }
    onSave(data);
  };

  const availableTasks = existingTasks.filter(t => t.id !== task?.id);

  return (
    <div className="drawer-backdrop-bt" onClick={onClose}>
      <div className="batch-drawer" onClick={e => e.stopPropagation()}>
        <div className="batch-drawer-header">
          <div>
            <div className="batch-drawer-title">{task ? '编辑子任务' : '新增子任务'}</div>
          </div>
          <button className="batch-drawer-close" onClick={onClose}>×</button>
        </div>
        <div className="batch-drawer-body">
          <form onSubmit={handleSubmit}>
            <div className="batch-form-section">
              <div className="batch-form-section-title">基本信息</div>
              <div className="batch-form-grid">
                <div className="batch-form-group">
                  <label>任务编码 <span className="required">*</span></label>
                  <input
                    type="text"
                    className="input"
                    value={formData.task_code}
                    onChange={(e) => setFormData({ ...formData, task_code: e.target.value })}
                    required
                    disabled={!!task}
                  />
                </div>
                <div className="batch-form-group">
                  <label>任务名称 <span className="required">*</span></label>
                  <input
                    type="text"
                    className="input"
                    value={formData.task_name}
                    onChange={(e) => setFormData({ ...formData, task_name: e.target.value })}
                    required
                  />
                </div>
              </div>
              <div className="batch-form-grid">
                <div className="batch-form-group">
                  <label>任务类型 <span className="required">*</span></label>
                  <select
                    className="input"
                    value={formData.task_type}
                    onChange={(e) => setFormData({ ...formData, task_type: e.target.value })}
                    required
                  >
                    <option value="API">API</option>
                    <option value="HTTP">HTTP</option>
                    <option value="INNER">内部方法</option>
                  </select>
                </div>
                <div className="batch-form-group">
                  <label>执行顺序</label>
                  <input
                    type="number"
                    className="input"
                    value={formData.task_order}
                    onChange={(e) => setFormData({ ...formData, task_order: parseInt(e.target.value) })}
                    min="1"
                  />
                </div>
              </div>
            </div>
            <div className="batch-form-section">
              <div className="batch-form-section-title">请求配置</div>
              <div className="batch-form-grid">
                <div className="batch-form-group">
                  <label>URL/接口地址</label>
                  <input
                    type="text"
                    className="input"
                    value={formData.url}
                    onChange={(e) => setFormData({ ...formData, url: e.target.value })}
                    placeholder="/api/xxx"
                  />
                </div>
                <div className="batch-form-group">
                  <label>请求方法</label>
                  <select
                    className="input"
                    value={formData.method}
                    onChange={(e) => setFormData({ ...formData, method: e.target.value })}
                  >
                    <option value="GET">GET</option>
                    <option value="POST">POST</option>
                    <option value="PUT">PUT</option>
                    <option value="DELETE">DELETE</option>
                  </select>
                </div>
              </div>
              <div className="batch-form-group">
                <label>请求体模板 (JSON)</label>
                <textarea
                  className="input json-editor"
                  rows="5"
                  value={formData.request_body}
                  onChange={(e) => setFormData({ ...formData, request_body: e.target.value })}
                  placeholder='{"instanceCode": "${instanceCode}"}'
                />
              </div>
            </div>
            <div className="batch-form-section">
              <div className="batch-form-section-title">执行策略</div>
              <div className="batch-form-grid">
                <div className="batch-form-group">
                  <label>重试次数</label>
                  <input
                    type="number"
                    className="input"
                    value={formData.retry_count}
                    onChange={(e) => setFormData({ ...formData, retry_count: parseInt(e.target.value) })}
                    min="0"
                    max="10"
                  />
                </div>
                <div className="batch-form-group">
                  <label>超时时间 (秒)</label>
                  <input
                    type="number"
                    className="input"
                    value={formData.timeout}
                    onChange={(e) => setFormData({ ...formData, timeout: parseInt(e.target.value) })}
                    min="1"
                    max="600"
                  />
                </div>
              </div>
              <div className="batch-form-group">
                <label>前置依赖任务</label>
                <div className="checkbox-group">
                  {availableTasks.map(t => (
                    <label key={t.id} className="checkbox-item">
                      <input
                        type="checkbox"
                        checked={formData.dep_task_ids.includes(t.id)}
                        onChange={(e) => {
                          if (e.target.checked) {
                            setFormData({ ...formData, dep_task_ids: [...formData.dep_task_ids, t.id] });
                          } else {
                            setFormData({ ...formData, dep_task_ids: formData.dep_task_ids.filter(id => id !== t.id) });
                          }
                        }}
                      />
                      {t.task_name} ({t.task_code})
                    </label>
                  ))}
                </div>
              </div>
              <div className="batch-form-group">
                <label>依赖条件</label>
                <select
                  className="input"
                  value={formData.dep_type}
                  onChange={(e) => setFormData({ ...formData, dep_type: e.target.value })}
                >
                  <option value="SUCCESS">依赖任务成功</option>
                  <option value="COMPLETED">依赖任务完成</option>
                  <option value="ANY">任意</option>
                </select>
              </div>
              <div className="batch-form-grid">
                <div className="batch-form-group">
                  <div className="checkbox-item">
                    <input
                      type="checkbox"
                      checked={formData.ignore_failure === 1}
                      onChange={(e) => setFormData({ ...formData, ignore_failure: e.target.checked ? 1 : 0 })}
                    />
                    <label>忽略失败 (失败后继续执行)</label>
                  </div>
                </div>
                <div className="batch-form-group">
                  <div className="checkbox-item">
                    <input
                      type="checkbox"
                      checked={formData.forced_execution === 1}
                      onChange={(e) => setFormData({ ...formData, forced_execution: e.target.checked ? 1 : 0 })}
                    />
                    <label>强制执行 (忽略前置状态)</label>
                  </div>
                </div>
              </div>
            </div>
            <div className="batch-form-section">
              <div className="batch-form-section-title">备注信息</div>
              <div className="batch-form-group">
                <label>备注</label>
                <textarea
                  className="input"
                  rows="2"
                  value={formData.remark}
                  onChange={(e) => setFormData({ ...formData, remark: e.target.value })}
                />
              </div>
            </div>
          </form>
        </div>
        <div className="batch-drawer-footer">
          <button type="button" className="btn btn-ghost" onClick={onClose}>取消</button>
          <button type="submit" className="btn btn-primary" onClick={handleSubmit}>保存</button>
        </div>
      </div>
    </div>
  );
}

// 执行监控组件
function TaskMonitor() {
  const [instances, setInstances] = React.useState([]);
  const [selectedInstance, setSelectedInstance] = React.useState(null);
  const [showDetail, setShowDetail] = React.useState(false);
  const [searchParams, setSearchParams] = React.useState({
    status: ""
  });

  const fetchInstances = async () => {
    try {
      const params = new URLSearchParams();
      if (searchParams.status) params.append('status', searchParams.status);
      const data = await window.apiFetch(`/api/rule/taskInstance/list?${params}`);
      setInstances(Array.isArray(data) ? data : (data.items || []));
    } catch (error) {
      console.error('获取执行实例失败:', error);
    }
  };

  const fetchInstanceDetail = async (id) => {
    try {
      const data = await window.apiFetch(`/api/rule/taskInstance/detail?id=${id}`);
      setSelectedInstance(data);
      setShowDetail(true);
    } catch (error) {
      console.error('获取实例详情失败:', error);
    }
  };

  React.useEffect(() => {
    fetchInstances();
    const interval = setInterval(fetchInstances, 5000);
    return () => clearInterval(interval);
  }, [searchParams]);

  const handleTerminate = async (id) => {
    if (!confirm('确定要终止该执行实例吗？')) return;
    try {
      await window.apiFetch(`/api/rule/taskInstance/terminate?id=${id}`, { method: 'POST' });
      fetchInstances();
    } catch (error) {
      alert('终止失败: ' + error.message);
    }
  };

  const handleRetry = async (id) => {
    if (!confirm('确定要重试该执行实例吗？')) return;
    try {
      await window.apiFetch(`/api/rule/taskInstance/retry?id=${id}`, { method: 'POST' });
      fetchInstances();
    } catch (error) {
      alert('重试失败: ' + error.message);
    }
  };

  const statusText = { RUNNING: '运行中', SUCCESS: '成功', FAILED: '失败', TERMINATED: '终止' };

  return (
    <div className="task-monitor">
      <div className="filter-row" style={{ padding: '16px' }}>
        <div className="filter-item">
          <label>状态</label>
          <select 
            className="input"
            value={searchParams.status}
            onChange={(e) => setSearchParams({ ...searchParams, status: e.target.value })}
            style={{ width: 100 }}
          >
            <option value="">全部</option>
            <option value="RUNNING">运行中</option>
            <option value="SUCCESS">成功</option>
            <option value="FAILED">失败</option>
            <option value="TERMINATED">终止</option>
          </select>
        </div>
        <button className="btn btn-primary" onClick={fetchInstances}>刷新</button>
      </div>

      <div className="batch-table-wrapper">
        <table className="batch-table">
          <thead>
            <tr>
              <th>实例编码</th>
              <th>任务组ID</th>
              <th>触发方式</th>
              <th>状态</th>
              <th>开始时间</th>
              <th>结束时间</th>
              <th>进度</th>
              <th>操作</th>
            </tr>
          </thead>
          <tbody>
            {instances.map(instance => {
              const progress = instance.total_count > 0 ? Math.round(((instance.success_count + instance.fail_count) / instance.total_count) * 100) : 0;
              return (
                <tr key={instance.id}>
                  <td><code className="batch-code">{instance.instance_code}</code></td>
                  <td>{instance.group_id}</td>
                  <td><span className="badge-bt badge-bt-cron">{instance.trigger_type}</span></td>
                  <td><span className={`badge-bt ${instance.status === 'SUCCESS' ? 'badge-bt-enabled' : instance.status === 'FAILED' ? 'badge-bt-disabled' : 'badge-bt-running'}`}>{statusText[instance.status]}</span></td>
                  <td>{instance.start_time?.split('T').join(' ')}</td>
                  <td>{instance.end_time?.split('T').join(' ') || '-'}</td>
                  <td>
                    <div className="progress-wrapper">
                      <div className="progress-bar">
                        <div className="progress-fill" style={{ width: `${progress}%` }}></div>
                      </div>
                      <span className="progress-text">{instance.success_count + instance.fail_count}/{instance.total_count}</span>
                    </div>
                  </td>
                  <td>
                    <div className="action-btns-bt">
                      <button className="action-btn-bt" onClick={() => fetchInstanceDetail(instance.id)}>详情</button>
                      {instance.status === 'RUNNING' && (
                        <button className="action-btn-bt delete" onClick={() => handleTerminate(instance.id)}>终止</button>
                      )}
                      {(instance.status === 'FAILED' || instance.status === 'TERMINATED') && (
                        <button className="action-btn-bt execute" onClick={() => handleRetry(instance.id)}>重试</button>
                      )}
                    </div>
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>

      {showDetail && selectedInstance && (
        <InstanceDetailModal
          instance={selectedInstance}
          onClose={() => setShowDetail(false)}
        />
      )}
    </div>
  );
}

// 实例详情弹窗
function InstanceDetailModal({ instance, onClose }) {
  const statusText = { PENDING: '待执行', RUNNING: '运行中', SUCCESS: '成功', FAILED: '失败' };
  const statusColor = { PENDING: 'pending', RUNNING: 'running', SUCCESS: 'success', FAILED: 'failed' };

  const taskLogs = instance.task_logs || [];

  return (
    <div className="drawer-backdrop-bt" onClick={onClose}>
      <div className="batch-drawer" onClick={e => e.stopPropagation()}>
        <div className="batch-drawer-header">
          <div>
            <div className="batch-drawer-title">执行实例详情</div>
          </div>
          <button className="batch-drawer-close" onClick={onClose}>×</button>
        </div>
        <div className="batch-drawer-body">
          <div className="detail-header">
            <div className="detail-info">
              <span className="detail-code">{instance.instance_code}</span>
              <span className={`badge-bt ${instance.status === 'SUCCESS' ? 'badge-bt-enabled' : instance.status === 'FAILED' ? 'badge-bt-disabled' : 'badge-bt-running'}`}>{instance.status}</span>
            </div>
            <div className="detail-meta">
              <span>开始时间: {instance.start_time?.split('T').join(' ')}</span>
              <span>结束时间: {instance.end_time?.split('T').join(' ') || '-'}</span>
            </div>
          </div>

          <div className="progress-section">
            <h4>执行进度</h4>
            <div className="stats-section">
              <div className="stat-item">
                <span className="stat-label">总任务</span>
                <span className="stat-value">{instance.total_count}</span>
              </div>
              <div className="stat-item success">
                <span className="stat-label">成功</span>
                <span className="stat-value">{instance.success_count}</span>
              </div>
              <div className="stat-item failed">
                <span className="stat-label">失败</span>
                <span className="stat-value">{instance.fail_count}</span>
              </div>
            </div>
          </div>

          <div className="workflow-steps">
            {taskLogs.map(log => (
              <div key={log.id} className={`workflow-step ${statusColor[log.status]}`}>
                <div className="step-number">{taskLogs.indexOf(log) + 1}</div>
                <div className="step-content">
                  <div className="step-header">
                    <span className="step-name">{log.task_name || log.task_code}</span>
                    <div className="step-info">
                      <span>{log.start_time?.split('T').join(' ') || '-'}</span>
                      {log.end_time && <span>耗时: {log.elapsed || 0}ms</span>}
                    </div>
                  </div>
                  {log.error_msg && (
                    <div className="step-error">
                      <span className="error-label">错误信息</span>
                      <p className="error-content">{log.error_msg}</p>
                    </div>
                  )}
                </div>
              </div>
            ))}
          </div>

          {instance.context_data && (
            <div className="context-section">
              <h4>上下文数据</h4>
              <pre className="context-data">{JSON.stringify(instance.context_data, null, 2)}</pre>
            </div>
          )}
        </div>
        <div className="batch-drawer-footer">
          <button type="button" className="btn btn-ghost" onClick={onClose}>关闭</button>
        </div>
      </div>
    </div>
  );
}

// 任务日志组件
function TaskLogs() {
  const [logs, setLogs] = React.useState([]);
  const [selectedLog, setSelectedLog] = React.useState(null);
  const [showDetail, setShowDetail] = React.useState(false);
  const [searchParams, setSearchParams] = React.useState({
    taskCode: "",
    status: ""
  });

  const fetchLogs = async () => {
    try {
      const params = new URLSearchParams();
      if (searchParams.taskCode) params.append('task_code', searchParams.taskCode);
      if (searchParams.status) params.append('status', searchParams.status);
      const data = await window.apiFetch(`/api/rule/taskLog/list?${params}`);
      setLogs(Array.isArray(data) ? data : (data.items || []));
    } catch (error) {
      console.error('获取任务日志失败:', error);
    }
  };

  const fetchLogDetail = async (id) => {
    try {
      const data = await window.apiFetch(`/api/rule/taskLog/detail?id=${id}`);
      setSelectedLog(data);
      setShowDetail(true);
    } catch (error) {
      console.error('获取日志详情失败:', error);
    }
  };

  React.useEffect(() => {
    fetchLogs();
  }, []);

  const statusText = { PENDING: '待执行', RUNNING: '运行中', SUCCESS: '成功', FAILED: '失败' };

  return (
    <div className="task-log">
      <div className="filter-row" style={{ padding: '16px' }}>
        <div className="filter-item">
          <label>任务编码</label>
          <input
            type="text"
            className="input"
            value={searchParams.taskCode}
            onChange={(e) => setSearchParams({ ...searchParams, taskCode: e.target.value })}
            placeholder="请输入任务编码"
            style={{ width: 160 }}
          />
        </div>
        <div className="filter-item">
          <label>状态</label>
          <select 
            className="input"
            value={searchParams.status}
            onChange={(e) => setSearchParams({ ...searchParams, status: e.target.value })}
            style={{ width: 100 }}
          >
            <option value="">全部</option>
            <option value="SUCCESS">成功</option>
            <option value="FAILED">失败</option>
          </select>
        </div>
        <button className="btn btn-primary" onClick={fetchLogs}>查询</button>
      </div>

      <div className="batch-table-wrapper">
        <table className="batch-table">
          <thead>
            <tr>
              <th>ID</th>
              <th>实例编码</th>
              <th>任务名称</th>
              <th>任务编码</th>
              <th>状态</th>
              <th>开始时间</th>
              <th>结束时间</th>
              <th>耗时</th>
              <th>重试</th>
              <th>操作</th>
            </tr>
          </thead>
          <tbody>
            {logs.map(log => (
              <tr key={log.id}>
                <td>{log.id}</td>
                <td><code className="batch-code">{log.instance_code || '-'}</code></td>
                <td>{log.task_name || '-'}</td>
                <td><code className="batch-code">{log.task_code}</code></td>
                <td><span className={`badge-bt ${log.status === 'SUCCESS' ? 'badge-bt-enabled' : 'badge-bt-disabled'}`}>{statusText[log.status]}</span></td>
                <td>{log.start_time?.split('T').join(' ')}</td>
                <td>{log.end_time?.split('T').join(' ') || '-'}</td>
                <td>{log.elapsed || 0}ms</td>
                <td>{log.retry_times}次</td>
                <td>
                  <button className="action-btn-bt" onClick={() => fetchLogDetail(log.id)}>详情</button>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      {showDetail && selectedLog && (
        <LogDetailModal
          log={selectedLog}
          onClose={() => setShowDetail(false)}
        />
      )}
    </div>
  );
}

// 日志详情弹窗
function LogDetailModal({ log, onClose }) {
  return (
    <div className="drawer-backdrop-bt" onClick={onClose}>
      <div className="batch-drawer" onClick={e => e.stopPropagation()}>
        <div className="batch-drawer-header">
          <div>
            <div className="batch-drawer-title">日志详情</div>
          </div>
          <button className="batch-drawer-close" onClick={onClose}>×</button>
        </div>
        <div className="batch-drawer-body">
          <div className="log-detail">
            <div className="detail-row">
              <div className="detail-label">日志ID</div>
              <div className="detail-value">{log.id}</div>
            </div>
            <div className="detail-row">
              <div className="detail-label">实例编码</div>
              <div className="detail-value"><code>{log.instance_code || '-'}</code></div>
            </div>
            <div className="detail-row">
              <div className="detail-label">任务名称</div>
              <div className="detail-value">{log.task_name || '-'}</div>
            </div>
            <div className="detail-row">
              <div className="detail-label">任务编码</div>
              <div className="detail-value"><code>{log.task_code}</code></div>
            </div>
            <div className="detail-row">
              <div className="detail-label">状态</div>
              <div className="detail-value"><span className={`badge-bt ${log.status === 'SUCCESS' ? 'badge-bt-enabled' : 'badge-bt-disabled'}`}>{log.status}</span></div>
            </div>
            <div className="detail-row">
              <div className="detail-label">开始时间</div>
              <div className="detail-value">{log.start_time?.split('T').join(' ')}</div>
            </div>
            <div className="detail-row">
              <div className="detail-label">结束时间</div>
              <div className="detail-value">{log.end_time?.split('T').join(' ') || '-'}</div>
            </div>
            <div className="detail-row">
              <div className="detail-label">耗时</div>
              <div className="detail-value">{log.elapsed || 0}ms</div>
            </div>
            <div className="detail-row">
              <div className="detail-label">重试次数</div>
              <div className="detail-value">{log.retry_times}次</div>
            </div>

            {log.request_data && (
              <div className="detail-section">
                <h4>请求数据</h4>
                <pre className="json-preview">{JSON.stringify(log.request_data, null, 2)}</pre>
              </div>
            )}

            {log.response_data && (
              <div className="detail-section">
                <h4>响应数据</h4>
                <pre className="json-preview">{JSON.stringify(log.response_data, null, 2)}</pre>
              </div>
            )}

            {log.error_msg && (
              <div className="detail-section error">
                <h4>错误信息</h4>
                <pre className="error-preview">{log.error_msg}</pre>
              </div>
            )}
          </div>
        </div>
        <div className="batch-drawer-footer">
          <button type="button" className="btn btn-ghost" onClick={onClose}>关闭</button>
        </div>
      </div>
    </div>
  );
}
