<template>
  <a-modal
    :visible="visible"
    :title="isEdit ? '编辑服务器' : '新增服务器'"
    @ok="handleOk"
    @cancel="handleCancel"
    @update:visible="handleUpdateVisible"
    :confirm-loading="confirmLoading"
    width="800px"
  >
    <a-form ref="formRef" :model="formData" :rules="rules" layout="vertical">
      <a-row :gutter="20">
        <a-col :span="12">
          <a-form-item field="name" label="服务器名称" required>
            <a-input v-model="formData.name" placeholder="请输入服务器名称" />
          </a-form-item>
        </a-col>
        <a-col :span="12">
          <a-form-item
            field="host"
            label="主机地址(IPv4 / IPv6)"
            required
          >
            <a-input v-model="formData.host" placeholder="域名或 IP，如 server.example.com 或 192.168.1.10" />
          </a-form-item>
        </a-col>
      </a-row>

      <a-row :gutter="20">
        <a-col :span="12">
          <a-form-item field="ip_address" label="IP地址" required>
            <a-input v-model="formData.ip_address" placeholder="IPv4 或 IPv6，如 192.168.1.10" />
          </a-form-item>
        </a-col>
      </a-row>

      <a-row :gutter="20">
        <a-col :span="8">
          <a-form-item field="server_type" label="服务器类型">
            <a-select v-model="formData.server_type" placeholder="请选择服务器类型">
              <a-option value="physical">物理服务器</a-option>
              <a-option value="virtual">虚拟服务器</a-option>
              <a-option value="cloud">云服务器</a-option>
            </a-select>
          </a-form-item>
        </a-col>
        <a-col :span="8">
          <a-form-item field="os" label="操作系统">
            <a-select v-model="formData.os" placeholder="请选择操作系统">
              <a-option value="Windows">Windows</a-option>
              <a-option value="Linux">Linux</a-option>
              <a-option value="Mac">Mac</a-option>
              <a-option value="Other">其它</a-option>
            </a-select>
          </a-form-item>
        </a-col>
        <a-col :span="8">
          <a-form-item field="os_version" label="系统版本">
            <a-input v-model="formData.os_version" placeholder="如: 22.04" />
          </a-form-item>
        </a-col>
      </a-row>

      <a-row :gutter="20">
        <a-col :span="8">
          <a-form-item field="kernel" label="内核类型">
            <a-select v-model="formData.kernel" placeholder="请选择内核类型">
              <a-option value="x86">x86</a-option>
              <a-option value="arm">ARM</a-option>
            </a-select>
          </a-form-item>
        </a-col>
        <a-col :span="8">
          <a-form-item field="location" label="位置/机房">
            <a-input v-model="formData.location" placeholder="机房A-机架01" />
          </a-form-item>
        </a-col>
        <a-col :span="8">
          <a-form-item field="asset_id" label="关联资产">
            <a-select
              v-model="formData.asset_id"
              :options="assetOptions"
              :loading="assetLoading"
              allow-clear
              show-search
              :filter-option="false"
              placeholder="请选择资产（可选）"
              @search="handleAssetSearch"
            />
          </a-form-item>
        </a-col>
      </a-row>

      <a-row :gutter="20">
        <a-col :span="8">
          <a-form-item field="tags" label="标签">
            <a-input v-model="formData.tags" placeholder="多个标签逗号分隔" />
          </a-form-item>
        </a-col>
      </a-row>

      <a-row :gutter="20">
        <a-col :span="12">
          <a-form-item field="remote_access" label="远程访问">
            <a-input v-model="formData.remote_access" placeholder="ssh://user@host" />
          </a-form-item>
        </a-col>
        <a-col :span="12">
          <a-form-item field="remote_port" label="远程端口">
            <a-input-number v-model="formData.remote_port" placeholder="SSH/RDP端口" :min="0" :max="65535" />
          </a-form-item>
        </a-col>
      </a-row>

      <a-form-item field="agent_config" label="Agent 配置 URL">
        <a-input v-model="formData.agent_config" placeholder="http://192.168.1.100:9100/dc-host/stats" />
      </a-form-item>

      <a-row :gutter="20">
        <a-col :span="8">
          <a-form-item field="status" label="状态">
            <a-select v-model="formData.status" placeholder="请选择状态">
              <a-option value="online">在线</a-option>
              <a-option value="offline">离线</a-option>
              <a-option value="unknown">未知</a-option>
            </a-select>
          </a-form-item>
        </a-col>
        <a-col :span="8">
          <a-form-item field="collect_on" label="启用采集">
            <a-switch v-model="formData.collect_on" />
          </a-form-item>
        </a-col>
        <a-col :span="8">
          <a-form-item v-if="formData.collect_on" field="collect_interval" label="采集间隔(秒)">
            <a-input-number v-model="formData.collect_interval" :min="10" :max="3600" placeholder="默认60秒" />
          </a-form-item>
        </a-col>
      </a-row>

      <a-row :gutter="20">
        <a-col :span="8">
          <a-form-item field="is_ip_scan_server" label="IP扫描执行服务器">
            <a-switch v-model="formData.is_ip_scan_server" />
          </a-form-item>
        </a-col>
        <a-col :span="8">
          <a-form-item v-if="formData.is_ip_scan_server" field="ip_scan_port" label="IP扫描端口">
            <a-input-number v-model="formData.ip_scan_port" :min="1" :max="65535" placeholder="默认12429" />
          </a-form-item>
        </a-col>
      </a-row>

      <a-form-item field="description" label="描述信息">
        <a-textarea v-model="formData.description" placeholder="请输入描述信息" :rows="4" />
      </a-form-item>
    </a-form>
  </a-modal>
</template>

<script lang="ts" setup>
import { ref, reactive, computed, watch } from 'vue'
import { Message } from '@arco-design/web-vue'
import type { FormInstance } from '@arco-design/web-vue'
import { createServer, updateServer } from '@/api/ops/server'
import type { ServerFormData, ServerItem } from '@/api/ops/server'
import { fetchAssetAll } from '@/api/ops/asset'

interface Props {
  visible: boolean
  record?: ServerItem | null
}

const props = withDefaults(defineProps<Props>(), {
  record: null,
})

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

const formRef = ref<FormInstance>()
const confirmLoading = ref(false)
const assetLoading = ref(false)
const assetOptions = ref<{ label: string; value: number }[]>([])
let assetSearchTimer: ReturnType<typeof setTimeout> | null = null

const isEdit = computed(() => !!props.record?.id)

const formData = reactive<ServerFormData>({
  server_identity: '',
  name: '',
  host: '',
  ip_address: '',
  description: '',
  os: '',
  os_version: '',
  kernel: '',
  server_type: '',
  tags: '',
  location: '',
  asset_id: undefined,
  remote_access: '',
  remote_port: 0,
  agent_config: '',
  status: 'unknown',
  collect_on: true,
  collect_interval: 60,
  is_ip_scan_server: false,
  ip_scan_port: 12429,
})

/** 判断是否为合法 IPv4 字符串 */
function isIPv4String(host: string): boolean {
  const h = host.trim()
  if (!h) return false
  const parts = h.split('.')
  if (parts.length !== 4) return false
  return parts.every((p) => {
    if (!/^\d{1,3}$/.test(p)) return false
    const n = Number(p)
    return n >= 0 && n <= 255
  })
}

/**
 * 若主机地址为 IP，返回规范化后的 IP（IPv4 或 IPv6）；否则返回 null
 */
function extractIpFromHost(host: string): string | null {
  const t = host.trim()
  if (!t) return null
  if (isIPv4String(t)) return t
  if (!t.includes(':')) return null
  try {
    const withBrackets = t.startsWith('[') && t.endsWith(']') ? t : `[${t}]`
    const u = new URL(`http://${withBrackets}/`)
    if (u.hostname.includes(':')) return u.hostname
  } catch {
    return null
  }
  return null
}

/** 校验 IP 地址字段（IPv4 或 IPv6） */
function isValidIpAddress(s: string): boolean {
  const t = s.trim()
  if (!t) return false
  if (isIPv4String(t)) return true
  try {
    const withBrackets = t.startsWith('[') && t.endsWith(']') ? t : `[${t}]`
    const u = new URL(`http://${withBrackets}/`)
    return u.hostname.includes(':')
  } catch {
    return false
  }
}

/** 主机为 IP 时同步到 IP 地址字段 */
function syncIpFromHost() {
  const ip = extractIpFromHost(formData.host)
  if (ip) {
    formData.ip_address = ip
  }
}

const rules = {
  name: [{ required: true, message: '请输入服务器名称' }],
  host: [{ required: true, message: '请输入主机地址' }],
  ip_address: [
    { required: true, message: '请输入IP地址' },
    {
      validator: (value: string | undefined, cb: (error?: string) => void) => {
        const v = (value || '').trim()
        if (!v) {
          cb()
          return
        }
        if (!isValidIpAddress(v)) {
          cb('请输入合法的 IPv4 或 IPv6 地址')
          return
        }
        cb()
      },
    },
  ],
}

function validateAgentConfigURL(raw?: string): string | null {
  const v = (raw || '').trim()
  if (!v) return null
  try {
    const u = new URL(v)
    const protocol = u.protocol.toLowerCase()
    if (protocol === 'https:' && u.port && u.port !== '443') {
      return `Agent 配置 URL 使用 https 且端口为 ${u.port}，请确认该端口确实启用了 TLS；若为明文服务请改为 http://`
    }
    return null
  } catch {
    return 'Agent 配置 URL 格式不合法，请输入完整 http(s) URL'
  }
}

watch(
  () => props.visible,
  (val) => {
    if (val) {
      loadAssetOptions()
      if (isEdit.value && props.record) {
        Object.assign(formData, {
          server_identity: props.record.server_identity || '',
          name: props.record.name || '',
          host: props.record.host || '',
          ip_address: props.record.ip_address || '',
          description: props.record.description || '',
          os: props.record.os || '',
          os_version: props.record.os_version || '',
          kernel: props.record.kernel || '',
          server_type: props.record.server_type || '',
          tags: props.record.tags || '',
          location: props.record.location || '',
          asset_id: props.record.asset_id,
          remote_access: props.record.remote_access || '',
          remote_port: props.record.remote_port || 0,
          agent_config: props.record.agent_config || '',
          status: props.record.status || 'unknown',
          collect_on: props.record.collect_on ?? true,
          collect_interval: props.record.collect_interval || 60,
          is_ip_scan_server: props.record.is_ip_scan_server ?? false,
          ip_scan_port: props.record.ip_scan_port || 12429,
        })
        syncIpFromHost()
      } else {
        Object.assign(formData, {
          server_identity: '',
          name: '',
          host: '',
          ip_address: '',
          description: '',
          os: '',
          os_version: '',
          kernel: '',
          server_type: '',
          tags: '',
          location: '',
          asset_id: undefined,
          remote_access: '',
          remote_port: 0,
          agent_config: '',
          status: 'unknown',
          collect_on: true,
          collect_interval: 60,
          is_ip_scan_server: false,
          ip_scan_port: 12429,
        })
      }
    }
  }
)

async function loadAssetOptions(keyword?: string) {
  assetLoading.value = true
  try {
    const res: any = await fetchAssetAll({ keyword: (keyword || '').trim() || undefined })
    if (res?.code !== 0) {
      Message.warning(res?.message || '加载资产列表失败')
      assetOptions.value = []
      return
    }
    const rows = res?.details || []
    assetOptions.value = rows.map((item: any) => ({
      value: Number(item.id),
      label: `${item.asset_code || item.id} | ${item.asset_name || '-'}`,
    }))
  } catch (error) {
    console.error('加载资产列表失败:', error)
    Message.warning('加载资产列表失败')
    assetOptions.value = []
  } finally {
    assetLoading.value = false
  }
}

// 资产下拉使用远程模糊查询，避免一次加载全部资产。
function handleAssetSearch(keyword: string) {
  if (assetSearchTimer) {
    clearTimeout(assetSearchTimer)
  }
  assetSearchTimer = setTimeout(() => {
    loadAssetOptions(keyword)
  }, 300)
}

watch(
  () => formData.host,
  () => {
    if (!props.visible) return
    syncIpFromHost()
  },
)

const handleOk = async () => {
  try {
    await formRef.value?.validate()

    const agentConfigErr = validateAgentConfigURL(formData.agent_config)
    if (agentConfigErr) {
      Message.warning(agentConfigErr)
      return
    }

    confirmLoading.value = true

    const submitData: ServerFormData = {
      server_identity: formData.server_identity || undefined,
      name: formData.name,
      host: formData.host,
      ip_address: formData.ip_address,
      description: formData.description,
      os: formData.os,
      os_version: formData.os_version,
      kernel: formData.kernel,
      server_type: formData.server_type,
      tags: formData.tags,
      location: formData.location,
      asset_id: formData.asset_id ?? (isEdit.value ? 0 : undefined),
      remote_access: formData.remote_access,
      remote_port: formData.remote_port,
      agent_config: formData.agent_config,
      status: formData.status,
      collect_on: formData.collect_on,
      collect_interval: formData.collect_interval,
      is_ip_scan_server: formData.is_ip_scan_server,
      ip_scan_port: formData.ip_scan_port,
    }

    if (isEdit.value && props.record?.id) {
      const res: any = await updateServer(props.record.id, submitData)
      if (res.code === 0) {
        Message.success('更新成功')
        emit('success')
        handleCancel()
      } else {
        Message.error(res.message || '更新失败')
      }
    } else {
      const res: any = await createServer(submitData)
      if (res.code === 0) {
        Message.success('创建成功')
        emit('success')
        handleCancel()
      } else {
        Message.error(res.message || '创建失败')
      }
    }
  } catch (error) {
    console.error('验证失败:', error)
  } finally {
    confirmLoading.value = false
  }
}

const handleUpdateVisible = (value: boolean) => {
  emit('update:visible', value)
}

const handleCancel = () => {
  emit('update:visible', false)
  formRef.value?.resetFields()
}
</script>
