<script setup lang="ts">
import { NButton, NPopover, type PopoverPlacement } from 'naive-ui'
import { ref } from 'vue'

export type ConfirmKind = 'danger' | 'warn' | 'plain'

/**
 * 统一确认气泡:替代 NPopconfirm 默认样式(批次8 设计稿)。
 * onConfirm 返回 Promise 时确认按钮进入 loading,期间弹层不可关闭、不可重复提交。
 */
const props = withDefaults(
  defineProps<{
    title: string
    content?: string
    note?: string
    kind?: ConfirmKind
    confirmText?: string
    cancelText?: string
    placement?: PopoverPlacement
    onConfirm?: () => unknown
  }>(),
  {
    kind: 'danger',
    confirmText: '确认',
    cancelText: '取消',
    placement: 'top',
    content: undefined,
    note: undefined,
    onConfirm: undefined,
  },
)

const show = ref(false)
const loading = ref(false)

function onUpdateShow(v: boolean) {
  if (loading.value) return
  show.value = v
}

async function confirm() {
  if (loading.value) return
  const r = props.onConfirm?.()
  if (r instanceof Promise) {
    loading.value = true
    try {
      await r
    } finally {
      loading.value = false
    }
  }
  show.value = false
}
</script>

<template>
  <NPopover
    :show="show"
    trigger="click"
    :placement="placement"
    raw
    :show-arrow="false"
    @update:show="onUpdateShow"
  >
    <template #trigger><slot name="trigger" /></template>
    <div
      class="w-[268px] rounded-lg border border-line bg-white p-4 pb-3.5 shadow-overlay"
    >
      <div class="flex items-center gap-2.5">
        <span
          class="flex h-[26px] w-[26px] flex-none items-center justify-center rounded-[7px]"
          :class="
            kind === 'danger'
              ? 'bg-err/12 text-err'
              : kind === 'warn'
                ? 'bg-warn/14 text-warn'
                : 'bg-wash text-ink-2'
          "
        >
          <svg
            v-if="kind === 'danger'"
            width="14"
            height="14"
            viewBox="0 0 24 24"
            fill="none"
            stroke="currentColor"
            stroke-width="2"
            stroke-linecap="round"
            stroke-linejoin="round"
          >
            <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" />
            <line x1="12" y1="9" x2="12" y2="13" />
            <line x1="12" y1="17" x2="12.01" y2="17" />
          </svg>
          <svg
            v-else-if="kind === 'warn'"
            width="14"
            height="14"
            viewBox="0 0 24 24"
            fill="none"
            stroke="currentColor"
            stroke-width="2"
            stroke-linecap="round"
            stroke-linejoin="round"
          >
            <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" />
          </svg>
          <svg
            v-else
            width="14"
            height="14"
            viewBox="0 0 24 24"
            fill="none"
            stroke="currentColor"
            stroke-width="2"
            stroke-linecap="round"
            stroke-linejoin="round"
          >
            <circle cx="12" cy="12" r="10" />
            <line x1="12" y1="16" x2="12" y2="12" />
            <line x1="12" y1="8" x2="12.01" y2="8" />
          </svg>
        </span>
        <!-- 超长资源名(如桶名)单行截断,悬停 tooltip 看全文 -->
        <span class="min-w-0 truncate text-[13.5px] font-semibold" :title="title">{{ title }}</span>
      </div>
      <div v-if="content" class="mt-2 pl-9 text-[12.5px] leading-relaxed text-ink-2">
        {{ content }}
      </div>
      <div v-if="note" class="mt-1 pl-9 text-xs leading-normal text-ink-3">{{ note }}</div>
      <div class="mt-3 flex justify-end gap-2">
        <NButton size="small" :disabled="loading" @click="show = false">{{ cancelText }}</NButton>
        <NButton
          size="small"
          :type="kind === 'danger' ? 'error' : 'primary'"
          :loading="loading"
          @click="confirm"
        >
          {{ confirmText }}
        </NButton>
      </div>
    </div>
  </NPopover>
</template>
