<template>
  <XtfConfigProvider class="demo-theme-root" :theme="demoTheme">
    <view class="page">
      <scroll-view class="scroll xtf-page-scroll" direction="vertical">
        <view class="body xtf-safe-bottom xtf-page-scroll-content">
          <view class="hero">
            <XtfText level="display" color="inverse" text="Toast" />
            <XtfText level="caption" color="inverse" text="状态提示、位置、视觉样式与布局" />
          </view>
          <view class="section">
            <XtfText level="h3" text="服务调用" />
            <XtfButton id="toast-service-open" label="发送常驻提示" @click="toastManager.show({ message: 'service-first', duration: 0 })" />
            <XtfButton id="toast-service-queue" label="排队提示" type="light" @click="toastManager.show({ message: 'service-next', duration: 800, mode: 'queue' })" />
            <XtfButton id="toast-service-update" label="更新当前提示" type="outline" @click="toastManager.update({ message: 'service-updated' })" />
            <XtfButton id="toast-service-clear" label="关闭当前提示" type="light" @click="toastManager.clear()" />
            <XtfText id="toast-service-state" level="caption" :text="serviceState" />
          </view>
          <view class="section">
            <XtfText level="h3" text="状态类型" />
            <view class="toast-demo-button-grid">
              <view class="toast-demo-button-item"><XtfButton label="Success" theme="success" @click="showToast('success')" /></view>
              <view class="toast-demo-button-item"><XtfButton label="Error" theme="danger" @click="showToast('error')" /></view>
              <view class="toast-demo-button-item"><XtfButton label="Warning" theme="warning" @click="showToast('warning')" /></view>
              <view class="toast-demo-button-item"><XtfButton label="Info" theme="primary" @click="showToast('info')" /></view>
              <view class="toast-demo-button-item"><XtfButton label="Loading" type="outline" @click="showToast('loading')" /></view>
            </view>
          </view>
          <view class="section">
            <XtfText level="h3" text="位置" />
            <view class="toast-demo-button-grid">
              <view class="toast-demo-button-item"><XtfButton label="左上" @click="showAt('top-left')" /></view>
              <view class="toast-demo-button-item"><XtfButton label="上中" @click="showAt('top-center')" /></view>
              <view class="toast-demo-button-item"><XtfButton label="右上" @click="showAt('top-right')" /></view>
              <view class="toast-demo-button-item"><XtfButton label="中心" @click="showAt('center')" /></view>
              <view class="toast-demo-button-item"><XtfButton label="底部" @click="showAt('bottom')" /></view>
              <view class="toast-demo-button-item"><XtfButton label="右下" @click="showAt('bottom-right')" /></view>
            </view>
            <view class="toast-demo-block-button"><XtfButton label="自定义坐标" type="light" block @click="showAt('custom')" /></view>
          </view>
          <view class="section">
            <XtfText level="h3" text="视觉样式" />
            <view class="toast-demo-button-grid">
              <view class="toast-demo-button-item"><XtfButton label="Solid" @click="showStyle('solid')" /></view>
              <view class="toast-demo-button-item"><XtfButton label="Light" type="light" @click="showStyle('light')" /></view>
              <view class="toast-demo-button-item"><XtfButton label="Outline" type="outline" @click="showStyle('outline')" /></view>
              <view class="toast-demo-button-item"><XtfButton label="Glass" type="ghost" @click="showStyle('glass')" /></view>
              <view class="toast-demo-button-item"><XtfButton label="Color" theme="success" @click="showStyle('gradient')" /></view>
              <view class="toast-demo-button-item"><XtfButton label="Accent" type="light" theme="danger" @click="showStyle('accent')" /></view>
            </view>
          </view>
          <view class="section">
            <XtfText level="h3" text="布局与行为" />
            <view class="toast-demo-block-button"><XtfButton label="Inline 布局" block @click="showLayout('inline')" /></view>
            <view class="toast-demo-block-button"><XtfButton label="Stack 布局" type="light" block @click="showLayout('stack')" /></view>
            <view class="toast-demo-block-button"><XtfButton label="Spotlight 布局" type="outline" block @click="showLayout('spotlight')" /></view>
            <view class="toast-demo-block-button"><XtfButton label="Overlay + Closeable" theme="danger" block @click="showOverlay" /></view>
            <view class="toast-demo-block-button"><XtfButton label="关闭 Loading" type="light" block @click="closeLoading" /></view>
            <XtfText class="demo-note" level="caption" color="secondary" text="allowHtml 当前按纯文本显示。" />
            <XtfText id="toast-main-log" class="demo-note" level="caption" color="secondary" :text="log" />
          </view>
          <view class="section">
            <XtfText level="h3" text="初始显示" />
            <view id="toast-initial-mount" class="toast-demo-block-button"><XtfButton label="挂载 show=true / 800ms" block @click="mountInitial" /></view>
            <view id="toast-initial-unmount" class="toast-demo-block-button"><XtfButton label="卸载初始实例" type="light" block @click="initialMounted = false" /></view>
            <XtfText id="toast-initial-log" class="demo-note" :text="initialLog" />
          </view>
          <view class="section">
            <XtfText level="h3" text="自动关闭与重开" />
            <view id="toast-auto-open" class="toast-demo-block-button"><XtfButton label="普通提示 / 800ms" block @click="showTimed(false)" /></view>
            <view id="toast-auto-reopen" class="toast-demo-block-button"><XtfButton label="实例重开并重新计时" type="light" block @click="reopenTimed" /></view>
            <XtfText id="toast-auto-log" class="demo-note" :text="timedLog" />
          </view>
          <view class="section">
            <XtfText level="h3" text="常驻提示" />
            <view id="toast-zero-open" class="toast-demo-block-button"><XtfButton label="duration=0 常驻" block @click="showTimed(true)" /></view>
            <view id="toast-loading-open" class="toast-demo-block-button"><XtfButton label="Loading / duration=800 常驻" block @click="showPersistentLoading" /></view>
            <view id="toast-persistent-close" class="toast-demo-block-button"><XtfButton label="关闭常驻提示" type="light" block @click="timedRef?.close()" /></view>
            <XtfText id="toast-persistent-log" class="demo-note" :text="persistentLog" />
          </view>
          <view class="section">
            <XtfText level="h3" text="关闭拦截" />
            <view v-for="mode in guardModes" :id="'toast-guard-' + mode" :key="mode" class="toast-demo-block-button"><XtfButton :label="mode" block @click="showGuard(mode)" /></view>
            <view id="toast-guard-close" class="toast-demo-block-button"><XtfButton label="请求关闭" type="light" block @click="guardRef?.close()" /></view>
            <view id="toast-guard-reopen" class="toast-demo-block-button"><XtfButton label="pending 时重开" type="light" block @click="guardRef?.open()" /></view>
            <view id="toast-guard-unmount" class="toast-demo-block-button"><XtfButton label="卸载拦截实例" type="light" block @click="guardMounted = false" /></view>
            <XtfText id="toast-guard-log" class="demo-note" :text="guardLog" />
          </view>
          <view class="section">
            <XtfText level="h3" text="实例方法" />
            <view id="toast-instance-open" class="toast-demo-block-button"><XtfButton label="instance.open()" block @click="instanceRef?.open()" /></view>
            <view id="toast-instance-close" class="toast-demo-block-button"><XtfButton label="instance.close()" type="light" block @click="instanceRef?.close()" /></view>
            <XtfText id="toast-instance-log" class="demo-note" :text="instanceLog" />
          </view>
          <view class="section">
            <XtfText level="h3" text="位置与类型组合" />
            <view id="toast-position-type" class="toast-demo-block-button"><XtfButton label="顶部 Success / 底部 Warning" block @click="showCombination" /></view>
            <XtfText id="toast-position-log" class="demo-note" :text="combinationLog" />
          </view>
        </view>
      </scroll-view>
      <XtfToast :show="visible" :type="type" :title="toastTitle" :message="message" :position="position" :layout="layout" :style-type="styleType" :duration="type == 'loading' ? 0 : 2200" :overlay="overlay" :closeable="closeable" :close-on-click-overlay="true" :offset-x="position == 'custom' ? 10 : 0" :offset-y="position == 'custom' ? 4 : 0" :custom-top="160" :custom-left="36" @update:show="visible = $event" @open="setLog('open')" @opened="setLog('opened')" @close="setLog('close')" @closed="setLog('closed')" />
      <XtfToast v-if="initialMounted" :show="initialVisible" message="初始显示 / 800ms" :duration="800" @update:show="initialVisible = $event" @open="record('initial', 'open')" @opened="record('initial', 'opened')" @close="record('initial', 'close')" @closed="record('initial', 'closed')" />
      <XtfToast ref="timedRef" :show="timedVisible" :type="timedType" :duration="timedDuration" message="计时与常驻提示" @update:show="timedVisible = $event" @open="recordTimed('open')" @opened="recordTimed('opened')" @close="recordTimed('close')" @closed="recordTimed('closed')" />
      <XtfToast v-if="guardMounted" ref="guardRef" :show="guardVisible" :duration="0" :before-close="beforeClose" message="关闭拦截" closeable @update:show="guardVisible = $event" @open="record('guard', 'open')" @opened="record('guard', 'opened')" @close="record('guard', 'close')" @closed="record('guard', 'closed')" @blocked-close="record('guard', 'blocked-close')" />
      <XtfToast ref="instanceRef" :show="instanceVisible" :duration="0" message="实例方法提示" @update:show="instanceVisible = $event" @open="record('instance', 'open')" @opened="record('instance', 'opened')" @close="record('instance', 'close')" @closed="record('instance', 'closed')" />
      <XtfToast :show="combinationVisible" :type="combinationType" :position="combinationPosition" :duration="800" message="位置与类型组合" @update:show="combinationVisible = $event" @open="record('combination', 'open')" @opened="record('combination', 'opened')" @close="record('combination', 'close')" @closed="record('combination', 'closed')" />
      <XtfToast service closeable />
    </view>
  </XtfConfigProvider>
</template>

<script setup lang="uts">
import { useDemoTheme } from '@/pages/demo-theme.uts'
const demoTheme = useDemoTheme()
import { computed, nextTick, onBeforeUnmount, ref } from "vue"
import { toastManager } from "@/uni_modules/xtf-linkuiunix/components/xtf-toast/service.uts"
import XtfConfigProvider from "@/uni_modules/xtf-linkuiunix/components/xtf-config-provider/xtf-config-provider.uvue"
import XtfText from "@/uni_modules/xtf-linkuiunix/components/xtf-text/xtf-text.uvue"
import XtfButton from "@/uni_modules/xtf-linkuiunix/components/xtf-button/xtf-button.uvue"
import XtfToast from "@/uni_modules/xtf-linkuiunix/components/xtf-toast/xtf-toast.uvue"

const serviceState = computed((): string => JSON.stringify(toastManager.state.value))
const initialMounted = ref(false)
const initialVisible = ref(true)
const timedRef = ref<InstanceType<typeof XtfToast> | null>(null)
const guardRef = ref<InstanceType<typeof XtfToast> | null>(null)
const instanceRef = ref<InstanceType<typeof XtfToast> | null>(null)
const timedVisible = ref(false)
const timedType = ref("info")
const timedDuration = ref(800)
const guardMounted = ref(false)
const guardVisible = ref(false)
const guardMode = ref("allow")
const guardModes = ["allow", "deny", "throw", "async-allow", "async-deny", "async-reject"]
const instanceVisible = ref(false)
const combinationVisible = ref(false)
const combinationType = ref("success")
const combinationPosition = ref("top")
const initialLog = ref("等待事件")
const timedLog = ref("等待事件")
const persistentLog = ref("等待事件")
const guardLog = ref("等待事件")
const instanceLog = ref("等待事件")
const combinationLog = ref("等待事件")
const hookTimers = new Array<number>()
let disposed = false

onBeforeUnmount(() => {
  disposed = true
  toastManager.clearAll()
  hookTimers.forEach((timer: number) => clearTimeout(timer))
})

function record(scene: string, event: string): void {
  const target = scene == "initial" ? initialLog : scene == "auto" ? timedLog : scene == "persistent" ? persistentLog : scene == "guard" ? guardLog : scene == "instance" ? instanceLog : combinationLog
  target.value = (target.value == "等待事件" ? "" : target.value + " → ") + event
  console.log("[toast-demo] " + scene + ": " + event)
}
function recordTimed(event: string): void { record(timedType.value == "loading" || timedDuration.value == 0 ? "persistent" : "auto", event) }
async function mountInitial(): Promise<void> {
  initialMounted.value = false
  await nextTick()
  if (disposed) return
  initialLog.value = "等待事件"
  initialVisible.value = true
  initialMounted.value = true
}
function showTimed(persistent: boolean): void {
  timedType.value = "info"
  timedDuration.value = persistent ? 0 : 800
  if (persistent) persistentLog.value = "等待事件"
  else timedLog.value = "等待事件"
  timedRef.value?.open()
}
function reopenTimed(): void { timedRef.value?.open() }
function showPersistentLoading(): void {
  timedType.value = "loading"
  timedDuration.value = 800
  persistentLog.value = "等待事件"
  timedRef.value?.open()
}
async function showGuard(mode: string): Promise<void> {
  guardMounted.value = false
  await nextTick()
  if (disposed) return
  guardMode.value = mode
  guardLog.value = "等待事件"
  guardVisible.value = true
  guardMounted.value = true
}
function beforeClose(_payload: UTSJSONObject): boolean | Promise<boolean> {
  const mode = guardMode.value
  record("guard", "beforeClose:" + mode)
  if (mode == "throw") throw new Error("demo beforeClose")
  if (mode.indexOf("async-") == 0) {
    return new Promise<boolean>((resolve, reject) => {
      const timer = setTimeout(() => {
        const index = hookTimers.indexOf(timer)
        if (index >= 0) hookTimers.splice(index, 1)
        if (mode == "async-reject") reject(new Error("demo rejection"))
        else resolve(mode == "async-allow")
      }, 800) as number
      hookTimers.push(timer)
    })
  }
  return mode != "deny"
}
function showCombination(): void {
  combinationType.value = combinationType.value == "success" ? "warning" : "success"
  combinationPosition.value = combinationType.value == "success" ? "top" : "bottom"
  combinationVisible.value = true
}

const visible = ref(false)
const type = ref("info")
const toastTitle = ref("")
const message = ref("已完成操作")
const position = ref("center")
const layout = ref("inline")
const styleType = ref("solid")
const overlay = ref(false)
const closeable = ref(false)
const log = ref("等待事件")

function reset(): void {
  toastTitle.value = ""
  layout.value = "inline"
  styleType.value = "solid"
  overlay.value = false
  closeable.value = false
}

function present(): void {
  if (!visible.value) { visible.value = true; return }
  visible.value = false
  nextTick(() => { visible.value = true })
}

function showToast(value: string): void {
  reset()
  type.value = value
  message.value = value == "loading" ? "加载中" : "操作结果已更新"
  position.value = "center"
  present()
}

function showAt(value: string): void {
  reset()
  type.value = "info"
  message.value = "位置: " + value
  position.value = value
  present()
}

function showStyle(value: string): void {
  reset()
  type.value = "success"
  message.value = "当前样式: " + value
  styleType.value = value
  present()
}

function showLayout(value: string): void {
  reset()
  type.value = "info"
  toastTitle.value = value == "inline" ? "即时提示" : value == "stack" ? "堆叠提示" : "聚焦提示"
  message.value = "布局: " + value
  layout.value = value
  present()
}

function showOverlay(): void {
  reset()
  type.value = "warning"
  message.value = "点击遮罩或右上角关闭"
  position.value = "center"
  overlay.value = true
  closeable.value = true
  present()
}

function closeLoading(): void {
  if (type.value == "loading") visible.value = false
  else showToast("loading")
}

function setLog(value: string): void { log.value = (log.value == "等待事件" ? "" : log.value + " → ") + value }
</script>

<style>
.page { display: flex; flex: 1; flex-direction: column; min-height: 0; background-color: var(--xtf-color-page, #f1f5f9); }
.scroll { display: flex; flex-direction: column; flex: 1; width: 100%; }
.body { display: flex; flex-direction: column; padding: 24rpx; }
.hero { display: flex; flex-direction: column; padding: 32rpx; border-radius: 16rpx; background-color: #0f766e; }
.section { display: flex; flex-direction: column; margin-top: 24rpx; padding: 24rpx; border-radius: 16rpx; background-color: var(--xtf-color-surface, #ffffff); }
.toast-demo-button-grid { display: flex; flex-direction: row; flex-wrap: wrap; justify-content: space-between; margin-top: 18rpx; }
.toast-demo-button-item { display: flex; flex-direction: column; width: 48%; margin-bottom: 14rpx; }
.toast-demo-block-button { display: flex; flex-direction: column; width: 100%; margin-top: 14rpx; }
.demo-note { margin-top: 14rpx; }
</style>
