<% @page_title = '设备管理 - 清巡' %>
<% @active_page = 'devices' %>

<style>
.test-result-container {
  padding: 0 20px;
}

.test-status {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px;
  margin-bottom: 20px;
  border-radius: 8px;
  font-weight: bold;
}

.test-status.status-online {
  background: #f0f9eb;
  color: #67C23A;
}

.test-status.status-error,
.test-status.status-timeout,
.test-status.status-refused,
.test-status.status-unreachable {
  background: #fef0f0;
  color: #F56C6C;
}

.status-icon {
  font-size: 24px;
}

.login-log {
  background: #1e1e1e;
  color: #d4d4d4;
  padding: 16px;
  border-radius: 8px;
  font-family: monospace;
  font-size: 13px;
  max-height: 60vh;
  overflow-y: auto;
}

.login-log pre {
  margin: 0;
  white-space: pre-wrap;
  word-break: break-all;
}

.loading-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 60px 20px;
  color: #909399;
}

.loading-container p {
  margin-top: 12px;
}
</style>

  <div id="app">
    <div class="app-wrapper">
      
      <main class="main-content">
        <div class="page-header">
          <h1>设备管理</h1>
          <div>
            <el-button type="warning" @click="openExecuteDialog" :disabled="selectedDevices.length === 0">
              <span>执行脚本</span>
            </el-button>
            <el-button type="success" @click="syncDevices" :loading="syncLoading">
              <span>同步到云端</span>
            </el-button>
            <el-button type="primary" @click="goToAdd">添加设备</el-button>
            <el-button @click="goToImport">导入设备</el-button>
            <el-button @click="exportDevices">导出设备</el-button>
          </div>
        </div>
        
        <el-card class="card">
          <div class="card-body">
            <el-table :data="devices" stripe style="width: 100%" v-loading="loading" @selection-change="handleSelectionChange">
              <el-table-column type="selection" width="55"></el-table-column>
              <el-table-column prop="name" label="设备名称" min-width="150"></el-table-column>
              <el-table-column prop="device_model" label="设备型号" width="150"></el-table-column>
              <el-table-column prop="ip_address" label="IP地址" width="140"></el-table-column>
              <el-table-column prop="port" label="端口" width="80" align="center"></el-table-column>
              <el-table-column prop="connection_type" label="连接类型" width="100">
                <template #default="scope">
                  <el-tag size="small">{{ scope.row.connection_type }}</el-tag>
                </template>
              </el-table-column>
              <el-table-column label="状态" width="80" align="center">
                <template #default="scope">
                  <span v-if="scope.row.test_status === 'online'" style="color: #67C23A;">● 在线</span>
                  <span v-else-if="scope.row.test_status" style="color: #F56C6C;">● 离线</span>
                  <span v-else style="color: #909399;">-</span>
                </template>
              </el-table-column>
              <el-table-column prop="username" label="用户名" width="120"></el-table-column>
              <el-table-column prop="description" label="描述" min-width="150" show-overflow-tooltip></el-table-column>
              <el-table-column label="操作" width="240" fixed="right">
                <template #default="scope">
                  <el-button type="primary" size="small" link @click="editDevice(scope.row.id)">编辑</el-button>
                  <el-button type="success" size="small" link @click="testConnection(scope.row.id)">测试</el-button>
                  <el-button type="warning" size="small" link @click="executeOnDevice(scope.row)">执行</el-button>
                  <el-button type="danger" size="small" link @click="deleteDevice(scope.row)">删除</el-button>
                </template>
              </el-table-column>
            </el-table>
            
            <div class="empty-state" v-if="!loading && devices.length === 0" style="text-align: center; padding: 60px 20px; color: #909399;">
              <div style="font-size: 64px; margin-bottom: 20px;">💻</div>
              <p>暂无设备</p>
            </div>
          </div>
        </el-card>

        <!-- 连通性测试结果对话框 -->
        <el-dialog
          v-model="testConnectionDialogVisible"
          title="连通性测试"
          width="600px"
          :close-on-click-modal="false"
          destroy-on-close
        >
          <div v-if="testLoading" class="loading-container">
            <el-icon class="is-loading" size="32"><Loading /></el-icon>
            <p>正在测试连接，请稍候...</p>
          </div>
          <div v-else-if="testResult" class="test-result-container">
            <div class="test-status" :class="'status-' + testResult.status">
              <span class="status-icon">{{ testResult.status === 'online' ? '✓' : '✗' }}</span>
              <span class="status-text">{{ testResult.protocol }} - {{ testResult.message }}</span>
            </div>
            <div class="login-log">
              <pre>{{ formatLoginSteps(testResult.login_steps) }}</pre>
            </div>
          </div>
        </el-dialog>

        <!-- 执行脚本对话框 -->
        <el-dialog
          v-model="executeDialogVisible"
          title="执行脚本"
          width="700px"
          :close-on-click-modal="false"
        >
          <div v-if="executeLoading" class="loading-container">
            <el-icon class="is-loading" size="32"><Loading /></el-icon>
            <p>正在同步脚本，请稍候...</p>
          </div>
          <div v-else>
            <p style="margin-bottom: 16px;">已选择 <strong>{{ selectedDevices.length }}</strong> 个设备</p>
            <table style="width:100%;border-collapse:collapse;">
              <thead>
                <tr style="background:#f5f7fa;">
                  <th style="padding:12px 8px;text-align:left;">脚本名称</th>
                  <th style="padding:12px 8px;text-align:left;">描述</th>
                  <th style="padding:12px 8px;text-align:left;">匹配型号</th>
                  <th style="padding:12px 8px;width:80px;">操作</th>
                </tr>
              </thead>
              <tbody>
                <tr v-for="s in getFilteredScripts()" :key="s.id" style="border-bottom:1px solid #ebeef5;">
                  <td style="padding:12px 8px;">{{ s.name }}</td>
                  <td style="padding:12px 8px;color:#666;">{{ s.description }}</td>
                  <td style="padding:12px 8px;color:#999;">{{ s.device_model_pattern }}</td>
                  <td style="padding:12px 8px;">
                    <button @click="executeSingleScript(s)" style="background:#409eff;color:#fff;border:none;padding:6px 12px;border-radius:4px;cursor:pointer;">执行</button>
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
          <template #footer>
            <el-button @click="executeDialogVisible = false">取消</el-button>
            <el-button type="primary" @click="executeScripts" :loading="executeRunning" :disabled="selectedScripts.length === 0">
              执行 ({{ selectedScripts.length }} 个脚本)
            </el-button>
          </template>
        </el-dialog>
      </main>
    </div>
    
    <!-- 添加/编辑设备对话框 -->
    <el-dialog 
      v-model="editDialogVisible" 
      :title="isEditMode ? '编辑设备' : '添加设备'" 
      width="600px"
      :close-on-click-modal="false"
      destroy-on-close
    >
      <el-form 
        :model="editForm" 
        label-width="100px" 
        v-loading="editLoading"
        :rules="editRules"
        ref="editFormRef"
      >
        <el-form-item label="设备名称" prop="name">
          <el-input v-model="editForm.name" placeholder="请输入设备名称"></el-input>
        </el-form-item>
        
        <el-form-item label="设备型号" prop="device_model">
          <el-input v-model="editForm.device_model" placeholder="请输入设备型号"></el-input>
        </el-form-item>
        
        <el-form-item label="IP地址" prop="ip_address">
          <el-input v-model="editForm.ip_address" placeholder="请输入IP地址"></el-input>
        </el-form-item>
        
        <el-form-item label="端口" prop="port">
          <el-input-number v-model="editForm.port" :min="1" :max="65535" style="width: 100%"></el-input-number>
        </el-form-item>
        
        <el-form-item label="连接类型" prop="connection_type">
          <el-select v-model="editForm.connection_type" placeholder="请选择连接类型" style="width: 100%">
            <el-option label="Telnet" value="telnet"></el-option>
            <el-option label="SSH" value="ssh"></el-option>
          </el-select>
        </el-form-item>
        
        <el-form-item label="用户名" prop="username">
          <el-input v-model="editForm.username" placeholder="请输入用户名"></el-input>
        </el-form-item>
        
        <el-form-item label="密码" prop="password">
          <el-input 
            v-model="editForm.password" 
            type="password" 
            show-password
            :placeholder="editForm.has_password ? '留空则保持不变' : '请输入密码'"
          ></el-input>
        </el-form-item>
        
        <el-form-item label="Enable命令" prop="enable_command">
          <el-input v-model="editForm.enable_command" placeholder="请输入enable命令（可选）"></el-input>
        </el-form-item>
        
        <el-form-item label="Enable密码" prop="enable_password">
          <el-input
            v-model="editForm.enable_password"
            type="password"
            show-password
            :placeholder="editForm.has_enable_password ? '留空则保持不变' : '请输入enable密码（可选）'"
          ></el-input>
        </el-form-item>

        <el-form-item label="Root密码" prop="root_password">
          <el-input
            v-model="editForm.root_password"
            type="password"
            show-password
            :placeholder="editForm.has_root_password ? '留空则保持不变' : '请输入root密码（可选）'"
          ></el-input>
        </el-form-item>

        <el-form-item label="描述" prop="description">
          <el-input 
            v-model="editForm.description" 
            type="textarea" 
            :rows="3"
            placeholder="请输入描述（可选）"
          ></el-input>
        </el-form-item>
      </el-form>
      
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="editDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="saveDevice" :loading="saveLoading">保存</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
  
  <% content_for :xxx do %>
  <script>
    const { createApp, ref, reactive, onMounted } = Vue;
    const app = createApp({
      setup() {
        const devices = ref([]);
        const loading = ref(true);
        const syncLoading = ref(false);
        const editDialogVisible = ref(false);
        const editLoading = ref(false);
        const saveLoading = ref(false);
        const editFormRef = ref(null);
        const currentDeviceId = ref(null);
        const isEditMode = ref(false);

        // 连通性测试相关变量
        const testConnectionDialogVisible = ref(false);
        const testLoading = ref(false);
        const testResult = ref(null);

        // 执行脚本相关变量
        const executeDialogVisible = ref(false);
        const executeLoading = ref(false);
        const executeRunning = ref(false);
        const selectedDevices = ref([]);
        const scripts = ref([]);
        const selectedScripts = ref([]);
        const scriptFilter = ref('');

        const editForm = reactive({
          name: '',
          device_model: '',
          ip_address: '',
          port: 23,
          connection_type: 'telnet',
          username: '',
          password: '',
          has_password: false,
          enable_command: '',
          enable_password: '',
          has_enable_password: false,
          root_password: '',
          has_root_password: false,
          description: ''
        });
        
        const editRules = {
          name: [{ required: true, message: '请输入设备名称', trigger: 'blur' }],
          ip_address: [{ required: true, message: '请输入IP地址', trigger: 'blur' }],
          port: [{ required: true, message: '请输入端口', trigger: 'blur' }],
          connection_type: [{ required: true, message: '请选择连接类型', trigger: 'change' }]
        };

        // 连通性测试辅助函数
        const formatLoginSteps = (steps) => {
          if (!steps || steps.length === 0) return '无登录记录';
          return steps.map(step => {
            let line = `[${step.timestamp}] ${step.step}`;
            if (step.details) {
              if (step.details.host) line += ` (${step.details.host}:${step.details.port})`;
              if (step.details.username) line += `\n  用户名: ${step.details.username}`;
              if (step.details.response) line += `\n  响应: ${step.details.response}`;
              if (step.details.error) line += `\n  错误: ${step.details.error}`;
              if (step.details.enable_command) line += `\n  命令: ${step.details.enable_command}`;
            }
            return line;
          }).join('\n');
        };

        const handleSelectionChange = (selection) => {
          selectedDevices.value = selection;
        };

        const resetEditForm = () => {
          Object.assign(editForm, {
            name: '',
            device_model: '',
            ip_address: '',
            port: 23,
            connection_type: 'telnet',
            username: '',
            password: '',
            has_password: false,
            enable_command: '',
            enable_password: '',
            has_enable_password: false,
            root_password: '',
            has_root_password: false,
            description: ''
          });
          currentDeviceId.value = null;
          isEditMode.value = false;
        };
        
        const fetchDevices = async () => {
          loading.value = true;
          try {
            const response = await fetch('/api/devices');
            devices.value = await response.json();
          } catch (error) {
            ElementPlus.ElMessage.error('获取设备列表失败');
          } finally {
            loading.value = false;
          }
        };
        
        const goToAdd = () => {
          isEditMode.value = false;
          resetEditForm();
          editDialogVisible.value = true;
        };
        
        const goToImport = () => {
          ElementPlus.ElMessage.info('导入功能待实现');
        };
        
        const editDevice = async (id) => {
          isEditMode.value = true;
          currentDeviceId.value = id;
          editLoading.value = true;
          try {
            const response = await fetch(`/api/devices/${id}`);
            const device = await response.json();
            Object.assign(editForm, {
              name: device.name || '',
              device_model: device.device_model || '',
              ip_address: device.ip_address || '',
              port: device.port || 23,
              connection_type: device.connection_type || 'telnet',
              username: device.username || '',
              password: '',
              has_password: device.has_password || false,
              enable_command: device.enable_command || '',
              enable_password: '',
              has_enable_password: device.has_enable_password || false,
              root_password: '',
              has_root_password: device.has_root_password || false,
              description: device.description || ''
            });
            editDialogVisible.value = true;
          } catch (error) {
            ElementPlus.ElMessage.error('获取设备信息失败');
          } finally {
            editLoading.value = false;
          }
        };
        
        const saveDevice = async () => {
          if (!editFormRef.value) return;
          
          try {
            await editFormRef.value.validate();
          } catch {
            return;
          }
          
          saveLoading.value = true;
          try {
            const url = isEditMode.value ? `/api/devices/${currentDeviceId.value}` : '/api/devices';
            const method = isEditMode.value ? 'PUT' : 'POST';
            
            const response = await fetch(url, {
              method: method,
              headers: {
                'Content-Type': 'application/json',
              },
              body: JSON.stringify(editForm)
            });
            
            const result = await response.json();
            
            if (result.success) {
              ElementPlus.ElMessage.success(isEditMode.value ? '设备更新成功' : '设备添加成功');
              editDialogVisible.value = false;
              fetchDevices();
            } else {
              ElementPlus.ElMessage.error(result.error || '操作失败');
            }
          } catch (error) {
            ElementPlus.ElMessage.error('网络错误');
          } finally {
            saveLoading.value = false;
          }
        };
        
        const deleteDevice = async (device) => {
          try {
            await ElementPlus.ElMessageBox.confirm(
              `确定要删除设备 "${device.name}" 吗？`,
              '删除确认',
              {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
              }
            );
            
            const response = await fetch(`/api/devices/${device.id}`, {
              method: 'DELETE'
            });
            
            const result = await response.json();
            
            if (result.success) {
              ElementPlus.ElMessage.success('设备删除成功');
              fetchDevices();
            } else {
              ElementPlus.ElMessage.error(result.error || '删除失败');
            }
          } catch (error) {
            if (error !== 'cancel') {
              ElementPlus.ElMessage.error('删除失败');
            }
          }
        };
        
        // 测试单个设备连接
        const testConnection = async (id) => {
          testConnectionDialogVisible.value = true;
          testLoading.value = true;
          testResult.value = null;

          try {
            const response = await fetch(`/api/devices/${id}/test_connection`, {
              method: 'POST',
              headers: { 'Content-Type': 'application/json' },
              body: JSON.stringify({ timeout: 30 })
            });

            const result = await response.json();

            if (result.success) {
              testResult.value = result;
              // 更新设备列表中的状态
              const device = devices.value.find(d => d.id === id);
              if (device) {
                device.test_status = result.status;
                device.test_message = result.message;
              }
            } else {
              ElementPlus.ElMessage.error(result.error || '测试失败');
              testConnectionDialogVisible.value = false;
            }
          } catch (error) {
            ElementPlus.ElMessage.error('网络错误: ' + error.message);
            testConnectionDialogVisible.value = false;
          } finally {
            testLoading.value = false;
          }
        };

        // 批量测试设备连接（预留扩展）
        const testConnections = async (ids) => {
          for (const id of ids) {
            await testConnection(id);
          }
        };

        // 执行脚本相关函数
        const getFilteredScripts = () => {
          console.log('getFilteredScripts:', scripts.value);
          if (!scriptFilter.value) return scripts.value;
          const keyword = scriptFilter.value.toLowerCase();
          return scripts.value.filter(s =>
            s.name.toLowerCase().includes(keyword) ||
            (s.description && s.description.toLowerCase().includes(keyword))
          );
        };

        const openExecuteDialog = async () => {
          console.log('openExecuteDialog 开始');
          executeDialogVisible.value = true;
          executeLoading.value = true;
          selectedScripts.value = [];
          console.log('executeDialogVisible 已设置');

          try {
            // 同步脚本
            const syncResponse = await fetch('/api/device-scripts/sync', {
              method: 'POST',
              headers: { 'Content-Type': 'application/json' }
            });
            const syncResult = await syncResponse.json();
            console.log('脚本同步结果:', syncResult);

            // 获取脚本列表
            const listResponse = await fetch('/api/device-scripts/list');
            const scriptsData = await listResponse.json();
            scripts.value = JSON.parse(JSON.stringify(scriptsData));
            console.log('获取到脚本:', scripts.value);

            if (scripts.value.length === 0) {
              ElementPlus.ElMessage.warning('云端没有可用的脚本');
            } else {
              ElementPlus.ElMessage.success(`已加载 ${scripts.value.length} 个脚本`);
            }
          } catch (error) {
            ElementPlus.ElMessage.error('同步脚本失败: ' + error.message);
          } finally {
            executeLoading.value = false;
            console.log('executeLoading 已设为 false');
          }
        };

        // 对单个设备执行脚本
        const executeOnDevice = async (device) => {
          selectedDevices.value = [device];
          await openExecuteDialog();
        };

        const handleScriptSelectionChange = (selection) => {
          selectedScripts.value = selection;
        };

        const executeScripts = async () => {
          if (selectedDevices.value.length === 0) {
            ElementPlus.ElMessage.warning('请选择设备');
            return;
          }
          if (selectedScripts.value.length === 0) {
            ElementPlus.ElMessage.warning('请选择脚本');
            return;
          }

          executeRunning.value = true;
          try {
            const deviceIds = selectedDevices.value.map(d => d.id);
            const scriptIds = selectedScripts.value.map(s => s.id);

            const response = await fetch('/api/device-scripts/execute', {
              method: 'POST',
              headers: { 'Content-Type': 'application/json' },
              body: JSON.stringify({
                device_ids: deviceIds,
                script_ids: scriptIds
              })
            });

            const result = await response.json();

            if (result.success) {
              ElementPlus.ElMessage.success('任务已创建并开始执行');
              executeDialogVisible.value = false;
              window.location.href = `/tasks/${result.task_id}/vue`;
            } else {
              ElementPlus.ElMessage.error(result.error || '执行失败');
            }
          } catch (error) {
            ElementPlus.ElMessage.error('执行失败: ' + error.message);
          } finally {
            executeRunning.value = false;
          }
        };

        const executeSingleScript = async (script) => {
          if (selectedDevices.value.length === 0) {
            ElementPlus.ElMessage.warning('请选择设备');
            return;
          }

          executeRunning.value = true;
          try {
            const deviceIds = selectedDevices.value.map(d => d.id);

            const response = await fetch('/api/device-scripts/execute', {
              method: 'POST',
              headers: { 'Content-Type': 'application/json' },
              body: JSON.stringify({
                device_ids: deviceIds,
                script_ids: [script.id]
              })
            });

            const result = await response.json();

            if (result.success) {
              ElementPlus.ElMessage.success('任务已创建并开始执行');
              executeDialogVisible.value = false;
              window.location.href = `/tasks/${result.task_id}/vue`;
            } else {
              ElementPlus.ElMessage.error(result.error || '执行失败');
            }
          } catch (error) {
            ElementPlus.ElMessage.error('执行失败: ' + error.message);
          } finally {
            executeRunning.value = false;
          }
        };

        const exportDevices = () => {
          ElementPlus.ElMessage.info('导出功能待实现');
        };

        const syncDevices = async () => {
          syncLoading.value = true;
          try {
            const response = await fetch('/api/devices/sync', {
              method: 'POST',
              headers: {
                'Content-Type': 'application/json'
              }
            });
            const result = await response.json();
            console.log('同步响应:', result);
            if (result.success || response.ok) {
              const synced = result.synced || (result.data && result.data.synced) || 0;
              const errors = result.errors || (result.data && result.data.errors) || 0;
              ElementPlus.ElMessage.success(
                `同步成功：成功 ${synced} 个设备${errors > 0 ? '，失败 ' + errors + ' 个' : ''}`
              );
            } else {
              ElementPlus.ElMessage.error(result.error || '同步失败');
            }
          } catch (error) {
            console.error('同步异常:', error);
            ElementPlus.ElMessage.error('网络错误: ' + error.message);
          } finally {
            syncLoading.value = false;
          }
        };
        
        onMounted(() => {
          fetchDevices();
        });
        
        return {
          devices,
          loading,
          syncLoading,
          editDialogVisible,
          editLoading,
          saveLoading,
          editFormRef,
          editForm,
          editRules,
          isEditMode,
          fetchDevices,
          goToAdd,
          goToImport,
          editDevice,
          saveDevice,
          deleteDevice,
          testConnection,
          exportDevices,
          syncDevices,
          testConnectionDialogVisible,
          testLoading,
          testResult,
          testConnection,
          testConnections,
          formatLoginSteps,
          handleSelectionChange,
          executeDialogVisible,
          executeLoading,
          executeRunning,
          selectedDevices,
          scripts,
          selectedScripts,
          scriptFilter,
          getFilteredScripts,
          openExecuteDialog,
          executeOnDevice,
          handleScriptSelectionChange,
          executeScripts,
          executeSingleScript
        };
      }
    });
    app.use(ElementPlus);
  app.mount('#app');
  </script>
<% end %>
