<template>
  <div class="container">
    <search-table
      :form-model="formModel"
      :form-items="formItems"
      :data="tableData"
      :columns="columns"
      :loading="loading"
      :pagination="clientPagination"
      title="SNMP Trap 匹配规则"
      search-button-text="查询"
      reset-button-text="重置"
      :show-download="false"
      @update:form-model="handleFormModelUpdate"
      @search="handleSearch"
      @reset="handleReset"
      @page-change="handlePageChange"
      @page-size-change="handlePageSizeChange"
      @refresh="fetchList"
    >
      <template #toolbar-left>
        <a-button type="primary" @click="openCreate">
          <template #icon><icon-plus /></template>
          新建规则
        </a-button>
      </template>
      <template #enabled="{ record }">
        <a-tag :color="record.enabled ? 'green' : 'red'">{{ record.enabled ? '启用' : '禁用' }}</a-tag>
      </template>
      <template #operations="{ record }">
        <a-space>
          <a-button type="text" size="small" @click="openEdit(record)">编辑</a-button>
          <a-button type="text" size="small" status="danger" @click="handleDelete(record)">删除</a-button>
        </a-space>
      </template>
    </search-table>

    <a-modal
      v-model:visible="modalVisible"
      :title="editingId ? `编辑规则 #${editingId}` : '新建 Trap 规则'"
      width="640px"
      :confirm-loading="submitting"
      @ok="submitForm"
      @cancel="modalVisible = false"
    >
      <a-form ref="formRef" :model="formData" layout="vertical">
        <a-form-item field="name" label="规则名称" :rules="[{ required: true, message: '必填' }]">
          <a-input v-model="formData.name" placeholder="规则名称" />
        </a-form-item>
        <a-row :gutter="16">
          <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="priority" label="优先级">
              <a-input-number v-model="formData.priority" style="width: 100%" />
            </a-form-item>
          </a-col>
        </a-row>
        <a-form-item field="oid_prefix" label="OID 前缀">
          <a-input v-model="formData.oid_prefix" placeholder="如 1.3.6.1.4.1." />
        </a-form-item>
        <a-form-item field="varbind_match_regex" label="Varbind 匹配正则">
          <a-input v-model="formData.varbind_match_regex" placeholder="可选" />
        </a-form-item>
        <a-form-item field="alert_name" label="告警名称">
          <a-input v-model="formData.alert_name" />
        </a-form-item>
        <a-row :gutter="16">
          <a-col :span="12">
            <a-form-item field="severity_code" label="严重级别代码">
              <a-select
                v-model="formData.severity_code"
                placeholder="请选择告警级别"
                :loading="severityLoading"
                allow-search
                :filter-option="false"
                @search="handleSeveritySearch"
              >
                <a-option
                  v-for="item in severityOptions"
                  :key="item.code"
                  :value="item.code"
                >
                  {{ item.name }}
                </a-option>
              </a-select>
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item field="policy_id" label="告警策略">
              <a-select
                v-model="formData.policy_id"
                placeholder="请选择告警策略"
                :loading="policyLoading"
                allow-search
                :filter-option="false"
                @search="handlePolicySearch"
                @change="handlePolicyChange"
              >
                <a-option
                  v-for="item in policyOptions"
                  :key="item.id"
                  :value="item.id"
                >
                  {{ item.name }}
                </a-option>
              </a-select>
            </a-form-item>
          </a-col>
        </a-row>
      </a-form>
    </a-modal>
  </div>
</template>

<script lang="ts" setup>
import { computed, reactive, ref } from 'vue'
import { Message, Modal } from '@arco-design/web-vue'
import { IconPlus } from '@arco-design/web-vue/es/icon'
import { fetchPolicyList } from '@/api/ops/alertPolicy'
import { fetchSeverityOptions, type AlertSeverity } from '@/api/ops/alertTemplate'
import type { FormItem } from '@/components/search-form/types'
import SearchTable from '@/components/search-table/index.vue'
import type { TableColumnData } from '@arco-design/web-vue/es/table/interface'
import type { FormInstance } from '@arco-design/web-vue'
import {
  createTrapRule,
  deleteTrapRule,
  fetchTrapRules,
  unwrapLogsPayload,
  updateTrapRule,
  type TrapRule,
} from '@/api/ops/logs'

const loading = ref(false)
const tableData = ref<TrapRule[]>([])
const allRows = ref<TrapRule[]>([])
const formModel = ref({ keyword: '' })

function handleFormModelUpdate(v: Record<string, unknown>) {
  formModel.value = v as { keyword: string }
}
const modalVisible = ref(false)
const submitting = ref(false)
const editingId = ref<number | null>(null)
const formRef = ref<FormInstance>()

const emptyForm = (): TrapRule => ({
  name: '',
  enabled: true,
  priority: 0,
  oid_prefix: '',
  varbind_match_regex: '',
  alert_name: '',
  severity_code: '',
  policy_id: 0,
})

const formData = reactive<TrapRule>(emptyForm())

const severityOptions = ref<AlertSeverity[]>([])
const baseSeverityOptions = ref<AlertSeverity[]>([])
const severityLoading = ref(false)
let severitySearchTimer: ReturnType<typeof setTimeout> | null = null

type PolicyOption = { id: number; name: string }
const policyLoading = ref(false)
const policyOptions = ref<PolicyOption[]>([{ id: 0, name: '未绑定' }])
const basePolicyOptions = ref<PolicyOption[]>([{ id: 0, name: '未绑定' }])
let policySearchTimer: ReturnType<typeof setTimeout> | null = null

async function loadPolicyOptions(keyword?: string) {
  policyLoading.value = true
  try {
    const res: any = await fetchPolicyList({
      page: 1,
      page_size: keyword ? 50 : 1000,
      enabled: true,
      keyword: keyword || undefined,
    })

    const list = Array.isArray(res?.details)
      ? res.details
      : res?.details?.data ?? res?.details?.list ?? res?.data?.data ?? res?.data ?? []

    const fetchedOptions: PolicyOption[] = (Array.isArray(list) ? list : [])
      .map((p: any) => ({ id: Number(p.id), name: p.name || '' }))
      .filter((p: PolicyOption) => !Number.isNaN(p.id))

    const isBaseLoad = !keyword || keyword.trim().length === 0
    if (isBaseLoad) {
      basePolicyOptions.value = [{ id: 0, name: '未绑定' }, ...fetchedOptions]
    }

    const selectedId = formData.policy_id
    const selectedOptions = basePolicyOptions.value.filter((p) => p.id === selectedId)

    const mergedMap = new Map<number, PolicyOption>()
    ;[...fetchedOptions, ...selectedOptions].forEach((item) => {
      mergedMap.set(item.id, item)
    })
    mergedMap.set(0, { id: 0, name: '未绑定' })
    policyOptions.value = Array.from(mergedMap.values())
  } catch (e: any) {
    console.error('加载告警策略失败:', e)
    policyOptions.value = [{ id: 0, name: '未绑定' }]
    basePolicyOptions.value = [{ id: 0, name: '未绑定' }]
  } finally {
    policyLoading.value = false
  }
}

function handlePolicySearch(keyword: string) {
  if (policySearchTimer) {
    clearTimeout(policySearchTimer)
  }

  policySearchTimer = setTimeout(() => {
    loadPolicyOptions(keyword)
  }, 300)
}

function handlePolicyChange(v: any) {
  formData.policy_id = Number(v)
}

async function loadSeverityOptions(keyword?: string) {
  severityLoading.value = true
  try {
    const res: any = await fetchSeverityOptions({
      keyword,
      enabled: 'true',
    })
    const list = Array.isArray(res?.details)
      ? res.details
      : res?.details?.data || res?.details?.list || res?.data || res

    const fetchedOptions = Array.isArray(list) ? list : []

    const isBaseLoad = !keyword || keyword.trim().length === 0
    if (isBaseLoad) {
      baseSeverityOptions.value = fetchedOptions
    }

    const selectedCode = formData.severity_code
    const selectedOptions = baseSeverityOptions.value.filter((s) => s.code === selectedCode)

    const mergedMap = new Map<string, AlertSeverity>()
    ;[...fetchedOptions, ...selectedOptions].forEach((item) => {
      if (item?.code) mergedMap.set(item.code, item)
    })
    severityOptions.value = Array.from(mergedMap.values())
  } catch (e: any) {
    console.error('加载告警级别失败:', e)
    severityOptions.value = []
  } finally {
    severityLoading.value = false
  }
}

function handleSeveritySearch(keyword: string) {
  if (severitySearchTimer) {
    clearTimeout(severitySearchTimer)
  }

  severitySearchTimer = setTimeout(() => {
    loadSeverityOptions(keyword)
  }, 300)
}

const clientPagination = reactive({
  current: 1,
  pageSize: 20,
  total: 0,
})

const formItems = computed<FormItem[]>(() => [
  { field: 'keyword', label: '关键词', type: 'input', placeholder: '规则名 / OID', span: 8 },
])

const columns = computed<TableColumnData[]>(() => [
  { title: 'ID', dataIndex: 'id', width: 72 },
  { title: '名称', dataIndex: 'name', ellipsis: true, tooltip: true },
  { title: '优先级', dataIndex: 'priority', width: 80 },
  { title: '启用', dataIndex: 'enabled', slotName: 'enabled', width: 88 },
  { title: 'OID 前缀', dataIndex: 'oid_prefix', ellipsis: true, tooltip: true },
  { title: 'Varbind 正则', dataIndex: 'varbind_match_regex', ellipsis: true, tooltip: true },
  { title: '告警名', dataIndex: 'alert_name', ellipsis: true, tooltip: true },
  { title: '级别', dataIndex: 'severity_code', width: 90 },
  { title: '策略ID', dataIndex: 'policy_id', width: 88 },
  { title: '操作', slotName: 'operations', width: 160, fixed: 'right' },
])

function applyFilter(list: TrapRule[]) {
  const kw = formModel.value.keyword?.trim()
  if (!kw) return list
  return list.filter(
    r =>
      r.name?.includes(kw) ||
      r.oid_prefix?.includes(kw) ||
      r.alert_name?.includes(kw)
  )
}

function slicePage(list: TrapRule[]) {
  const start = (clientPagination.current - 1) * clientPagination.pageSize
  tableData.value = list.slice(start, start + clientPagination.pageSize)
}

async function fetchList() {
  loading.value = true
  try {
    const res: any = await fetchTrapRules()
    const payload = unwrapLogsPayload(res)
    const items = (payload?.items ?? []) as TrapRule[]
    allRows.value = items
    const filtered = applyFilter(items)
    clientPagination.total = filtered.length
    slicePage(filtered)
    if (typeof res.code === 'number' && res.code !== 0) {
      Message.error(res.message || res.msg || '加载失败')
    }
  } catch (e: any) {
    Message.error(e?.message || '加载失败')
    allRows.value = []
    tableData.value = []
    clientPagination.total = 0
  } finally {
    loading.value = false
  }
}

function handleSearch() {
  clientPagination.current = 1
  const filtered = applyFilter(allRows.value)
  clientPagination.total = filtered.length
  slicePage(filtered)
}

function handleReset() {
  formModel.value = { keyword: '' }
  clientPagination.current = 1
  const filtered = applyFilter(allRows.value)
  clientPagination.total = filtered.length
  slicePage(filtered)
}

function handlePageChange(c: number) {
  clientPagination.current = c
  slicePage(applyFilter(allRows.value))
}

function handlePageSizeChange(size: number) {
  clientPagination.pageSize = size
  clientPagination.current = 1
  slicePage(applyFilter(allRows.value))
}

function openCreate() {
  editingId.value = null
  Object.assign(formData, emptyForm())
  modalVisible.value = true
}

function openEdit(row: TrapRule) {
  if (!row.id) return
  editingId.value = row.id
  Object.assign(formData, {
    name: row.name,
    enabled: row.enabled,
    priority: row.priority,
    oid_prefix: row.oid_prefix ?? '',
    varbind_match_regex: row.varbind_match_regex ?? '',
    alert_name: row.alert_name ?? '',
    severity_code: row.severity_code ?? '',
    policy_id: row.policy_id ?? 0,
  })
  modalVisible.value = true
}

async function submitForm() {
  const err = await formRef.value?.validate()
  if (err) return
  submitting.value = true
  try {
    if (editingId.value != null) {
      const res: any = await updateTrapRule(editingId.value, { ...formData })
      if (typeof res.code === 'number' && res.code !== 0) {
        Message.error(res.message || res.msg || '保存失败')
        return
      }
      Message.success('已保存')
    } else {
      const res: any = await createTrapRule({ ...formData })
      if (typeof res.code === 'number' && res.code !== 0) {
        Message.error(res.message || res.msg || '创建失败')
        return
      }
      Message.success('已创建')
    }
    modalVisible.value = false
    await fetchList()
  } catch (e: any) {
    Message.error(e?.message || '请求失败')
  } finally {
    submitting.value = false
  }
}

function handleDelete(row: TrapRule) {
  if (!row.id) return
  Modal.confirm({
    title: '确认删除',
    content: `删除规则「${row.name}」？`,
    onOk: async () => {
      try {
        const res: any = await deleteTrapRule(row.id!)
        if (typeof res.code === 'number' && res.code !== 0) {
          Message.error(res.message || res.msg || '删除失败')
          return
        }
        Message.success('已删除')
        await fetchList()
      } catch (e: any) {
        Message.error(e?.message || '删除失败')
      }
    },
  })
}

fetchList()
loadSeverityOptions()
loadPolicyOptions()
</script>

<script lang="ts">
export default { name: 'LogMgmtTrapRules' }
</script>

<style scoped lang="less">
.container {
  padding: 16px;
}
</style>
