<template>
  <div class="page">
    <PageHeader :title="t('ipRules.title')" :description="t('ipRules.description')">
      <template #actions>
        <el-button @click="load">{{ t('common.refresh') }}</el-button>
        <el-button type="primary" @click="openDialog()">{{ t('ipRules.add') }}</el-button>
      </template>
    </PageHeader>

    <AppCard>
      <el-table :data="list" v-loading="loading" size="small">
        <el-table-column prop="id" :label="t('common.id')" width="60" />
        <el-table-column prop="pattern" :label="t('ipRules.pattern')" min-width="160" />
        <el-table-column :label="t('ipRules.ruleType')" width="100">
          <template #default="{ row }">
            <el-tag :type="ruleTypeTag(row)" size="small">{{ ruleTypeLabel(row) }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column :label="t('ipRules.resourceType')" width="100">
          <template #default="{ row }">{{ resourceTypeLabel(row) }}</template>
        </el-table-column>
        <el-table-column :label="t('ipRules.resource')" min-width="160" show-overflow-tooltip>
          <template #default="{ row }">{{ resourceLabel(row) }}</template>
        </el-table-column>
        <el-table-column :label="t('common.actions')" width="140" fixed="right">
          <template #default="{ row }">
            <el-button size="small" link type="primary" @click="openDialog(row)">{{ t('common.edit') }}</el-button>
            <el-button size="small" link type="danger" @click="remove(row)">{{ t('common.delete') }}</el-button>
          </template>
        </el-table-column>
      </el-table>
    </AppCard>

    <el-dialog
      v-model="dialogVisible"
      :title="form.id ? t('ipRules.edit') : t('ipRules.add')"
      width="520px"
      destroy-on-close
    >
      <el-form :model="form" label-width="100px">
        <el-form-item :label="t('ipRules.pattern')"><el-input v-model="form.pattern" :placeholder="t('ipRules.patternPlaceholder')" /></el-form-item>
        <el-form-item :label="t('ipRules.ruleType')">
          <el-select v-model="form.rule_type">
            <el-option :label="t('ipRules.allow')" value="allow" />
            <el-option :label="t('ipRules.deny')" value="deny" />
          </el-select>
        </el-form-item>
        <el-form-item :label="t('ipRules.resourceType')">
          <el-select v-model="form.resource_type" class="w-full">
            <el-option :label="t('ipRules.global')" value="global" />
            <el-option :label="t('ipRules.tunnel')" value="tunnel" />
            <el-option :label="t('ipRules.host')" value="host" />
          </el-select>
        </el-form-item>
        <el-form-item v-if="form.resource_type !== 'global'" :label="t('ipRules.resource')" required>
          <el-select
            v-model="form.resource_id"
            filterable
            class="w-full"
            :placeholder="t('ipRules.selectResource')"
            :loading="resourcesLoading"
            :no-data-text="t('ipRules.noResource')"
          >
            <el-option
              v-for="item in resourceOptions"
              :key="item.id"
              :label="item.label"
              :value="item.id"
            />
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="dialogVisible = false">{{ t('common.cancel') }}</el-button>
        <el-button type="primary" @click="save">{{ t('common.save') }}</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, computed, watch, onMounted } from 'vue'
import { useI18n } from 'vue-i18n'
import { ElMessage, ElMessageBox } from 'element-plus'
import PageHeader from '@/components/PageHeader.vue'
import AppCard from '@/components/AppCard.vue'
import api from '@/api'

const { t } = useI18n()
const list = ref([])
const tunnels = ref([])
const hosts = ref([])
const loading = ref(false)
const resourcesLoading = ref(false)
const dialogVisible = ref(false)
const form = reactive({
  id: null,
  pattern: '',
  rule_type: 'deny',
  resource_type: 'global',
  resource_id: null,
})

const resourceOptions = computed(() => {
  if (form.resource_type === 'tunnel') {
    return tunnels.value.map((item) => ({
      id: item.id,
      label: `${item.name} (#${item.id}) · :${item.listen_port}`,
    }))
  }
  if (form.resource_type === 'host') {
    return hosts.value.map((item) => ({
      id: item.id,
      label: `${item.host} (#${item.id})`,
    }))
  }
  return []
})

watch(
  () => form.resource_type,
  (type) => {
    if (type === 'global') {
      form.resource_id = null
      return
    }
    const options = resourceOptions.value
    if (!options.some((item) => item.id === form.resource_id)) {
      form.resource_id = options[0]?.id ?? null
    }
  },
)

function ruleScope(row) {
  return row.scope || row.resource_type || 'global'
}

function ruleTypeLabel(row) {
  const type = row.type || row.rule_type
  if (type === 'allow') return t('ipRules.allow')
  if (type === 'deny') return t('ipRules.deny')
  return type || '—'
}

function ruleTypeTag(row) {
  const type = row.type || row.rule_type
  if (type === 'allow') return 'success'
  if (type === 'deny') return 'danger'
  return 'info'
}

function resourceTypeLabel(row) {
  const scope = ruleScope(row)
  if (scope === 'global') return t('ipRules.global')
  if (scope === 'tunnel') return t('ipRules.tunnel')
  if (scope === 'host') return t('ipRules.host')
  return scope
}

function resourceLabel(row) {
  const scope = ruleScope(row)
  const id = row.resource_id
  if (scope === 'global' || !id) return '—'
  if (scope === 'tunnel') {
    const item = tunnels.value.find((tunnel) => tunnel.id === id)
    return item ? `${item.name} (#${id})` : `#${id}`
  }
  if (scope === 'host') {
    const item = hosts.value.find((host) => host.id === id)
    return item ? `${item.host} (#${id})` : `#${id}`
  }
  return `#${id}`
}

function rowToForm(row) {
  return {
    id: row.id,
    pattern: row.pattern,
    rule_type: row.type || row.rule_type || 'deny',
    resource_type: ruleScope(row),
    resource_id: row.resource_id || null,
  }
}

function formToPayload() {
  return {
    pattern: form.pattern,
    scope: form.resource_type,
    type: form.rule_type,
    resource_id: form.resource_type === 'global' ? 0 : form.resource_id,
  }
}

async function loadResources() {
  resourcesLoading.value = true
  try {
    const [tunnelsRes, hostsRes] = await Promise.all([
      api.get('/tunnels', { params: { page: 1, page_size: 1000 } }),
      api.get('/hosts', { params: { page: 1, page_size: 1000 } }),
    ])
    tunnels.value = tunnelsRes.data.items || []
    hosts.value = hostsRes.data.items || []
  } finally {
    resourcesLoading.value = false
  }
}

async function load() {
  loading.value = true
  try {
    const [rulesRes] = await Promise.all([api.get('/security/ip-rules'), loadResources()])
    list.value = rulesRes.data
  } finally {
    loading.value = false
  }
}

function openDialog(row) {
  if (row) Object.assign(form, rowToForm(row))
  else {
    Object.assign(form, {
      id: null,
      pattern: '',
      rule_type: 'deny',
      resource_type: 'global',
      resource_id: null,
    })
  }
  dialogVisible.value = true
}

async function save() {
  if (form.resource_type !== 'global' && !form.resource_id) {
    ElMessage.warning(t('ipRules.resourceRequired'))
    return
  }
  const payload = formToPayload()
  if (form.id) await api.put(`/security/ip-rules/${form.id}`, payload)
  else await api.post('/security/ip-rules', payload)
  ElMessage.success(t('message.saveSuccess'))
  dialogVisible.value = false
  load()
}

async function remove(row) {
  await ElMessageBox.confirm(t('ipRules.confirmDelete'), t('common.hint'), { type: 'warning' })
  await api.delete(`/security/ip-rules/${row.id}`)
  ElMessage.success(t('message.deleteSuccess'))
  load()
}

onMounted(load)
</script>
