<template>
  <el-dialog v-model="visibleProxy" title="注册节点详情" width="70%" append-to-body :close-on-click-modal="false">
    <div v-loading="loading">
      <el-descriptions :column="2" border class="mb-4">
        <el-descriptions-item label="执行器名称">{{ executorData?.title }}</el-descriptions-item>
        <el-descriptions-item label="AppName">{{ executorData?.appname }}</el-descriptions-item>
        <el-descriptions-item label="注册方式">
          <el-tag :type="executorData?.addressType === 0 ? 'success' : 'info'">
            {{ executorData?.addressType === 0 ? '自动注册' : '手动录入' }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="更新时间">{{ proxy.parseTime(executorData?.updateTime) }}</el-descriptions-item>
      </el-descriptions>

      <div class="registry-section">
        <div class="section-header">
          <h4>在线机器地址</h4>
          <el-button type="primary" size="small" icon="Refresh" @click="refreshRegistry">刷新</el-button>
        </div>

        <div v-if="onlineNodes.length > 0" class="node-list">
          <div v-for="node in onlineNodes" :key="node.address" class="node-item online">
            <div class="node-info">
              <div class="node-address">
                <el-icon class="status-icon">
                  <CircleCheckFilled />
                </el-icon>
                {{ node.address }}
              </div>
              <div class="node-status">
                <span class="status-text">在线</span>
                <span class="heartbeat-time">最后心跳: {{ proxy.parseTime(node.lastHeartbeat) }}</span>
              </div>
            </div>
            <div class="node-actions">
              <el-button size="small" type="primary" @click="testConnection(node.address)">连接测试</el-button>
            </div>
          </div>
        </div>
        <el-empty v-else description="暂无在线节点" :image-size="100" />
      </div>

      <div class="registry-section" v-if="offlineNodes.length > 0">
        <div class="section-header">
          <h4>离线机器地址</h4>
        </div>

        <div class="node-list">
          <div v-for="node in offlineNodes" :key="node.address" class="node-item offline">
            <div class="node-info">
              <div class="node-address">
                <el-icon class="status-icon">
                  <CircleCloseFilled />
                </el-icon>
                {{ node.address }}
              </div>
              <div class="node-status">
                <span class="status-text">离线</span>
                <span class="heartbeat-time">最后心跳: {{ proxy.parseTime(node.lastHeartbeat) }}</span>
              </div>
            </div>
            <div class="node-actions">
              <el-button size="small" type="danger" plain @click="removeOfflineNode(node.address)">移除</el-button>
            </div>
          </div>
        </div>
      </div>

      <!-- 统计信息 -->
      <div class="stats-section">
        <el-row :gutter="20">
          <el-col :span="8">
            <el-statistic title="总节点数" :value="totalNodes" />
          </el-col>
          <el-col :span="8">
            <el-statistic title="在线节点" :value="onlineNodes.length">
              <template #suffix>
                <el-icon style="vertical-align: -0.125em; color: #67c23a">
                  <CircleCheckFilled />
                </el-icon>
              </template>
            </el-statistic>
          </el-col>
          <el-col :span="8">
            <el-statistic title="离线节点" :value="offlineNodes.length">
              <template #suffix>
                <el-icon style="vertical-align: -0.125em; color: #f56c6c">
                  <CircleCloseFilled />
                </el-icon>
              </template>
            </el-statistic>
          </el-col>
        </el-row>
      </div>
    </div>
  </el-dialog>
</template>

<script setup lang="ts">
import { getExecutorRegistry, checkExecutorStatus } from '@/api/xxljob/executor';
import { JobGroupVO, ExecutorStatus } from '@/api/xxljob/executor/types';
import { CircleCheckFilled, CircleCloseFilled } from '@element-plus/icons-vue';

const props = defineProps({
  visible: {
    type: Boolean,
    default: false
  },
  executorData: {
    type: Object as PropType<JobGroupVO | null>,
    default: null
  }
});

const emit = defineEmits(['update:visible']);

const { proxy } = getCurrentInstance() as ComponentInternalInstance;

// 可见性的双向绑定
const visibleProxy = computed({
  get: () => props.visible,
  set: (val) => emit('update:visible', val)
});

const loading = ref(false);
const onlineNodes = ref<ExecutorStatus[]>([]);
const offlineNodes = ref<ExecutorStatus[]>([]);

const totalNodes = computed(() => onlineNodes.value.length + offlineNodes.value.length);

/** 刷新注册信息 */
const refreshRegistry = async () => {
  if (!props.executorData) return;

  loading.value = true;
  try {
    // 获取注册地址列表
    let addresses: string[] = [];

    if (props.executorData.addressType === 0) {
      // 自动注册，从注册中心获取
      addresses = [
        ...(props.executorData.onlineRegistryList || []),
        ...(props.executorData.offlineRegistryList || [])
      ];
    } else {
      // 手动录入，从配置获取
      if (props.executorData.addressList) {
        addresses = props.executorData.addressList.split(',').map(addr => addr.trim());
      }
    }

    if (addresses.length > 0) {
      // 检查执行器状态
      const statusRes = await checkExecutorStatus(addresses);
      const statusList = statusRes.data || [];

      onlineNodes.value = statusList.filter(item => item.status === 'online');
      offlineNodes.value = statusList.filter(item => item.status === 'offline');
    } else {
      onlineNodes.value = [];
      offlineNodes.value = [];
    }
  } catch (error) {
    ElMessage.error('刷新注册信息失败');
  } finally {
    loading.value = false;
  }
};

/** 测试连接 */
const testConnection = async (address: string) => {
  try {
    ElMessage.info('正在测试连接...');
    const res = await checkExecutorStatus([address]);
    const status = res.data?.[0];

    if (status?.status === 'online') {
      ElMessage.success(`连接 ${address} 成功`);
    } else {
      ElMessage.error(`连接 ${address} 失败`);
    }
  } catch (error) {
    ElMessage.error(`连接 ${address} 失败`);
  }
};

/** 移除离线节点 */
const removeOfflineNode = async (address: string) => {
  try {
    await ElMessageBox.confirm(`确定要移除离线节点 ${address} 吗？`, '确认移除', {
      type: 'warning'
    });

    // 这里应该调用后端API移除节点
    // await removeExecutorNode(props.executorData?.appname, address);

    // 暂时从本地列表移除
    offlineNodes.value = offlineNodes.value.filter(node => node.address !== address);
    ElMessage.success('移除成功');
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error('移除失败');
    }
  }
};

// 监听对话框显示状态
watch(
  () => props.visible,
  (visible) => {
    if (visible && props.executorData) {
      refreshRegistry();
    }
  }
);
</script>

<style scoped>
.registry-section {
  margin-bottom: 24px;
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
  padding-bottom: 8px;
  border-bottom: 1px solid #ebeef5;
}

.section-header h4 {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: #303133;
}

.node-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.node-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px;
  border-radius: 8px;
  border: 1px solid #ebeef5;
  transition: all 0.2s;
}

.node-item:hover {
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.node-item.online {
  border-left: 4px solid #67c23a;
  background-color: #f0f9ff;
}

.node-item.offline {
  border-left: 4px solid #f56c6c;
  background-color: #fef0f0;
}

.node-info {
  flex: 1;
}

.node-address {
  display: flex;
  align-items: center;
  font-weight: 600;
  margin-bottom: 4px;
}

.status-icon {
  margin-right: 8px;
  font-size: 16px;
}

.node-item.online .status-icon {
  color: #67c23a;
}

.node-item.offline .status-icon {
  color: #f56c6c;
}

.node-status {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 12px;
  color: #909399;
}

.status-text {
  font-weight: 500;
}

.node-item.online .status-text {
  color: #67c23a;
}

.node-item.offline .status-text {
  color: #f56c6c;
}

.heartbeat-time {
  color: #c0c4cc;
}

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

.stats-section {
  margin-top: 24px;
  padding: 20px;
  background-color: #fafafa;
  border-radius: 8px;
}
</style>
