<script setup lang="ts">
import {
  NButton,
  NDataTable,
  NPopconfirm,
  NSpin,
  type DataTableColumns,
} from 'naive-ui'
import { computed, h, ref } from 'vue'
import { RouterLink, useRoute, useRouter } from 'vue-router'

import { deleteVcn, enableVcnIpv6, getVcn, listSecurityLists, listSubnets, renameVcn } from '@/api/networks'
import FootNote from '@/components/FootNote.vue'
import LifecycleBadge from '@/components/LifecycleBadge.vue'
import RenameModal from '@/components/RenameModal.vue'
import StatusBadge from '@/components/StatusBadge.vue'
import { fmtTime } from '@/composables/useFormat'
import { useAsync } from '@/composables/useAsync'
import type { Ipv6Step, SecurityList, Subnet } from '@/types/api'
import { useToast } from '@/composables/useToast'

const route = useRoute()
const router = useRouter()
const message = useToast()

const cfgId = computed(() => Number(route.params.cfgId))
const vcnId = computed(() => String(route.params.vcnId))
/** 列表页跳转时带上查询区域，非主区域 VCN 的所有请求都要发往该区域 */
const region = computed(() => (route.query.region as string) || undefined)

const vcn = useAsync(() => getVcn(cfgId.value, vcnId.value, region.value))
const subnets = useAsync(() => listSubnets(cfgId.value, vcnId.value, region.value))
const seclists = useAsync(() => listSecurityLists(cfgId.value, vcnId.value, region.value))

const ipv6Steps = ref<Ipv6Step[] | null>(null)
const enabling = ref(false)

async function runEnableIpv6() {
  enabling.value = true
  try {
    const report = await enableVcnIpv6(cfgId.value, vcnId.value, region.value)
    ipv6Steps.value = report.steps
    const failed = report.steps.filter((s) => s.status === 'failed').length
    if (failed) message.warning(`${failed} 个步骤失败，详见执行报告`)
    else message.success('一键 IPv6 执行完成')
    void vcn.run()
    void subnets.run()
  } catch (e) {
    message.error(e instanceof Error ? e.message : '执行失败')
  } finally {
    enabling.value = false
  }
}

const removing = ref(false)

async function removeVcn() {
  removing.value = true
  try {
    await deleteVcn(cfgId.value, vcnId.value, region.value)
    message.success('VCN 已删除')
    void router.push({ name: 'network' })
  } catch (e) {
    message.error(e instanceof Error ? e.message : '删除失败')
  } finally {
    removing.value = false
  }
}

const showRename = ref(false)
const renaming = ref(false)

async function doRename(name: string) {
  renaming.value = true
  try {
    await renameVcn(cfgId.value, vcnId.value, name, region.value)
    message.success('已重命名')
    showRename.value = false
    void vcn.run()
  } catch (e) {
    message.error(e instanceof Error ? e.message : '重命名失败')
  } finally {
    renaming.value = false
  }
}

const subnetColumns: DataTableColumns<Subnet> = [
  {
    title: '子网',
    key: 'displayName',
    minWidth: 170,
    render: (row) =>
      h('div', [
        h('div', { class: 'font-medium' }, row.displayName),
        h('div', { class: 'mono text-xs text-ink-3 mt-px' }, row.dnsLabel),
      ]),
  },
  {
    title: 'IPv4 CIDR',
    key: 'cidrBlock',
    minWidth: 120,
    render: (r) => h('span', { class: 'mono' }, r.cidrBlock),
  },
  {
    title: 'IPv6 /64',
    key: 'ipv6CidrBlock',
    minWidth: 200,
    render: (r) =>
      r.ipv6CidrBlock
        ? h('span', { class: 'mono text-[12.5px]' }, r.ipv6CidrBlock)
        : h('span', { class: 'text-xs text-ink-3' }, '未启用'),
  },
  {
    title: '公网 IP',
    key: 'prohibitPublicIp',
    width: 100,
    render: (r) =>
      h(StatusBadge, {
        kind: r.prohibitPublicIp ? 'stop' : 'run',
        label: r.prohibitPublicIp ? '禁止' : '允许',
        dot: false,
      }),
  },
  {
    title: '状态',
    key: 'lifecycleState',
    width: 120,
    render: (r) => h(LifecycleBadge, { state: r.lifecycleState }),
  },
]

function ruleSummary(list: SecurityList): string {
  const ingress = list.ingressRules ?? []
  const egress = list.egressRules ?? []
  const ing = ingress.length
  const eg = egress.length
  const allOpen =
    ingress.some((r) => r.protocol === 'all' && r.source === '0.0.0.0/0') &&
    egress.some((r) => r.protocol === 'all' && r.destination === '0.0.0.0/0')
  return allOpen ? `出入全放行 · 入 ${ing} / 出 ${eg}` : `入 ${ing} / 出 ${eg}`
}

const seclistColumns: DataTableColumns<SecurityList> = [
  {
    title: '安全列表',
    key: 'displayName',
    minWidth: 240,
    render: (row) => h('span', { class: 'font-medium' }, row.displayName),
  },
  {
    title: '规则',
    key: 'rules',
    minWidth: 180,
    render: (row) => h('span', { class: 'text-[13px] text-ink-2' }, ruleSummary(row)),
  },
  {
    title: '状态',
    key: 'lifecycleState',
    width: 120,
    render: (r) => h(LifecycleBadge, { state: r.lifecycleState }),
  },
]

const stepColumns: DataTableColumns<Ipv6Step> = [
  {
    title: '步骤',
    key: 'step',
    minWidth: 170,
    render: (r) => h('span', { class: 'mono text-[12.5px]' }, r.step),
  },
  {
    title: '状态',
    key: 'status',
    width: 110,
    render: (r) =>
      h(StatusBadge, {
        kind: r.status === 'done' ? 'run' : r.status === 'skipped' ? 'check' : 'term',
        label: r.status,
      }),
  },
  {
    title: '详情',
    key: 'detail',
    minWidth: 260,
    render: (r) => h('span', { class: 'mono text-xs break-all' }, r.detail),
  },
]
</script>

<template>
  <div class="flex flex-col gap-4 p-6 pb-8 max-md:p-3">
    <div
      v-if="vcn.loading.value && !vcn.data.value"
      class="panel flex items-center justify-center py-20"
    >
      <NSpin size="small" />
    </div>
    <div v-else-if="vcn.error.value" class="panel px-5 py-10 text-center text-[13px] text-ink-3">
      {{ vcn.error.value }}
    </div>

    <div v-if="vcn.data.value" class="panel px-5 py-4">
      <RouterLink
        class="mb-2 inline-flex items-center gap-1.5 text-[13px] text-ink-3 hover:text-ink"
        :to="{ name: 'network' }"
      >
        ← 返回网络列表
      </RouterLink>
      <div class="flex flex-wrap items-center gap-3">
        <h1 class="page-title">{{ vcn.data.value.displayName }}</h1>
        <LifecycleBadge :state="vcn.data.value.lifecycleState" />
        <StatusBadge
          v-if="vcn.data.value.ipv6CidrBlocks?.length"
          kind="prov"
          label="IPv6 已启用"
          :dot="false"
        />
        <div class="flex-1" />
        <NButton size="small" @click="showRename = true">重命名</NButton>
        <NPopconfirm @positive-click="removeVcn">
          <template #trigger>
            <NButton size="small" type="error" ghost :loading="removing" :disabled="removing">
              {{ removing ? '删除中…' : '删除 VCN' }}
            </NButton>
          </template>
          删除 VCN？将级联删除其子网、网关、路由等关联资源；子网仍被实例占用时会失败，需先终止实例
        </NPopconfirm>
      </div>
      <div class="mt-3 grid grid-cols-4 gap-4 max-lg:grid-cols-2 max-md:grid-cols-1">
        <div class="min-w-0">
          <div class="text-xs text-ink-3">IPv4 CIDR</div>
          <div class="mono mt-0.5 text-[13px]">{{ (vcn.data.value.cidrBlocks ?? []).join(', ') }}</div>
        </div>
        <div class="min-w-0">
          <div class="text-xs text-ink-3">IPv6 CIDR</div>
          <div class="mono mt-0.5 text-[13px] break-all">
            {{ (vcn.data.value.ipv6CidrBlocks ?? []).join(', ') || '未启用' }}
          </div>
        </div>
        <div class="min-w-0">
          <div class="text-xs text-ink-3">DNS Label</div>
          <div class="mono mt-0.5 text-[13px]">{{ vcn.data.value.dnsLabel || '—' }}</div>
        </div>
        <div class="min-w-0">
          <div class="text-xs text-ink-3">创建时间</div>
          <div class="mt-0.5 text-[13px]">{{ fmtTime(vcn.data.value.timeCreated) }}</div>
        </div>
      </div>
    </div>

    <div class="panel">
      <div class="border-b border-line-soft px-4.5 py-3.5 text-sm font-semibold">子网</div>
      <NDataTable
        :columns="subnetColumns"
        :data="subnets.data.value ?? []"
        :loading="subnets.loading.value"
        :scroll-x="760"
        :row-key="(r: Subnet) => r.id"
      />
    </div>

    <div class="panel">
      <div class="border-b border-line-soft px-4.5 py-3.5 text-sm font-semibold">安全列表</div>
      <NDataTable
        :columns="seclistColumns"
        :data="seclists.data.value ?? []"
        :loading="seclists.loading.value"
        :scroll-x="600"
        :row-key="(r: SecurityList) => r.id"
      />
      <FootNote>
        更新安全列表时规则字段一经提供即全量替换；protocol 取 all / 6(TCP) / 17(UDP) / 1(ICMP) /
        58(ICMPv6)
      </FootNote>
    </div>

    <div class="panel">
      <div class="flex items-center justify-between border-b border-line-soft px-4.5 py-3.5">
        <div class="text-sm font-semibold">一键启用 IPv6</div>
        <NButton size="small" type="primary" :loading="enabling" @click="runEnableIpv6">
          {{ ipv6Steps ? '重新执行' : '执行' }}
        </NButton>
      </div>
      <NDataTable
        v-if="ipv6Steps"
        :columns="stepColumns"
        :data="ipv6Steps"
        :scroll-x="620"
        :row-key="(r: Ipv6Step) => r.step"
      />
      <div v-else class="px-4.5 py-4 text-[13px] text-ink-3">
        依次执行：VCN 分配 /56 → 子网分配 /64 → 默认路由补 ::/0 → 默认安全列表放行 IPv6
        出方向；全部步骤幂等，已配置的自动跳过。
      </div>
      <FootNote>
        只改默认路由表与默认安全列表；实例要实际获得 IPv6 还需在创建实例 / VNIC 时启用 IPv6 分配
      </FootNote>
    </div>

    <RenameModal
      v-model:show="showRename"
      title="重命名 VCN"
      :current="vcn.data.value?.displayName ?? ''"
      :submitting="renaming"
      @submit="doRename"
    />
  </div>
</template>
