<template>
  <a-modal
    :visible="visible"
    :title="isEdit ? '编辑网络设备采集' : '新增网络设备采集'"
    :confirm-loading="confirmLoading"
    :mask-closable="true"
    width="980px"
    @ok="handleOk"
    @cancel="handleCancel"
    @update:visible="handleUpdateVisible"
  >
      <a-form ref="formRef" :model="formData" :rules="rules" layout="vertical" auto-label-width>
      <a-alert type="info" show-icon class="mb-12">
        采集协议固定为 SNMP；仅在勾选“采集FIB信息”时需要填写 SSH。编辑时密码不回显，留空表示不修改。
      </a-alert>
      <a-divider orientation="left">基础信息</a-divider>
      <a-row :gutter="20">
        <a-col :span="12">
          <a-form-item field="name" label="设备名称" required>
            <a-input v-model="formData.name" placeholder="例如：核心路由器-01" />
          </a-form-item>
        </a-col>
        <a-col :span="12">
          <a-form-item field="category" label="设备类型" required>
            <a-select v-model="formData.category" allow-search>
              <a-option value="router">路由器</a-option>
              <a-option value="switch">交换机</a-option>
              <a-option value="firewall">防火墙</a-option>
              <a-option value="access_point">接入点</a-option>
              <a-option value="load_balancer">负载均衡</a-option>
              <a-option value="other">其他</a-option>
            </a-select>
          </a-form-item>
        </a-col>
      </a-row>
      <a-row :gutter="20">
        <a-col :span="12">
          <a-form-item field="server_identity" label="执行节点">
            <a-select v-model="formData.server_identity" allow-search allow-clear>
              <a-option v-for="server in serverOptions" :key="server.server_identity" :value="server.server_identity">
                {{ server.name }} ({{ server.server_identity }})
              </a-option>
            </a-select>
          </a-form-item>
        </a-col>
        <a-col :span="12">
          <a-form-item field="vendor" label="厂商">
            <a-select v-model="formData.vendor" allow-search allow-create allow-clear>
              <a-option value="Cisco">Cisco</a-option>
              <a-option value="Huawei">Huawei</a-option>
              <a-option value="H3C">H3C</a-option>
              <a-option value="Juniper">Juniper</a-option>
            </a-select>
          </a-form-item>
        </a-col>
      </a-row>
      <a-row :gutter="20">
        <a-col :span="12">
          <a-form-item field="model" label="型号"><a-input v-model="formData.model" placeholder="例如：ASR1001-X" /></a-form-item>
        </a-col>
        <a-col :span="12">
          <a-form-item field="location" label="位置信息">
            <a-input v-model="formData.location" placeholder="例如：A机房-R03-12U" />
          </a-form-item>
        </a-col>
      </a-row>
      <a-form-item field="description" label="描述"><a-textarea v-model="formData.description" :rows="2" /></a-form-item>
      <a-form-item field="tags" label="标签"><a-input-tag v-model="tagList" placeholder="回车添加标签" /></a-form-item>

      <a-divider orientation="left">连接信息</a-divider>
      <a-row :gutter="20">
        <a-col :span="12">
          <a-form-item field="host" label="设备地址" required>
            <a-input v-model="formData.host" placeholder="例如：192.168.1.10" />
          </a-form-item>
        </a-col>
        <a-col :span="12">
          <a-form-item label="采集协议"><a-tag color="purple">SNMP + SSH（FIB可选）</a-tag></a-form-item>
        </a-col>
      </a-row>

      <a-divider orientation="left">SNMP 配置（必填）</a-divider>
      <a-row :gutter="20">
        <a-col :span="12">
          <a-form-item field="snmp_port" label="SNMP端口" required>
            <a-input-number v-model="formData.port" :min="1" :max="65535" style="width: 100%" />
          </a-form-item>
        </a-col>
        <a-col :span="12">
          <a-form-item field="snmp_version" label="SNMP版本">
            <a-radio-group v-model="formData.snmp_version" type="button">
              <a-radio value="v2c">v2c</a-radio>
              <a-radio value="v3">v3</a-radio>
            </a-radio-group>
          </a-form-item>
        </a-col>
      </a-row>
      <a-form-item v-if="formData.snmp_version !== 'v3'" field="community" label="Community" required>
        <a-input v-model="formData.community" placeholder="SNMP v1/v2c 必填" />
      </a-form-item>
      <a-row v-else :gutter="20">
        <a-col :span="12">
          <a-form-item field="snmpv3_security_name" label="Security Name" required>
            <a-input v-model="formData.snmpv3.security_name" />
          </a-form-item>
        </a-col>
        <a-col :span="12">
          <a-form-item field="snmpv3_security_level" label="Security Level">
            <a-select v-model="formData.snmpv3.security_level">
              <a-option value="noAuthNoPriv">noAuthNoPriv</a-option>
              <a-option value="authNoPriv">authNoPriv</a-option>
              <a-option value="authPriv">authPriv</a-option>
            </a-select>
          </a-form-item>
        </a-col>
      </a-row>
      <a-row v-if="formData.snmp_version === 'v3' && formData.snmpv3.security_level !== 'noAuthNoPriv'" :gutter="20">
        <a-col :span="12">
          <a-form-item field="snmpv3_auth_protocol" label="Auth协议">
            <a-select v-model="formData.snmpv3.auth_protocol">
              <a-option value="SHA">SHA</a-option>
              <a-option value="MD5">MD5</a-option>
            </a-select>
          </a-form-item>
        </a-col>
        <a-col :span="12">
          <a-form-item field="snmpv3_auth_password" label="Auth密码" required>
            <a-input-password v-model="formData.snmpv3.auth_password" placeholder="authNoPriv/authPriv 必填" />
          </a-form-item>
        </a-col>
      </a-row>
      <a-row v-if="formData.snmp_version === 'v3' && formData.snmpv3.security_level === 'authPriv'" :gutter="20">
        <a-col :span="12">
          <a-form-item field="snmpv3_priv_protocol" label="Priv协议">
            <a-select v-model="formData.snmpv3.priv_protocol">
              <a-option value="AES">AES</a-option>
              <a-option value="DES">DES</a-option>
            </a-select>
          </a-form-item>
        </a-col>
        <a-col :span="12">
          <a-form-item field="snmpv3_priv_password" label="Priv密码" required>
            <a-input-password v-model="formData.snmpv3.priv_password" placeholder="authPriv 必填" />
          </a-form-item>
        </a-col>
      </a-row>
      <a-row v-if="formData.snmp_version === 'v3'" :gutter="20">
        <a-col :span="12">
          <a-form-item field="snmpv3_context_name" label="Context Name">
            <a-input v-model="formData.snmpv3.context_name" placeholder="可选" />
          </a-form-item>
        </a-col>
      </a-row>

      <a-divider orientation="left">
        {{ fibEnabled ? 'SSH 配置（采集 FIB 时必填）' : 'SSH 配置（未采集 FIB 时可选）' }}
      </a-divider>
      <a-row :gutter="20">
        <a-col :span="12">
          <a-form-item field="ssh_port" label="SSH端口" :required="fibEnabled">
            <a-input-number v-model="formData.ssh.port" :min="1" :max="65535" style="width: 100%" />
          </a-form-item>
        </a-col>
        <a-col :span="12">
          <a-form-item field="ssh_username" label="SSH用户名" :required="fibEnabled">
            <a-input v-model="formData.ssh.username" />
          </a-form-item>
        </a-col>
      </a-row>
      <a-row :gutter="20">
        <a-col :span="12">
          <a-form-item field="ssh_password" label="SSH密码" :required="fibEnabled">
            <a-input-password v-model="formData.ssh.password" :placeholder="isEdit ? '留空表示不修改' : '请输入 SSH 密码'" />
          </a-form-item>
        </a-col>
        <a-col :span="12">
          <a-form-item field="ssh_command_fib" label="FIB命令覆盖">
            <a-input v-model="formData.ssh.command_fib" placeholder="可选：覆盖厂商默认命令" />
          </a-form-item>
        </a-col>
      </a-row>
      <a-form-item field="ssh_private_key" label="SSH私钥">
        <a-textarea v-model="formData.ssh.private_key" :rows="2" placeholder="可选，支持粘贴私钥" />
      </a-form-item>

      <a-divider orientation="left">采集策略</a-divider>
      <a-row :gutter="20">
        <a-col :span="12">
          <a-form-item field="enabled" label="启用采集"><a-switch v-model="formData.enabled" /></a-form-item>
        </a-col>
        <a-col :span="12">
          <a-form-item field="interval" label="采集间隔(秒)">
            <a-input-number v-model="formData.interval" :min="1" :max="86400" style="width: 100%" />
          </a-form-item>
        </a-col>
      </a-row>
      <a-row :gutter="20">
        <a-col :span="12"><a-checkbox v-model="formData.collect.interface_enabled">采集接口信息</a-checkbox></a-col>
        <a-col :span="12"><a-checkbox v-model="formData.collect.arp_enabled">采集ARP信息</a-checkbox></a-col>
      </a-row>
      <a-row :gutter="20" class="mt-8">
        <a-col :span="12"><a-checkbox v-model="formData.collect.route_enabled">采集路由信息</a-checkbox></a-col>
        <a-col :span="12"><a-checkbox v-model="formData.collect.fib_enabled">采集FIB信息</a-checkbox></a-col>
      </a-row>
    </a-form>
  </a-modal>
</template>

<script lang="ts" setup>
import { ref, reactive, computed, watch, onMounted } from 'vue'
import { Message } from '@arco-design/web-vue'
import type { FormInstance } from '@arco-design/web-vue'
import { fetchServerList, type ServerItem } from '@/api/ops/server'
import { createNetworkDevice, updateNetworkDevice } from '@/api/ops/network-device'

interface Props {
  visible: boolean
  record?: any
}
const props = withDefaults(defineProps<Props>(), { record: () => ({}) })
const emit = defineEmits(['update:visible', 'success'])

const formRef = ref<FormInstance>()
const confirmLoading = ref(false)
const serverOptions = ref<ServerItem[]>([])
const tagList = ref<string[]>([])
const isEdit = computed(() => !!props.record?.id)

const defaults = () => ({
  service_identity: '',
  server_identity: '',
  name: '',
  category: 'router',
  type: 'network',
  host: '',
  port: 161,
  protocol: 'snmp',
  community: 'public',
  snmp_version: 'v2c',
  vendor: '',
  model: '',
  location: '',
  description: '',
  enabled: true,
  interval: 60,
  tags: '',
  snmpv3: {
    security_level: 'noAuthNoPriv',
    security_name: '',
    auth_protocol: 'SHA',
    auth_password: '',
    priv_protocol: 'AES',
    priv_password: '',
    context_name: '',
  },
  ssh: {
    port: 22,
    username: '',
    password: '',
    private_key: '',
    command_fib: '',
  },
  collect: { interface_enabled: true, arp_enabled: true, route_enabled: true, fib_enabled: true, timeout_sec: 5, retries: 1 },
})
const formData = reactive(defaults())
const fibEnabled = computed(() => formData.collect.fib_enabled)
const rules = {
  name: [{ required: true, message: '请输入设备名称' }],
  category: [{ required: true, message: '请选择设备类型' }],
  host: [{ required: true, message: '请输入设备地址' }],
  community: [{ required: true, message: '请输入 SNMP community' }],
  ssh_username: [
    {
      validator: (value: string | undefined, callback: (error?: string) => void) => {
        if (formData.collect.fib_enabled && !String(value || '').trim()) {
          callback('请输入 SSH 用户名')
          return
        }
        callback()
      },
    },
  ],
}

watch(
  () => props.visible,
  (val) => {
    if (!val) return
    if (isEdit.value && props.record) {
      let parsedExtra: any = {}
      try {
        parsedExtra = props.record.extra ? JSON.parse(props.record.extra) : {}
      } catch {}
      const deviceCategory =
        props.record.category && props.record.category !== 'network_device' ? props.record.category : props.record.type || 'other'
      Object.assign(formData, defaults(), {
        ...props.record,
        category: deviceCategory,
        type: 'network',
        collect: {
          interface_enabled: parsedExtra.collect?.interface_enabled ?? true,
          arp_enabled: parsedExtra.collect?.arp_enabled ?? true,
          route_enabled: parsedExtra.collect?.route_enabled ?? true,
          fib_enabled: parsedExtra.collect?.fib_enabled ?? true,
          timeout_sec: parsedExtra.collect?.timeout_sec ?? 5,
          retries: parsedExtra.collect?.retries ?? 1,
        },
        snmpv3: {
          security_level: parsedExtra.snmp_v3?.security_level || 'noAuthNoPriv',
          security_name: parsedExtra.snmp_v3?.security_name || '',
          auth_protocol: parsedExtra.snmp_v3?.auth_protocol || 'SHA',
          auth_password: '',
          priv_protocol: parsedExtra.snmp_v3?.priv_protocol || 'AES',
          priv_password: '',
          context_name: parsedExtra.snmp_v3?.context_name || '',
        },
        ssh: {
          port: parsedExtra.ssh?.port || 22,
          username: parsedExtra.ssh?.username || props.record.username || '',
          password: '',
          private_key: parsedExtra.ssh?.private_key || '',
          command_fib: parsedExtra.ssh?.command_fib || '',
        },
      })
      tagList.value = (props.record.tags || '')
        .split(',')
        .map((i: string) => i.trim())
        .filter(Boolean)
    } else {
      Object.assign(formData, defaults())
      tagList.value = []
    }
  }
)

watch(tagList, (tags) => {
  formData.tags = tags.join(',')
})

watch(
  () => formData.collect.fib_enabled,
  (enabled) => {
    if (!enabled) {
      ;(formRef.value as any)?.clearValidate?.(['ssh_port', 'ssh_username', 'ssh_password'])
    }
  }
)

const handleOk = async () => {
  try {
    await formRef.value?.validate()
    if (formData.snmp_version !== 'v3' && !formData.community.trim()) {
      Message.warning('请填写 SNMP community')
      return
    }
    if (formData.snmp_version === 'v3') {
      if (!formData.snmpv3.security_name.trim()) {
        Message.warning('请填写 SNMPv3 Security Name')
        return
      }
      if (formData.snmpv3.security_level !== 'noAuthNoPriv' && !formData.snmpv3.auth_password.trim()) {
        Message.warning('请填写 SNMPv3 Auth 密码')
        return
      }
      if (formData.snmpv3.security_level === 'authPriv' && !formData.snmpv3.priv_password.trim()) {
        Message.warning('请填写 SNMPv3 Priv 密码')
        return
      }
    }
    if (formData.collect.fib_enabled) {
      if (!formData.ssh.username.trim()) {
        Message.warning('请填写 SSH 用户名')
        return
      }
      if (!isEdit.value && !formData.ssh.password.trim() && !formData.ssh.private_key.trim()) {
        Message.warning('请填写 SSH 密码或 SSH 私钥')
        return
      }
    }
    confirmLoading.value = true
    const payload: any = {
      ...formData,
      type: 'network',
      protocol: 'snmp',
      username: formData.ssh.username,
      extra: JSON.stringify({
        schema_version: '1.0',
        collect: formData.collect,
        snmp_v2c: { port: formData.port, community: formData.community },
        snmp_v3: {
          port: formData.port,
          security_level: formData.snmpv3.security_level,
          security_name: formData.snmpv3.security_name,
          auth_protocol: formData.snmpv3.auth_protocol,
          auth_password: formData.snmpv3.auth_password,
          priv_protocol: formData.snmpv3.priv_protocol,
          priv_password: formData.snmpv3.priv_password,
          context_name: formData.snmpv3.context_name,
        },
        ssh: formData.ssh,
      }),
    }
    delete payload.snmpv3
    delete payload.ssh
    delete payload.collect
    if (formData.ssh.password.trim()) {
      payload.password = formData.ssh.password
    } else {
      delete payload.password
    }
    if (isEdit.value) await updateNetworkDevice(props.record.id, payload)
    else await createNetworkDevice(payload)
    Message.success(isEdit.value ? '更新成功' : '创建成功')
    emit('success')
    handleCancel()
  } catch (error: any) {
    if (error?.response?.data?.message) Message.error(error.response.data.message)
    else Message.error('保存失败，请检查输入后重试')
  } finally {
    confirmLoading.value = false
  }
}

const handleUpdateVisible = (value: boolean) => emit('update:visible', value)
const handleCancel = () => {
  emit('update:visible', false)
  formRef.value?.resetFields()
}
const loadServerOptions = async () => {
  try {
    const response: any = await fetchServerList({ page: 1, size: 1000 })
    serverOptions.value = response?.details?.data || []
  } catch {
    serverOptions.value = []
  }
}
onMounted(loadServerOptions)
</script>

<style scoped lang="less">
.mb-12 {
  margin-bottom: 12px;
}
.mt-8 {
  margin-top: 8px;
}
</style>
