<template>
  <div class="sg-detail-page">
    <div class="page-header">
      <div class="header-left">
        <el-button @click="goBack" link class="back-btn"><el-icon><ArrowLeft /></el-icon> 返回安全组列表</el-button>
        <el-divider direction="vertical" />
        <span class="page-title">安全组详情</span>
      </div>
      <div class="header-right">
        <el-button plain :icon="Refresh" @click="loadDetail" :loading="loading">刷新</el-button>
      </div>
    </div>

    <div class="main-content" v-loading="loading">
      <!-- 基本信息 -->
      <el-card shadow="never" class="info-card" v-if="detail">
        <template #header><span class="card-title">基本信息</span></template>
        <el-descriptions :column="2" border>
          <el-descriptions-item label="ID">{{ detail.id }}</el-descriptions-item>
          <el-descriptions-item label="名称">{{ detail.name }}</el-descriptions-item>
          <el-descriptions-item label="锁定">
            <el-tag :type="detail.lock ? 'danger' : 'success'" size="small">{{ detail.lock ? '是' : '否' }}</el-tag>
          </el-descriptions-item>
          <el-descriptions-item label="白名单模式">
            <el-tag :type="detail.drop_all ? 'warning' : 'info'" size="small">{{ detail.drop_all ? '开启' : '关闭' }}</el-tag>
          </el-descriptions-item>
          <el-descriptions-item label="宿主机">{{ getHostLabel(detail.host_id) }}</el-descriptions-item>
          <el-descriptions-item label="介绍">{{ detail.direction || '-' }}</el-descriptions-item>
          <el-descriptions-item label="创建时间">{{ formatTimestamp(detail.created_at) }}</el-descriptions-item>
          <el-descriptions-item label="更新时间">{{ formatTimestamp(detail.updated_at) }}</el-descriptions-item>
        </el-descriptions>
      </el-card>

      <!-- 操作按钮 -->
      <el-card shadow="never" class="info-card" v-if="detail">
        <template #header><span class="card-title">操作</span></template>
        <div class="action-buttons">
          <el-button type="primary" @click="handleSync">同步到宿主机</el-button>
          <el-button type="success" @click="handleBind">绑定VM</el-button>
          <el-button type="warning" @click="handleUnbind">解绑VM</el-button>
          <el-button :type="detail.drop_all ? 'info' : 'warning'" @click="handleToggleWhitelist">
            {{ detail.drop_all ? '关闭白名单' : '开启白名单' }}
          </el-button>
          <el-button type="primary" @click="handleApply">应用规则</el-button>
          <el-button type="danger" @click="handleDelete">删除安全组</el-button>
        </div>
      </el-card>

      <!-- 规则管理 -->
      <el-card shadow="never" class="info-card">
        <template #header>
          <div class="card-header-row">
            <span class="card-title">安全组规则</span>
            <el-button type="primary" size="small" @click="handleAddRule">新增规则</el-button>
          </div>
        </template>
        <el-table :data="detail?.rules || []" stripe size="small" style="width: 100%">
          <el-table-column prop="id" label="ID" width="60" />
          <el-table-column prop="protocol" label="协议" width="80">
            <template #default="{ row }"><el-tag size="small">{{ (row.protocol || '-').toUpperCase() }}</el-tag></template>
          </el-table-column>
          <el-table-column prop="action" label="动作" width="80">
            <template #default="{ row }">
              <el-tag :type="row.action === 'allow' ? 'success' : 'danger'" size="small">{{ row.action === 'allow' ? '允许' : '拒绝' }}</el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="port_range" label="端口范围" min-width="120" />
          <el-table-column prop="ip_range" label="IP 范围" min-width="140" />
          <el-table-column prop="priority" label="优先级" width="80" />
          <el-table-column label="操作" width="130">
            <template #default="{ row }">
              <el-button link type="primary" size="small" @click="handleEditRule(row)">编辑</el-button>
              <el-button link type="danger" size="small" @click="handleDeleteRule(row)">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
        <el-empty v-if="!detail?.rules?.length && !loading" description="暂无规则" />
      </el-card>
    </div>

    <!-- 同步弹窗 -->
    <el-dialog v-model="syncDialogVisible" title="同步到宿主机" width="420px" destroy-on-close>
      <el-form label-width="100px">
        <el-form-item label="安全组">{{ detail?.name || '-' }}</el-form-item>
        <el-form-item label="目标宿主机">
          <el-select v-model="syncHostId" placeholder="选择宿主机" filterable style="width: 100%">
            <el-option v-for="h in hostOptions" :key="h.id" :label="`${h.name} (${h.ip || h.id})`" :value="h.id" />
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="syncDialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="actionLoading" @click="submitSync">同步</el-button>
      </template>
    </el-dialog>

    <!-- 绑定/解绑弹窗 -->
    <el-dialog v-model="bindDialogVisible" :title="bindType === 'bind' ? '绑定安全组到虚拟机' : '解绑安全组'" width="420px" destroy-on-close>
      <el-form label-width="100px">
        <el-form-item label="安全组">{{ detail?.name || '-' }}</el-form-item>
        <el-form-item label="虚拟机">
          <div style="display: flex; gap: 8px; width: 100%">
            <el-input :model-value="bindVmId ? `${bindVmName || ''} (ID: ${bindVmId})` : ''" readonly placeholder="请选择虚拟机" style="flex: 1" />
            <el-button type="primary" @click="showVmSelector = true">选择</el-button>
          </div>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="bindDialogVisible = false">取消</el-button>
        <el-button :type="bindType === 'bind' ? 'primary' : 'warning'" :loading="actionLoading" @click="submitBind">
          {{ bindType === 'bind' ? '绑定' : '解绑' }}
        </el-button>
      </template>
    </el-dialog>

    <VmSelectorPopup v-model="showVmSelector" :service-id="serviceId" :current-id="bindVmId" @confirm="vm => { bindVmId = vm.id; bindVmName = vm.name || '' }" />

    <!-- 规则弹窗 -->
    <el-dialog v-model="ruleDialogVisible" :title="ruleDialogType === 'add' ? '新增规则' : '编辑规则'" width="520px" destroy-on-close>
      <el-form ref="ruleFormRef" :model="ruleForm" :rules="ruleRules" label-width="100px">
        <el-form-item label="协议" prop="protocol">
          <el-select v-model="ruleForm.protocol" style="width: 100%">
            <el-option label="TCP" value="tcp" /><el-option label="UDP" value="udp" />
          </el-select>
        </el-form-item>
        <el-form-item label="动作" prop="action">
          <el-select v-model="ruleForm.action" style="width: 100%">
            <el-option label="允许" value="allow" /><el-option label="拒绝" value="deny" />
          </el-select>
        </el-form-item>
        <el-form-item label="端口范围"><el-input v-model="ruleForm.port_range" placeholder="如 80 或 80-90" /></el-form-item>
        <el-form-item label="IP 范围"><el-input v-model="ruleForm.ip_range" placeholder="如 0.0.0.0/0" /></el-form-item>
        <el-form-item label="优先级"><el-input-number v-model="ruleForm.priority" :min="0" :max="9999" style="width: 100%" /></el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="ruleDialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="actionLoading" @click="submitRule">确定</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
import { ArrowLeft, Refresh } from '@element-plus/icons-vue'
import {
  getRemoteHostList, getSecurityGroupDetail,
  syncSecurityGroup, bindSecurityGroup, unbindSecurityGroup,
  deleteSecurityGroup, enableSecurityGroupWhitelist, disableSecurityGroupWhitelist,
  applySecurityGroup, createSecurityGroupRule, updateSecurityGroupRule, deleteSecurityGroupRule
} from '@/api/admin/kvmService'
import VmSelectorPopup from '@/components/admin/VmSelectorPopup.vue'
import { useTagsViewStore } from '@/store/tagsViewStore'

const route = useRoute()
const router = useRouter()
const tagsViewStore = useTagsViewStore()

const serviceId = computed(() => parseInt(route.query.service_id) || 0)
const serviceName = computed(() => route.query.service_name || '')
const sgId = computed(() => parseInt(route.query.id) || 0)

const loading = ref(false)
const actionLoading = ref(false)
const detail = ref(null)
const hostOptions = ref([])

// 同步
const syncDialogVisible = ref(false)
const syncHostId = ref(0)

// 绑定
const bindDialogVisible = ref(false)
const bindType = ref('bind')
const bindVmId = ref(0)
const bindVmName = ref('')
const showVmSelector = ref(false)

// 规则
const ruleDialogVisible = ref(false)
const ruleDialogType = ref('add')
const ruleFormRef = ref(null)
const ruleForm = reactive({ id: undefined, group_id: 0, protocol: 'tcp', action: 'allow', port_range: '', ip_range: '', priority: 0, port_group_id: 0 })
const ruleRules = {
  protocol: [{ required: true, message: '请选择协议', trigger: 'change' }],
  action: [{ required: true, message: '请选择动作', trigger: 'change' }]
}

const formatTimestamp = (ts) => {
  if (!ts) return '-'
  if (typeof ts === 'object' && ts.seconds) return new Date(Number(ts.seconds) * 1000).toLocaleString('zh-CN')
  if (typeof ts === 'string' || typeof ts === 'number') { const d = new Date(ts); return isNaN(d.getTime()) ? String(ts) : d.toLocaleString('zh-CN') }
  return '-'
}
const getHostLabel = (hid) => { const h = hostOptions.value.find(x => x.id === hid); return h ? h.name : (hid || '-') }

const loadHostOptions = async () => {
  try {
    const res = await getRemoteHostList({ service_id: serviceId.value, page: 1, page_size: 100 })
    if (res?.data?.code === 200 && res?.data?.data) {
      const inner = res.data.data
      hostOptions.value = inner.hosts || inner.data || (Array.isArray(inner) ? inner : [])
    }
  } catch { /* */ }
}

const loadDetail = async () => {
  if (!sgId.value) return
  loading.value = true
  try {
    const res = await getSecurityGroupDetail({ service_id: serviceId.value, id: sgId.value })
    if (res?.data?.code === 200 && res?.data?.data) {
      const inner = res.data.data
      detail.value = inner.group || inner.data || inner
    } else ElMessage.error(res?.data?.message || '加载失败')
  } catch { ElMessage.error('加载失败') } finally { loading.value = false }
}

const handleSync = () => { syncHostId.value = detail.value?.host_id || 0; syncDialogVisible.value = true }
const submitSync = async () => {
  if (!syncHostId.value) { ElMessage.warning('请选择宿主机'); return }
  actionLoading.value = true
  try {
    const res = await syncSecurityGroup({ service_id: serviceId.value, id: sgId.value, host_id: syncHostId.value })
    if (res?.data?.code === 200) { ElMessage.success('同步成功'); syncDialogVisible.value = false; loadDetail() }
    else ElMessage.error(res?.data?.message || '同步失败')
  } catch { ElMessage.error('同步失败') } finally { actionLoading.value = false }
}

const handleBind = () => { bindType.value = 'bind'; bindVmId.value = 0; bindVmName.value = ''; bindDialogVisible.value = true }
const handleUnbind = () => { bindType.value = 'unbind'; bindVmId.value = 0; bindVmName.value = ''; bindDialogVisible.value = true }
const submitBind = async () => {
  if (!bindVmId.value) { ElMessage.warning('请选择虚拟机'); return }
  actionLoading.value = true
  try {
    const api = bindType.value === 'bind' ? bindSecurityGroup : unbindSecurityGroup
    const res = await api({ service_id: serviceId.value, id: sgId.value, vm_id: bindVmId.value })
    if (res?.data?.code === 200) { ElMessage.success(bindType.value === 'bind' ? '绑定成功' : '解绑成功'); bindDialogVisible.value = false }
    else ElMessage.error(res?.data?.message || '操作失败')
  } catch { ElMessage.error('操作失败') } finally { actionLoading.value = false }
}

const handleToggleWhitelist = () => {
  const action = detail.value.drop_all ? '关闭' : '开启'
  ElMessageBox.confirm(`确定${action}白名单模式？`, `${action}白名单`, { type: 'warning' }).then(async () => {
    try {
      const api = detail.value.drop_all ? disableSecurityGroupWhitelist : enableSecurityGroupWhitelist
      const res = await api({ service_id: serviceId.value, id: sgId.value })
      if (res?.data?.code === 200) { ElMessage.success(`${action}成功`); loadDetail() }
      else ElMessage.error(res?.data?.message || `${action}失败`)
    } catch { ElMessage.error(`${action}失败`) }
  }).catch(() => {})
}

const handleApply = () => {
  ElMessageBox.confirm('确定应用安全组规则到所有绑定的虚拟机？', '应用安全组', { type: 'info' }).then(async () => {
    try {
      const res = await applySecurityGroup({ service_id: serviceId.value, id: sgId.value })
      if (res?.data?.code === 200) ElMessage.success('应用成功')
      else ElMessage.error(res?.data?.message || '应用失败')
    } catch { ElMessage.error('应用失败') }
  }).catch(() => {})
}

const handleDelete = () => {
  ElMessageBox.confirm(`确定删除安全组「${detail.value?.name}」？`, '删除确认', { type: 'warning' }).then(async () => {
    try {
      const res = await deleteSecurityGroup({ service_id: serviceId.value, id: sgId.value })
      if (res?.data?.code === 200) { ElMessage.success('删除成功'); goBack() }
      else ElMessage.error(res?.data?.message || '删除失败')
    } catch { ElMessage.error('删除失败') }
  }).catch(() => {})
}

const handleAddRule = () => {
  ruleDialogType.value = 'add'
  Object.assign(ruleForm, { id: undefined, group_id: sgId.value, protocol: 'tcp', action: 'allow', port_range: '', ip_range: '', priority: 0, port_group_id: 0 })
  ruleDialogVisible.value = true
}
const handleEditRule = (rule) => {
  ruleDialogType.value = 'edit'
  Object.assign(ruleForm, { id: rule.id, group_id: sgId.value, port_group_id: sgId.value, protocol: rule.protocol || 'tcp', action: rule.action || 'allow', port_range: rule.port_range || '', ip_range: rule.ip_range || '', priority: rule.priority || 0 })
  ruleDialogVisible.value = true
}
const submitRule = () => {
  ruleFormRef.value?.validate(async (valid) => {
    if (!valid) return
    actionLoading.value = true
    try {
      const api = ruleDialogType.value === 'add' ? createSecurityGroupRule : updateSecurityGroupRule
      const res = await api({ service_id: serviceId.value, ...ruleForm })
      if (res?.data?.code === 200) { ElMessage.success('操作成功'); ruleDialogVisible.value = false; loadDetail() }
      else ElMessage.error(res?.data?.message || '操作失败')
    } catch { ElMessage.error('操作失败') } finally { actionLoading.value = false }
  })
}
const handleDeleteRule = (rule) => {
  ElMessageBox.confirm('确定删除该规则？', '删除确认', { type: 'warning' }).then(async () => {
    try {
      const res = await deleteSecurityGroupRule({ service_id: serviceId.value, id: rule.id })
      if (res?.data?.code === 200) { ElMessage.success('删除成功'); loadDetail() }
      else ElMessage.error(res?.data?.message || '删除失败')
    } catch { ElMessage.error('删除失败') }
  }).catch(() => {})
}

const goBack = () => {
  tagsViewStore.delVisitedView(route)
  router.push({ path: '/virtualization/kvm-service-detail', query: { service_id: serviceId.value, service_name: serviceName.value } })
}

onMounted(() => { loadHostOptions(); loadDetail() })
</script>

<style scoped>
.sg-detail-page { padding: 0; }
.page-header { display: flex; justify-content: space-between; align-items: center; padding: 16px 20px; background: #fff; border-bottom: 1px solid #ebeef5; }
.header-left { display: flex; align-items: center; gap: 0; }
.back-btn { font-size: 14px; color: #606266; }
.back-btn:hover { color: #409eff; }
.page-title { font-size: 16px; font-weight: 600; color: #303133; }
.header-right { display: flex; gap: 8px; }
.main-content { padding: 20px; }
.info-card { margin-bottom: 20px; }
.card-title { font-weight: 600; font-size: 15px; color: #303133; }
.card-header-row { display: flex; justify-content: space-between; align-items: center; }
.action-buttons { display: flex; gap: 8px; flex-wrap: wrap; }
</style>
