<template>
  <XtfConfigProvider class="demo-theme-root" :theme="demoTheme" component-size="md" :safe-area="true">
    <scroll-view class="search-demo-scroll xtf-page-scroll" direction="vertical">
      <view id="search-demo" class="search-demo-page xtf-safe-bottom xtf-page-scroll-content">
        <view class="search-demo-header"><text class="search-demo-kicker">XTF LINKUI / COMPONENTS</text><text class="search-demo-title">Search 搜索</text></view>

        <view id="search-basic-scene" class="search-demo-section">
          <text class="search-demo-heading">01 / 基础、形状与尺寸</text>
          <XtfSearch id="search-basic" v-model="basicValue" placeholder="搜索账单或商户" @search="recordSearch" @clear="record('clear', '')" @cancel="record('cancel', '')" />
          <text class="search-demo-result">当前值：{{ basicValue }}</text>
          <XtfSearch id="search-outline" v-model="outlineValue" variant="outline" shape="square" theme="success" size="sm" :show-action="false" placeholder="方形 outline / small" />
          <view class="search-demo-gap"></view>
          <XtfSearch id="search-filled" v-model="filledValue" variant="filled" size="lg" action-variant="filled" action-theme="danger" action-text="查询" placeholder="大尺寸 filled" @search="recordSearch" />
        </view>

        <view id="search-panel-scene" class="search-demo-section">
          <text class="search-demo-heading">02 / 联想、热词与历史</text>
          <XtfSearch id="search-panel" ref="panelSearch" v-model="panelValue" show-panel search-on-input :search-debounce="350" :suggestions="suggestions" :hot-keywords="hotKeywords" :history-keywords="historyKeywords" :recent-keywords="recentKeywords" placeholder="订单" @input="record('input', $event)" @change="record('change', $event)" @select-suggestion="recordSelection" @search-input="recordInputSearch" @search="recordSearch" @clear="record('clear', '')" @cancel="record('cancel', '')" />
          <view class="search-demo-controls">
            <button id="search-panel-clear" class="search-demo-button" @click="clearPanel">清空</button>
            <button id="search-panel-submit" class="search-demo-button" @click="submitPanel">确认搜索</button>
            <button id="search-panel-focus" class="search-demo-button" @click="focusPanel">聚焦</button>
          </view>
          <text id="search-panel-value" class="search-demo-result">{{ panelValue }}</text>
        </view>

        <view id="search-focus-scene" class="search-demo-section">
          <text class="search-demo-heading">03 / 插槽与焦点</text>
          <XtfSearch id="search-slots" ref="programmaticSearch" v-model="slotValue" action-variant="soft" @focus="onFocus" @blur="onBlur" @search="recordSearch">
            <template #prefix><XtfText level="caption" text="全部" /></template>
            <template #suffix><XtfIcon name="tune" size="sm" theme="secondary" /></template>
            <template #action><text class="search-demo-action-slot">执行</text></template>
          </XtfSearch>
          <view class="search-demo-controls">
            <button id="search-focus" class="search-demo-button" @click="focusSearch">Focus</button>
            <button id="search-blur" class="search-demo-button" @click="blurSearch">Blur</button>
            <button id="search-refocus" class="search-demo-button" :disabled="focusBusy" @click="rapidRefocus">Focus / Blur / Focus</button>
            <button id="search-slot-clear" class="search-demo-button" @click="clearSearch">Clear</button>
            <button id="search-slot-submit" class="search-demo-button" @click="submitSearch">Search</button>
          </view>
          <text id="search-focus-result" class="search-demo-result">{{ slotFocused ? '已聚焦' : '未聚焦' }} / focus {{ focusCount }} / blur {{ blurCount }}</text>
        </view>

        <view id="search-external-scene" class="search-demo-section">
          <text class="search-demo-heading">04 / 外部回填与状态</text>
          <XtfSearch id="search-external" :value="inputValue" :disabled="disabled" :readonly="readOnly" search-on-input :search-debounce="350" placeholder="输入以触发搜索" @input="inputValue = $event" @search-input="recordInputSearch" @search="recordSearch" />
          <view class="search-demo-controls">
            <button id="search-external-fill" class="search-demo-button" @click="fillExternal">外部回填</button>
            <button id="search-external-reset" class="search-demo-button" @click="resetExternal">外部置空</button>
          </view>
          <view class="search-demo-state"><text class="search-demo-label">Disabled</text><switch id="search-disabled" :checked="disabled" @change="disabled = $event.detail.value" /></view>
          <view class="search-demo-state"><text class="search-demo-label">Readonly</text><switch id="search-readonly" :checked="readOnly" @change="readOnly = $event.detail.value" /></view>
          <text class="search-demo-result">{{ disabled ? '已禁用' : (readOnly ? '只读（映射为禁用输入）' : '可编辑') }} / 外部值：{{ inputValue }}</text>
          <XtfSearch id="search-loading" value="同步中" loading :show-action="false" />
          <view class="search-demo-gap"></view>
          <XtfSearch id="search-disabled-example" value="不可编辑" disabled :show-action="false" />
          <view class="search-demo-gap"></view>
          <XtfSearch id="search-priority" v-model="priorityValue" :value="priorityFallback" :cursor-spacing="32" :selection-start="0" :selection-end="2" :show-action="false" placeholder="modelValue 为空仍优先" />
          <view class="search-demo-controls"><button id="search-priority-fill" class="search-demo-button" @click="priorityValue = '绑定值'">回填绑定值</button><button id="search-priority-clear" class="search-demo-button" @click="priorityValue = ''; priorityFallback = '备用值已更新'">清空绑定并更新备用值</button></view>
          <text id="search-priority-result" class="search-demo-result">绑定值：{{ JSON.stringify(priorityValue) }} / 备用值：{{ priorityFallback }}</text>
        </view>

        <view id="search-unmount-scene" class="search-demo-section">
          <text class="search-demo-heading">05 / 实例卸载</text>
          <XtfSearch v-if="mountedSearch" id="search-unmount" ref="unmountSearch" v-model="unmountValue" search-on-input :search-debounce="350" placeholder="输入后立即卸载" @input="onUnmountInput" @focus="record('unmount-focus', '')" @blur="record('unmount-blur', '')" @search-input="onUnmountSearchInput" @search="onUnmountSearch" />
          <view class="search-demo-state"><text class="search-demo-label">输入后 80ms 自动卸载</text><switch id="search-auto-unmount" :checked="autoUnmount" @change="autoUnmount = $event.detail.value" /></view>
          <view class="search-demo-controls">
            <button id="search-unmount-now" class="search-demo-button" :disabled="!mountedSearch" @click="removeSearch">卸载</button>
            <button id="search-unmount-blur" class="search-demo-button" :disabled="!mountedSearch" @click="blurAndRemove">失焦后卸载</button>
            <button id="search-remount" class="search-demo-button" :disabled="mountedSearch" @click="remountSearch">重新挂载</button>
          </view>
          <text id="search-unmount-result" class="search-demo-result">{{ mountedSearch ? '已挂载' : '已卸载' }} / search-input {{ unmountInputCount }} / search {{ unmountSearchCount }}</text>
        </view>

        <view id="search-action-mode-scene" class="search-demo-section">
          <XtfText level="title" text="06 / 搜索与取消模式" />
          <XtfText level="caption" text="切换右侧操作模式。取消保留关键词并关闭建议，搜索会记录当前关键词。" />
          <view class="search-demo-controls">
            <XtfButton id="search-mode-auto" size="sm" :type="actionMode == 'auto' ? 'solid' : 'outline'" theme="primary" label="自动" @click="actionMode = 'auto'" />
            <XtfButton id="search-mode-search" size="sm" :type="actionMode == 'search' ? 'solid' : 'outline'" theme="success" label="搜索" @click="actionMode = 'search'" />
            <XtfButton id="search-mode-cancel" size="sm" :type="actionMode == 'cancel' ? 'solid' : 'outline'" theme="warning" label="取消" @click="actionMode = 'cancel'" />
            <XtfButton id="search-mode-fill" size="sm" type="light" theme="info" label="回填关键词" @click="modeValue = '月度账单'" />
          </view>
          <XtfSearch id="search-mode-input" v-model="modeValue" :action-mode="actionMode" action-variant="soft" show-panel :suggestions="['coffee', '月度账单', '月度统计']" placeholder="输入关键词后体验取消" @search="onModeSearch" @cancel="onModeCancel" />
          <XtfText id="search-mode-events" level="caption" :text="'模式 ' + actionMode + ' / 当前值 ' + modeValue + ' / search ' + modeSearchCount + ' / cancel ' + modeCancelCount + ' / 最近事件 ' + modeLastEvent" />
        </view>

        <view id="search-events-scene" class="search-demo-section">
          <text class="search-demo-heading">07 / 事件记录</text>
          <text id="search-event-counts" class="search-demo-result">总计 {{ eventCount }} / search {{ searchCount }} / search-input {{ searchInputCount }} / select {{ selectionCount }}</text>
          <view class="search-demo-controls"><button id="search-events-reset" class="search-demo-button" @click="resetEvents">清空记录</button></view>
          <text v-for="(entry, index) in eventLog" :key="eventCount.toString() + '-' + index.toString()" class="search-demo-event">{{ entry }}</text>
        </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 XtfSearch from "@/uni_modules/xtf-linkuiunix/components/xtf-search/xtf-search.uvue"
import XtfText from "@/uni_modules/xtf-linkuiunix/components/xtf-text/xtf-text.uvue"
import XtfIcon from "@/uni_modules/xtf-linkuiunix/components/xtf-icon/xtf-icon.uvue"
import XtfButton from "@/uni_modules/xtf-linkuiunix/components/xtf-button/xtf-button.uvue"

const basicValue = ref("")
const outlineValue = ref("")
const filledValue = ref("")
const actionMode = ref<"auto" | "search" | "cancel">("cancel")
const modeValue = ref("")
const modeSearchCount = ref(0)
const modeCancelCount = ref(0)
const modeLastEvent = ref("暂无")
const panelValue = ref("")
const inputValue = ref("")
const priorityValue = ref("")
const priorityFallback = ref("备用值")
const slotValue = ref("月度账单")
const panelSearch = ref<any>(null)
const programmaticSearch = ref<any>(null)
const unmountSearch = ref<any>(null)
const suggestions = ["订单异常", "订单退款", "订单统计", "订单导出", "账单分类"]
const hotKeywords = ["本月支出", "待报销", "家庭账本"]
const historyKeywords = ["咖啡", "交通", "订阅服务"]
const recentKeywords = ["会员续费", "旅行预算"]
const disabled = ref(false)
const readOnly = ref(false)
const slotFocused = ref(false)
const focusBusy = ref(false)
const focusCount = ref(0)
const blurCount = ref(0)
const mountedSearch = ref(true)
const autoUnmount = ref(true)
const unmountValue = ref("")
const unmountInputCount = ref(0)
const unmountSearchCount = ref(0)
const eventCount = ref(0)
const searchCount = ref(0)
const searchInputCount = ref(0)
const selectionCount = ref(0)
const eventLog = ref<string[]>([])
let focusTimer: number | null = null
let unmountTimer: number | null = null
let fillCount = 0

function record(name: string, value: string): void {
  eventCount.value++
  eventLog.value.unshift(eventCount.value.toString() + ' / ' + Date.now().toString() + ' / ' + name + ': ' + value)
  if (eventLog.value.length > 24) eventLog.value.pop()
}
function recordSearch(value: string): void { searchCount.value++; record("search", value) }
function onModeSearch(value: string): void { modeSearchCount.value++; modeLastEvent.value = "search: " + value; recordSearch(value) }
function onModeCancel(): void { modeCancelCount.value++; modeLastEvent.value = "cancel: " + modeValue.value; record("cancel", modeValue.value) }
function recordInputSearch(value: string): void { searchInputCount.value++; record("search-input", value) }
function recordSelection(payload: UTSJSONObject): void { selectionCount.value++; record("select-suggestion", JSON.stringify(payload)) }
function clearPanel(): void { panelSearch.value?.clear() }
function submitPanel(): void { panelSearch.value?.search() }
function focusPanel(): void { panelSearch.value?.focus() }
function focusSearch(): void { programmaticSearch.value?.focus() }
function blurSearch(): void { programmaticSearch.value?.blur() }
function clearSearch(): void { programmaticSearch.value?.clear() }
function submitSearch(): void { programmaticSearch.value?.search() }
function onFocus(): void { slotFocused.value = true; focusCount.value++; record("focus", slotValue.value) }
function onBlur(): void { slotFocused.value = false; blurCount.value++; record("blur", slotValue.value) }
function rapidRefocus(): void {
  if (focusBusy.value) return
  focusBusy.value = true
  focusSearch()
  focusTimer = setTimeout(() => {
    blurSearch()
    focusTimer = setTimeout(() => { focusTimer = null; focusSearch(); focusBusy.value = false }, 40)
  }, 40)
}
function fillExternal(): void { fillCount++; inputValue.value = "外部账单 " + fillCount.toString(); record("external-value", inputValue.value) }
function resetExternal(): void { inputValue.value = ""; record("external-value", "") }
function onUnmountInput(value: string): void {
  record("unmount-input", value)
  if (unmountTimer != null) { clearTimeout(unmountTimer); unmountTimer = null }
  if (autoUnmount.value) unmountTimer = setTimeout(() => { unmountTimer = null; removeSearch() }, 80)
}
function removeSearch(): void {
  if (unmountTimer != null) { clearTimeout(unmountTimer); unmountTimer = null }
  mountedSearch.value = false
  record("unmount", unmountValue.value)
}
function blurAndRemove(): void {
  if (unmountTimer != null) clearTimeout(unmountTimer)
  unmountSearch.value?.blur()
  unmountTimer = setTimeout(() => { unmountTimer = null; removeSearch() }, 20)
}
function remountSearch(): void { unmountValue.value = ""; mountedSearch.value = true; record("mount", "") }
function onUnmountSearchInput(value: string): void { unmountInputCount.value++; recordInputSearch(value) }
function onUnmountSearch(value: string): void { unmountSearchCount.value++; recordSearch(value) }
function resetEvents(): void { eventLog.value = []; eventCount.value = 0; searchCount.value = 0; searchInputCount.value = 0; selectionCount.value = 0; focusCount.value = 0; blurCount.value = 0; unmountInputCount.value = 0; unmountSearchCount.value = 0 }
onBeforeUnmount(() => { if (focusTimer != null) clearTimeout(focusTimer); if (unmountTimer != null) clearTimeout(unmountTimer) })
</script>

<style>
.search-demo-scroll { display: flex; flex-direction: column; flex: 1; width: 100%; height: 100%; min-height: 0; }
.search-demo-page { display: flex; flex-direction: column; width: 100%; padding: 24rpx; background-color: var(--xtf-color-page, #f8fafc); }
.search-demo-header { display: flex; flex-direction: column; padding: 16rpx 0; }
.search-demo-kicker { color: var(--xtf-color-text-secondary, #475569); font-size: 20rpx; }
.search-demo-title { margin-top: 8rpx; color: var(--xtf-color-text, #0f172a); font-size: 40rpx; font-weight: 700; }
.search-demo-section { display: flex; flex-direction: column; margin-top: 24rpx; padding-top: 24rpx; padding-bottom: 24rpx; border-top-width: 1rpx; border-top-style: solid; border-top-color: var(--xtf-color-border, #cbd5e1); }
.search-demo-heading { margin-bottom: 20rpx; color: var(--xtf-color-text, #0f172a); font-size: 28rpx; font-weight: 600; }
.search-demo-result { margin-top: 16rpx; margin-bottom: 16rpx; color: var(--xtf-color-text-secondary, #475569); font-size: 24rpx; line-height: 1.5; }
.search-demo-gap { display: flex; flex-direction: column; height: 16rpx; }
.search-demo-action-slot { color: var(--xtf-color-primary, #2563eb); font-size: 26rpx; font-weight: 600; }
.search-demo-controls { display: flex; flex-direction: row; flex-wrap: wrap; margin-top: 16rpx; }
.search-demo-button { display: flex; flex-direction: row; align-items: center; justify-content: center; margin: 0 12rpx 12rpx 0; padding: 12rpx 20rpx; min-height: 64rpx; border-radius: 8rpx; font-size: 24rpx; line-height: 1.5; color: var(--xtf-color-primary, #2563eb); background-color: var(--xtf-color-surface, #ffffff); }
.search-demo-state { display: flex; flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: space-between; margin-top: 16rpx; }
.search-demo-label { color: var(--xtf-color-text, #0f172a); font-size: 24rpx; }
.search-demo-event { margin-top: 8rpx; color: var(--xtf-color-text-secondary, #475569); font-size: 22rpx; line-height: 1.5; }
</style>
