<template>

  <view class="picker-wrap">

    <view class="region-trigger" @click="openDrawer">

    <text :class="displayText ? 'region-text' : 'region-placeholder'">{{ displayText || placeholder }}</text>

    <u-icon name="arrow-right" color="#c0c4cc" size="28"></u-icon>

  </view>



  <drawer-page-container v-model="show" title="选择省市区">

    <view class="drawer-body" :style="drawerBodyStyle">

      <view class="search-box">

        <u-input v-model="keyword" placeholder="搜索省/市/区" clearable :adjust-position="false" />

      </view>

      <scroll-view scroll-x class="crumb-scroll">

        <view class="crumbs">

          <text

            v-for="(item, idx) in breadcrumbs"

            :key="item.rowKey"

            class="crumb"

            @click="onCrumb(item)"

          >{{ item.label }}<text v-if="idx < breadcrumbs.length - 1" class="crumb-sep"> / </text></text>

          <text v-if="!breadcrumbs.length" class="crumb muted">请选择</text>

        </view>

      </scroll-view>

      <scroll-view scroll-y class="list-scroll" :style="listScrollStyle">

        <view

          v-for="row in listRows"

          :key="row.rowKey"

          class="list-row"

          @click="onPickRow(row)"

        >

          <text class="row-label">{{ isSearching ? row.label : row.node.label }}</text>

          <text v-if="!isSearching && rowHasNextLevel(row, ctx)" class="row-arrow">›</text>

        </view>

        <view v-if="!listRows.length" class="empty">无匹配结果</view>

      </scroll-view>

    </view>

  </drawer-page-container>

  </view>

</template>



<script>

import DrawerPageContainer from '@/subPackages/sub_salesperson/components/DrawerPageContainer.vue'

import {

  formatAddressDisplay,

  resolveAddressValue,

  buildAddressOutput,

  buildBreadcrumbFromContext,

  getInitialPickerLevel,

  levelOptionsToRows,

  searchAddressHits,

  searchHitsToRows,

  applySearchHit,

  rowHasNextLevel,

  truncateContextToBreadcrumb,

  getNextLevel,

  canCompleteAfterSelect,

} from '@/subPackages/sub_clinic_salesperson/utils/address-index.js'



export default {

  name: 'RegionAddressPicker',

  components: { DrawerPageContainer },

  props: {

    value: { type: Array, default: () => [] },

    placeholder: { type: String, default: '请选择省市区' },

  },

  data() {

    return {

      show: false,

      keyword: '',

      currentLevel: 'province',

      ctx: { provinceId: undefined, cityId: undefined, districtId: undefined },

      keyboardHeight: 0,

    }

  },

  computed: {

    displayText() {

      return formatAddressDisplay(this.value)

    },

    isSearching() {

      return !!(this.keyword || '').trim()

    },

    breadcrumbs() {

      return buildBreadcrumbFromContext(this.ctx).map((item) => ({

        ...item,

        rowKey: item.level + '-' + item.id,

      }))

    },

    listRows() {

      const rows = this.isSearching

        ? searchHitsToRows(searchAddressHits(this.keyword, this.ctx))

        : levelOptionsToRows(this.currentLevel, this.ctx)

      return rows.map((row) => ({

        ...row,

        rowKey: row.level + '-' + row.node.value,

      }))

    },

    drawerBodyStyle() {

      if (!this.keyboardHeight) {

        return {}

      }

      return {

        paddingBottom: this.keyboardHeight + 'px',

        maxHeight: `calc(70vh - ${this.keyboardHeight}px)`,

      }

    },

    listScrollStyle() {

      if (!this.keyboardHeight) {

        return {}

      }

      return {

        maxHeight: `calc(52vh - ${this.keyboardHeight}px)`,

        minHeight: '240rpx',

      }

    },

  },

  watch: {

    show(val) {

      if (val) {

        this.bindKeyboardListener()

        return

      }

      this.keyboardHeight = 0

      this.unbindKeyboardListener()

    },

  },

  beforeDestroy() {

    this.unbindKeyboardListener()

  },

  methods: {

    rowHasNextLevel,

    bindKeyboardListener() {

      if (this._keyboardBound) return

      this._keyboardBound = true

      this._keyboardHandler = (res) => {

        this.keyboardHeight = res.height || 0

      }

      uni.onKeyboardHeightChange(this._keyboardHandler)

    },

    unbindKeyboardListener() {

      if (!this._keyboardBound || !this._keyboardHandler) return

      if (typeof uni.offKeyboardHeightChange === 'function') {

        uni.offKeyboardHeightChange(this._keyboardHandler)

      }

      this._keyboardBound = false

      this._keyboardHandler = null

    },

    syncFromValue() {

      const resolved = resolveAddressValue(this.value)

      this.ctx = {

        provinceId: resolved.provinceId,

        cityId: resolved.cityId,

        districtId: resolved.districtId,

      }

      this.currentLevel = getInitialPickerLevel(resolved)

      this.keyword = ''

    },

    openDrawer() {

      this.syncFromValue()

      this.show = true

    },

    emitValue() {

      const out = buildAddressOutput(this.ctx.provinceId, this.ctx.cityId, this.ctx.districtId)

      if (out) this.$emit('change', out)

    },

    onCrumb(item) {

      this.ctx = truncateContextToBreadcrumb(this.ctx, item)

      this.currentLevel = item.level

      this.keyword = ''

    },

    onPickRow(row) {

      if (this.isSearching) {

        const hit = searchAddressHits(this.keyword, this.ctx).find(

          (h) => h.level === row.level && h.node.value === row.node.value

        )

        if (!hit) return

        this.ctx = applySearchHit(hit, this.ctx)

        if (hit.complete) {

          this.emitValue()

          this.show = false

          return

        }

        const next = getNextLevel(hit.level, this.ctx)

        this.currentLevel = next || hit.level

        this.keyword = ''

        return

      }



      const pickCtx = row.level === 'city'

        ? { provinceId: this.ctx.provinceId, cityId: row.node.value }

        : row.level === 'district'

          ? { provinceId: this.ctx.provinceId, cityId: this.ctx.cityId, districtId: row.node.value }

          : { provinceId: row.node.value, cityId: undefined, districtId: undefined }



      if (row.level === 'province') {

        this.ctx = { provinceId: row.node.value, cityId: undefined, districtId: undefined }

        this.currentLevel = getNextLevel('province', this.ctx) || 'province'

      } else if (row.level === 'city') {

        this.ctx = { ...this.ctx, cityId: row.node.value, districtId: undefined }

        if (canCompleteAfterSelect('city', pickCtx, row.node)) {

          this.emitValue()

          this.show = false

          return

        }

        this.currentLevel = getNextLevel('city', this.ctx) || 'city'

      } else if (row.level === 'district') {

        this.ctx = { ...this.ctx, districtId: row.node.value }

        this.emitValue()

        this.show = false

      }

    },

  },

}

</script>



<style scoped>

.picker-wrap { width: 100%; }

.region-trigger {

  display: flex;

  align-items: center;

  justify-content: space-between;

  width: 100%;

  min-height: 72rpx;

}

.region-text { font-size: 28rpx; color: #303133; flex: 1; }

.region-placeholder { font-size: 28rpx; color: #c0c4cc; flex: 1; }

.drawer-body { display: flex; flex-direction: column; max-height: 70vh; min-height: 50vh; box-sizing: border-box; }

.search-box { padding: 16rpx 24rpx; flex-shrink: 0; }

.crumb-scroll { white-space: nowrap; padding: 0 24rpx 16rpx; flex-shrink: 0; }

.crumbs { display: inline-flex; flex-wrap: nowrap; }

.crumb { font-size: 26rpx; color: #6acdbb; }

.crumb.muted { color: #86909c; }

.crumb-sep { color: #c0c4cc; }

.list-scroll { flex: 1; max-height: 52vh; min-height: 240rpx; box-sizing: border-box; }

.list-row {

  display: flex;

  align-items: center;

  justify-content: space-between;

  padding: 28rpx 32rpx;

  border-bottom: 1rpx solid #f5f5f5;

}

.row-label { font-size: 28rpx; color: #1d2129; flex: 1; }

.row-arrow { font-size: 36rpx; color: #c0c4cc; }

.empty { text-align: center; color: #86909c; padding: 80rpx 0; font-size: 28rpx; }

</style>

