<template>
  <XtfConfigProvider class="demo-theme-root" :theme="demoTheme" component-size="md" :safe-area="true">
    <scroll-view id="xtf-switch-demo-scroll" class="switch-demo-scroll xtf-page-scroll" style="flex: 1" direction="vertical">
      <view class="switch-demo-page xtf-safe-bottom xtf-page-scroll-content">
        <view class="switch-demo-hero"><XtfText class="switch-demo-kicker" level="micro" color="inverse" text="XTF LINKUI / COMPONENTS" /><XtfText class="switch-demo-title" level="display" color="inverse" text="Switch" /><XtfText class="switch-demo-intro" level="caption" color="inverse" text="自绘轨道与滑块，覆盖状态、文案和异步确认流程。" /></view>
        <view id="switch-scenarios-basic" class="switch-demo-section"><XtfText class="switch-demo-heading" level="h3" text="基础、变体与尺寸" /><XtfText class="switch-demo-desc" level="caption" color="secondary" text="普通切换、filled / outline / soft / native、预设、尺寸与图标。" /><view class="switch-demo-list"><view id="switch-basic" class="switch-demo-control"><XtfSwitch v-model="filled" variant="filled" /></view><view id="switch-outline" class="switch-demo-control"><XtfSwitch v-model="outline" variant="outline" theme="warning" /></view><view id="switch-soft" class="switch-demo-control"><XtfSwitch v-model="soft" variant="soft" theme="success" /></view><view id="switch-native" class="switch-demo-control"><XtfSwitch v-model="native" variant="native" theme="info" /></view><view id="switch-presets" class="switch-demo-control"><XtfSwitch v-model="classic" preset="classic" /><XtfSwitch v-model="material" preset="material" theme="success" /><XtfSwitch v-model="minimal" preset="minimal" theme="warning" /></view><view id="switch-sizes" class="switch-demo-control"><XtfSwitch v-model="small" size="sm" /><XtfSwitch v-model="large" size="lg" theme="danger" /></view><view id="switch-icons" class="switch-demo-control"><XtfSwitch v-model="iconState" variant="soft" active-icon="success" inactive-icon="close" active-text="图标开启" inactive-text="图标关闭" label-placement="inside" /></view></view></view>
        <view id="switch-labels" class="switch-demo-section"><XtfText class="switch-demo-heading" level="h3" text="文案与语义预设" /><view class="switch-demo-list"><view class="switch-demo-control"><XtfSwitch v-model="semantic" preset="semantic" active-text="已启用" inactive-text="未启用" label-placement="inside" /></view><view class="switch-demo-control"><XtfSwitch v-model="insideText" active-text="开启" inactive-text="关闭" label-placement="inside" /></view><view class="switch-demo-control"><XtfSwitch v-model="outsideText" active-text="通知开启" inactive-text="通知关闭" label-placement="outside-right" theme="success" /></view></view></view>
        <view id="switch-external-state" class="switch-demo-section"><XtfText class="switch-demo-heading" level="h3" text="外部 loading、disabled 与赋值" /><view class="switch-demo-list"><view id="switch-external-loading" class="switch-demo-control"><XtfSwitch :model-value="true" loading active-text="同步中" label-placement="outside-right" /></view><view id="switch-external-disabled" class="switch-demo-control"><XtfSwitch :model-value="true" disabled active-text="不可更改" label-placement="outside-right" /></view><view class="switch-demo-control"><XtfSwitch v-model="customColor" active-color="#0f766e" inactive-color="#d7e7e2" /><XtfSwitch v-model="wideSwitch" width="150" active-text="宽轨道" inactive-text="窄轨道" label-placement="inside" /></view><view id="switch-external-assignment" class="switch-demo-control"><XtfSwitch :model-value="assignedValue" active-value="on" inactive-value="off" @update:model-value="onAssignedUpdate" /><view id="switch-external-assignment-trigger" class="switch-demo-assignment-trigger" @click="toggleAssignedValue"><text class="switch-demo-assignment-text">外部赋值</text></view></view></view><XtfText class="switch-demo-event" level="caption" color="secondary" :text="'外部赋值: ' + assignedValue" /></view>
        <view id="switch-events" class="switch-demo-section"><XtfText class="switch-demo-heading" level="h3" text="字符串、数字值与事件日志" /><XtfSwitch :model-value="statusValue" active-value="enabled" inactive-value="paused" active-text="Enabled" inactive-text="Paused" label-placement="outside-right" @input="onInput" @update:model-value="onModelUpdate" @update:value="onValueUpdate" @change="onStatusChange" /><XtfSwitch v-model="numericValue" :active-value="1" :inactive-value="0" size="sm" @change="onNumericChange" /><XtfText id="switch-event-log" class="switch-demo-event" level="caption" color="secondary" :text="eventLog" /></view>
        <view id="switch-async" class="switch-demo-section"><XtfText class="switch-demo-heading" level="h3" text="异步确认：无钩子、允许、拒绝、抛错" /><XtfText class="switch-demo-desc" level="caption" color="secondary" text="异步无钩子立即同步 v-model；守卫期间 loading 锁定重复点击，拒绝和异常回滚。" /><view id="switch-async-no-hook" class="switch-demo-control"><XtfSwitch v-model="asyncNoHook" async active-text="无钩子已开" inactive-text="无钩子已关" label-placement="outside-right" /></view><view id="switch-async-allow" class="switch-demo-control"><XtfSwitch v-model="asyncAllowed" async :disabled="guardDisabled" :before-change="allowAsyncChange" active-text="允许" inactive-text="等待允许" label-placement="outside-right" @change="guardChanges++" /></view><view class="switch-demo-guard-tools"><button id="switch-guard-disabled" class="switch-demo-guard-button" @click="guardDisabled = !guardDisabled">{{ guardDisabled ? '启用异步开关' : '禁用异步开关' }}</button><button id="switch-guard-override" class="switch-demo-guard-button" @click="asyncAllowed = false">外部回填关闭</button><text id="switch-guard-result" class="switch-demo-event">{{ asyncAllowed }} / change {{ guardChanges }}</text></view><view id="switch-async-reject" class="switch-demo-control"><XtfSwitch v-model="asyncRejected" async :before-change="rejectAsyncChange" active-text="不会保持" inactive-text="拒绝" label-placement="outside-right" /></view><view id="switch-async-throw" class="switch-demo-control"><XtfSwitch v-model="asyncThrown" async :before-change="throwAsyncChange" active-text="不会保持" inactive-text="抛错回滚" label-placement="outside-right" /></view><view id="switch-guard-sync" class="switch-demo-control"><XtfSwitch v-model="syncGuard" :before-change="syncGuardChange" active-text="同步 guard" inactive-text="需保持开启" label-placement="outside-right" /></view></view>
      </view>
    </scroll-view>
  </XtfConfigProvider>
</template>

<script setup lang="uts">
import { useDemoTheme } from '@/pages/demo-theme.uts'
const demoTheme = useDemoTheme()
import { onBeforeUnmount, ref } from "vue"
import XtfConfigProvider from "@/uni_modules/xtf-linkuiunix/components/xtf-config-provider/xtf-config-provider.uvue"
import XtfSwitch from "@/uni_modules/xtf-linkuiunix/components/xtf-switch/xtf-switch.uvue"
import XtfText from "@/uni_modules/xtf-linkuiunix/components/xtf-text/xtf-text.uvue"
const filled = ref(true); const outline = ref(false); const soft = ref(true); const native = ref(false)
const classic = ref(true); const material = ref(false); const minimal = ref(true); const semantic = ref(false); const small = ref(false); const large = ref(true)
const insideText = ref(true); const outsideText = ref(false); const iconState = ref(true); const customColor = ref(false)
const wideSwitch = ref(false)
const statusValue = ref("paused"); const numericValue = ref(0); const assignedValue = ref("off"); const eventLog = ref("暂无事件")
const asyncNoHook = ref(false); const asyncAllowed = ref(false); const asyncRejected = ref(false); const asyncThrown = ref(false); const syncGuard = ref(false)
const guardDisabled = ref(false)
const guardChanges = ref(0)
let demoTimers: number[] = []
function logEvent(name: string, value: any): void { eventLog.value = name + ":" + value.toString() }
function onInput(value: any): void { logEvent("input", value) }
function onModelUpdate(value: any): void { statusValue.value = value as string; logEvent("update:modelValue", value) }
function onValueUpdate(value: any): void { logEvent("update:value", value) }
function onStatusChange(value: any): void { statusValue.value = value as string; logEvent("change", value) }
function onNumericChange(value: any): void { numericValue.value = value as number; logEvent("numeric change", value) }
function onAssignedUpdate(value: any): void { assignedValue.value = value as string }
function toggleAssignedValue(): void { assignedValue.value = assignedValue.value == "on" ? "off" : "on" }
function delayedGuard(nextChecked: boolean, result: boolean): Promise<boolean> { return new Promise<boolean>((resolve) => { const timer = setTimeout(() => { resolve(result) }, 700); demoTimers.push(timer) }) }
function allowAsyncChange(nextChecked: boolean): Promise<boolean> { return delayedGuard(nextChecked, true) }
function rejectAsyncChange(nextChecked: boolean): Promise<boolean> { return delayedGuard(nextChecked, false) }
function throwAsyncChange(nextChecked: boolean): Promise<boolean> { return new Promise<boolean>((resolve, reject) => { const timer = setTimeout(() => { reject(new Error("demo guard error")) }, 700); demoTimers.push(timer) }) }
function syncGuardChange(nextChecked: boolean): boolean { return nextChecked }
onBeforeUnmount(() => { for (const timer of demoTimers) clearTimeout(timer); demoTimers = [] })
</script>

<style>
.switch-demo-guard-tools { display: flex; flex-direction: column; margin-bottom: 20rpx; }
.switch-demo-guard-button { margin-bottom: 10rpx; font-size: 24rpx; }
.switch-demo-scroll { flex: 1; width: 100%; height: 100%; min-height: 0; }
.switch-demo-page { display: flex; flex-direction: column; width: 100%; padding: 24rpx; background-color: var(--xtf-color-page, #f8fafc); }
.switch-demo-hero { display: flex; flex-direction: column; padding: 32rpx; border-radius: 16rpx; background-color: #0f766e; }
.switch-demo-kicker { color: #ffffff; font-size: 20rpx; font-weight: 600; }.switch-demo-title { margin-top: 8rpx; color: #ffffff; font-size: 52rpx; font-weight: 700; line-height: 1.1; }.switch-demo-intro { margin-top: 14rpx; color: #ffffff; font-size: 24rpx; line-height: 1.5; }
.switch-demo-section { display: flex; flex-direction: column; margin-top: 24rpx; padding: 24rpx; border-width: 1rpx; border-style: solid; border-color: var(--xtf-color-border, #cbd5e1); border-radius: 16rpx; background-color: var(--xtf-color-surface, #ffffff); }.switch-demo-heading { color: var(--xtf-color-text, #0f172a); font-size: 30rpx; font-weight: 700; }.switch-demo-desc { margin-top: 8rpx; color: var(--xtf-color-text-secondary, #475569); font-size: 22rpx; line-height: 1.45; }.switch-demo-list { display: flex; flex-direction: column; align-items: flex-start; margin-top: 20rpx; }.switch-demo-control { display: flex; flex-direction: row; margin-bottom: 20rpx; }.switch-demo-event { margin-top: 18rpx; color: var(--xtf-color-text-secondary, #475569); font-size: 22rpx; }
.switch-demo-assignment-trigger { display: flex; flex-direction: row; align-items: center; margin-left: 16rpx; padding: 10rpx 14rpx; border-radius: 8rpx; background-color: var(--xtf-color-surface-muted, #e2e8f0); }.switch-demo-assignment-text { color: var(--xtf-color-text-secondary, #334155); font-size: 22rpx; }
</style>
