<template>
  <XtfConfigProvider class="demo-theme-root" :theme="demoTheme">
  <XtfBubbleMenuHost>
    <scroll-view id="bubble-demo-scroll" class="bubble-demo-scroll" direction="vertical">
      <view class="bubble-demo-page">
        <text class="bubble-demo-title">Bubble Menu</text>
        <text class="bubble-demo-heading">八个方向与窗口边界</text>
        <view class="bubble-demo-directions">
          <XtfBubbleMenu v-for="placement in placements" :key="placement" :actions="shortActions" :placement="placement" :width="240" @update:show="recordUpdate" @open="recordOpen" @close="recordClose" @select="handleSelect">
            <view :id="'bubble-trigger-' + placement" class="bubble-demo-trigger" @click="recordPointer"><text class="bubble-demo-label">{{ placement }}</text></view>
          </XtfBubbleMenu>
        </view>

        <text class="bubble-demo-heading">真实点击与业务载荷</text>
        <XtfBubbleMenu :actions="richActions" :image-size="42" @update:show="recordUpdate" @open="recordOpen" @close="recordClose" @select="handleSelect">
          <view id="bubble-trigger-rich" class="bubble-demo-trigger" @click="recordPointer"><text class="bubble-demo-label">订单操作</text></view>
        </XtfBubbleMenu>

        <text class="bubble-demo-heading">禁用与显示覆盖</text>
        <XtfBubbleMenu :actions="shortActions" disabled @update:show="recordUpdate" @open="recordOpen" @select="handleSelect">
          <view id="bubble-trigger-disabled" class="bubble-demo-trigger" @click="recordPointer"><text class="bubble-demo-muted">禁用触发器</text></view>
        </XtfBubbleMenu>
        <XtfBubbleMenu :actions="overrideActions" :show-icon="false" :show-suffix="false" :arrow="false" :width="600" :max-width="340" :offset="28" @open="recordOpen" @close="recordClose" @select="handleSelect">
          <view id="bubble-trigger-overrides" class="bubble-demo-trigger"><text class="bubble-demo-label">单项覆盖 / 无箭头 / 最大宽度</text></view>
        </XtfBubbleMenu>

        <text class="bubble-demo-heading">关闭策略</text>
        <XtfBubbleMenu v-model:show="policyShow" :actions="shortActions" :close-on-click-outside="outsideClosable" :close-on-click-action="actionClosable" :before-close="beforeClose" @update:show="recordUpdate" @open="recordOpen" @close="recordClose" @select="handleSelect">
          <view id="bubble-trigger-policy" class="bubble-demo-trigger"><text class="bubble-demo-label">关闭策略菜单</text></view>
        </XtfBubbleMenu>
        <view class="bubble-demo-setting"><text class="bubble-demo-setting-label">允许关闭</text><switch id="bubble-allow-close" :checked="allowClose" @change="allowClose = $event.detail.value" /></view>
        <view class="bubble-demo-setting"><text class="bubble-demo-setting-label">外部关闭</text><switch id="bubble-outside-close" :checked="outsideClosable" @change="outsideClosable = $event.detail.value" /></view>
        <view class="bubble-demo-setting"><text class="bubble-demo-setting-label">选择后关闭</text><switch id="bubble-action-close" :checked="actionClosable" @change="actionClosable = $event.detail.value" /></view>

        <text class="bubble-demo-heading">手动与连续开关</text>
        <XtfBubbleMenu v-model:show="manualShow" trigger="manual" :actions="shortActions" :transition-duration="220" @open="recordOpen" @close="recordClose" @select="handleSelect">
          <view id="bubble-trigger-manual" class="bubble-demo-trigger"><text class="bubble-demo-label">手动锚点</text></view>
        </XtfBubbleMenu>
        <view class="bubble-demo-row"><XtfButton id="bubble-manual-open" size="sm" label="手动打开" @click="manualShow = true" /><XtfButton id="bubble-cycle" size="sm" type="outline" label="连续开关" @click="cycleMenu" /></view>

        <text class="bubble-demo-heading">Content 与 Item 插槽</text>
        <XtfBubbleMenu v-model:show="contentShow" :actions="shortActions" :width="360" @open="recordOpen" @close="recordClose" @select="handleSelect">
          <view id="bubble-trigger-content" class="bubble-demo-trigger"><text class="bubble-demo-label">自定义面板</text></view>
          <template #content="scope">
            <view class="bubble-demo-content">
              <text class="bubble-demo-slot-title">订单 #A1024</text>
              <view id="bubble-content-select" class="bubble-demo-slot-action" @click.stop="scope.select(scope.actions[0].raw, 0)"><text class="bubble-demo-slot-text">分享订单</text></view>
              <view id="bubble-content-close" class="bubble-demo-slot-action" @click.stop="contentShow = false"><text class="bubble-demo-slot-text">关闭</text></view>
            </view>
          </template>
        </XtfBubbleMenu>
        <XtfBubbleMenu :actions="richActions" @open="recordOpen" @close="recordClose" @select="handleSelect">
          <view id="bubble-trigger-item" class="bubble-demo-trigger"><text class="bubble-demo-label">自定义菜单项</text></view>
          <template #item="scope"><text :id="'bubble-slot-item-' + scope.index.toString()" class="bubble-demo-slot-text">{{ scope.index + 1 }}. {{ scope.action.label }}</text></template>
        </XtfBubbleMenu>
        <text class="bubble-demo-heading">悬停与触摸点击</text>
        <XtfBubbleMenu trigger="hover" :actions="shortActions" @open="recordOpen" @close="recordClose" @select="handleSelect">
          <view id="bubble-trigger-hover" class="bubble-demo-trigger"><text class="bubble-demo-label">鼠标悬停或触摸点击打开</text></view>
        </XtfBubbleMenu>
        <text class="bubble-demo-result">鼠标悬停打开、移出关闭；触摸点击切换，点击外部关闭。</text>
        <view class="bubble-demo-bottom-space"></view>
      </view>
    </scroll-view>
    <view class="bubble-demo-results">
      <text id="bubble-pointer" class="bubble-demo-result">{{ pointer }}</text>
      <text id="bubble-state" class="bubble-demo-result">open={{ openCount }} close={{ closeCount }} select={{ selectCount }}</text>
      <text id="bubble-update" class="bubble-demo-result">update:show={{ updateCount }} value={{ lastShow }}</text>
      <text id="bubble-payload" class="bubble-demo-result">{{ payload }}</text>
      <text id="bubble-close-result" class="bubble-demo-result">{{ closeResult }}</text>
    </view>
    <view class="bubble-demo-toolbar"><XtfButton id="bubble-manual-close" size="sm" type="outline" label="手动关闭" @click="manualShow = false" /><XtfButton id="bubble-policy-close" size="sm" type="ghost" label="受控关闭" @click="policyShow = false" /></view>
  </XtfBubbleMenuHost>
  </XtfConfigProvider>
</template>

<script setup lang="uts">
import { useDemoTheme } from '@/pages/demo-theme.uts'
import XtfConfigProvider from '@/uni_modules/xtf-linkuiunix/components/xtf-config-provider/xtf-config-provider.uvue'
const demoTheme = useDemoTheme()
import { nextTick, onUnmounted, ref } from "vue"
import XtfBubbleMenu from "../../../uni_modules/xtf-linkuiunix/components/xtf-bubble-menu/xtf-bubble-menu.uvue"
import XtfBubbleMenuHost from "../../../uni_modules/xtf-linkuiunix/components/xtf-bubble-menu-host/xtf-bubble-menu-host.uvue"
import XtfButton from "../../../uni_modules/xtf-linkuiunix/components/xtf-button/xtf-button.uvue"
import type { XtfBubbleMenuPlacement } from "../../../uni_modules/xtf-linkuiunix/libs/bubble-menu/index"

const placements: XtfBubbleMenuPlacement[] = ["top-start", "top", "top-end", "left", "right", "bottom-start", "bottom", "bottom-end"]
const shortActions = [{ key: "share", label: "分享", icon: "share", orderId: "A1024", data: { source: "bubble-demo" } }, { key: "favorite", label: "收藏并保持", icon: "favorite", keepOpen: true }]
const richActions = [
  { key: "image", label: "图片优先", description: "订单 A1024", image: "/static/logo.png", icon: "info", orderId: "A1024", data: { source: "bubble-demo" } },
  { key: "danger", label: "删除订单", desc: "危险操作", icon: "error", danger: true },
  { key: "disabled", label: "当前不可用", icon: "info", disabled: true },
  { value: "stay", name: "保持打开", desc: "收藏订单", icon: "favorite", keepOpen: true }
]
const overrideActions = [{ label: "单项强制显示", icon: "info", showIcon: true, showSuffix: true }, { label: "继承全局隐藏", icon: "info" }]
const manualShow = ref(false)
const policyShow = ref(false)
const contentShow = ref(false)
const allowClose = ref(true)
const outsideClosable = ref(true)
const actionClosable = ref(true)
const openCount = ref(0)
const closeCount = ref(0)
const selectCount = ref(0)
const updateCount = ref(0)
const lastShow = ref(false)
const pointer = ref("clientX/clientY: -")
const payload = ref("select: -")
const closeResult = ref("beforeClose: -")
let cycleTimer: ReturnType<typeof setTimeout> | null = null
let cycleVersion = 0

function recordPointer(event: UniPointerEvent): void { pointer.value = "clientX=" + event.clientX.toString() + " clientY=" + event.clientY.toString() }
function recordOpen(): void { openCount.value += 1 }
function recordClose(): void { closeCount.value += 1 }
function recordUpdate(value: boolean): void { updateCount.value += 1; lastShow.value = value }
function handleSelect(event: UTSJSONObject): void { selectCount.value += 1; payload.value = JSON.stringify(event) }
function beforeClose(event: UTSJSONObject): boolean { closeResult.value = JSON.stringify(event) + " allowed=" + allowClose.value.toString(); return allowClose.value }
function cycleMenu(): void {
  cycleVersion += 1
  const version = cycleVersion
  if (cycleTimer != null) clearTimeout(cycleTimer)
  manualShow.value = false
  nextTick(() => {
    if (version != cycleVersion) return
    manualShow.value = true
    cycleTimer = setTimeout(() => {
      manualShow.value = false
      nextTick(() => {
        if (version != cycleVersion) return
        manualShow.value = true
      })
    }, 40)
  })
}
onUnmounted(() => { cycleVersion += 1; if (cycleTimer != null) clearTimeout(cycleTimer) })
</script>

<style>
.bubble-demo-scroll { display: flex; flex: 1; flex-direction: column; min-height: 0; }
.bubble-demo-page { display: flex; flex-direction: column; padding: 16px; background-color: var(--xtf-color-page, #f8fafc); }
.bubble-demo-title { font-size: 24px; font-weight: 700; color: var(--xtf-color-text, #111827); }
.bubble-demo-heading { font-size: 16px; font-weight: 600; color: var(--xtf-color-text, #111827); margin-top: 24px; margin-bottom: 8px; }
.bubble-demo-directions { display: flex; flex-direction: row; flex-wrap: wrap; justify-content: space-between; }
.bubble-demo-trigger { display: flex; flex-direction: row; align-items: center; min-height: 44px; padding: 10px; margin-bottom: 8px; border-width: 1px; border-color: var(--xtf-color-border, #cbd5e1); border-style: solid; border-radius: 6px; background-color: var(--xtf-color-surface, #ffffff); }
.bubble-demo-label { font-size: 14px; color: #2563eb; }
.bubble-demo-muted { font-size: 14px; color: var(--xtf-color-text-disabled, #94a3b8); }
.bubble-demo-setting { display: flex; flex-direction: row; align-items: center; justify-content: space-between; min-height: 44px; }
.bubble-demo-setting-label { font-size: 14px; color: var(--xtf-color-text-secondary, #334155); }
.bubble-demo-row { display: flex; flex-direction: row; flex-wrap: wrap; justify-content: space-between; margin-top: 8px; }
.bubble-demo-results { display: flex; flex-direction: column; padding: 12px 16px; background-color: var(--xtf-color-surface, #ffffff); z-index: 1; border-top-width: 1px; border-top-color: var(--xtf-color-border, #cbd5e1); border-top-style: solid; }
.bubble-demo-toolbar { display: flex; flex-direction: row; justify-content: space-between; padding: 8px 16px 16px; background-color: var(--xtf-color-surface, #ffffff); z-index: 4000; }
.bubble-demo-result { font-size: 12px; line-height: 18px; color: var(--xtf-color-text-secondary, #334155); }
.bubble-demo-content { display: flex; flex-direction: column; padding: 16px; }
.bubble-demo-slot-title { font-size: 16px; color: #ffffff; font-weight: 600; }
.bubble-demo-slot-action { display: flex; flex-direction: row; padding-top: 12px; padding-bottom: 12px; }
.bubble-demo-slot-text { font-size: 14px; color: #ffffff; }
.bubble-demo-bottom-space { display: flex; flex-direction: column; height: 180px; }
</style>
