<template>
  <!-- 预约专家：见 doc/app/预约服务/预约服务接口说明.md -->
  <view :class="pageRootClass" class="tab-page be-page" :style="pageStyle">
    <scroll-view scroll-y class="be-scroll" enable-back-to-top :show-scrollbar="false">
      <view class="be-card be-card--top">
        <!-- 第一行：左头像 | 中标题区 | 右评分（可点击） -->
        <view class="be-hero">
          <up-avatar
            v-if="photoSrc"
            shape="circle"
            :src="photoSrc"
            size="48"
            font-size="24"
          />
          <up-avatar
            v-else
            shape="circle"
            :text="avatarText"
            size="48"
            font-size="24"
            bg-color="#9ca3af"
            color="#ffffff"
          />
          <view class="be-hero__mid">
            <text class="be-hero__title text-body">{{ expertTitle }}</text>
            <text class="be-hero__sub text-body">{{ expertSub }}</text>
            <text class="be-hero__contact text-body">{{ contactLine }}</text>
          </view>
          <view class="be-hero__rate" role="button" @tap="onRateSideTap">
            <text class="be-hero__score text-body">{{ expertScoreText }}</text>
            <view class="be-hero__rate-icons">
              <up-rate
                :model-value="floorStars"
                readonly
                :touchable="false"
                :count="5"
                :size="16"
                gutter="4"
                active-color="#EAB308"
                inactive-color="#d1d5db"
              />
              <up-icon name="arrow-right" color="#22c55e" :size="18" />
            </view>
          </view>
        </view>

        <!-- 第二行起：专家介绍、地址等（与文档一致） -->
        <text class="be-line be-line--after-hero text-body">
          <text class="be-line__k">{{ $t('bookingExpertPage.labelIntro') }}</text>{{ introBody }}
        </text>
        <text class="be-line text-body"><text class="be-line__k">{{ $t('bookingExpertPage.labelAddress') }}</text>{{ detailAddress }}</text>
        <text class="be-line text-body"><text class="be-line__k">{{ $t('bookingExpertPage.labelHours') }}</text>{{ serviceHours }}</text>
        <text class="be-line text-body"><text class="be-line__k">{{ $t('bookingExpertPage.labelArea') }}</text>{{ serviceArea }}</text>
        <text class="be-line text-body"><text class="be-line__k">{{ $t('bookingExpertPage.labelFee') }}</text>{{ feeLine }}</text>
      </view>

      <view class="be-card be-card--bottom">
        <text class="be-section-title text-body">{{ $t('bookingExpertPage.pickTimeTitle') }}</text>
        <scroll-view scroll-x class="be-date-scroll" :show-scrollbar="false" enable-flex>
          <view class="be-date-row">
            <view
              v-for="chip in dateChips"
              :key="chip.key"
              class="be-chip"
              :class="{
                'be-chip--on': !chip.weekdayDisabled && selectedDateKey === chip.key,
                'be-chip--disabled': chip.weekdayDisabled
              }"
              role="button"
              @tap="onDateChipTap(chip)"
            >
              <view class="be-chip__stack">
                <text class="be-chip__name text-body">{{ chip.weekdayLabel }}</text>
                <text v-if="!chip.weekdayDisabled" class="be-chip__date text-body">{{ chip.dateShort }}</text>
                <text v-else class="be-chip__full text-body">{{ $t('bookingExpertPage.dayNotAvailable') }}</text>
              </view>
            </view>
          </view>
        </scroll-view>
        <up-divider :hairline="true" line-color="#e5e7eb" margin="12rpx 0 8rpx" />
        <up-button
          type="success"
          shape="circle"
          :disabled="bookBtnDisabled"
          :text="bookBtnText"
          @click="openBookPopup"
        />
      </view>
      <view class="be-footer-spacer" />
    </scroll-view>

    <up-popup
      :show="bookPopupShow"
      mode="center"
      :round="16"
      :close-on-click-overlay="true"
      :safe-area-inset-bottom="true"
      :custom-style="bookPopupStyle"
      @update:show="bookPopupShow = $event"
    >
      <view class="be-popup">
        <scroll-view scroll-y class="be-popup__scroll" :show-scrollbar="false">
          <text class="be-popup__h1 text-body">{{ $t('bookingExpertPage.popupBookTitle') }}</text>
          <text class="be-popup__row text-body">{{ $t('bookingExpertPage.popupExpertName') }}{{ expertTitle }}</text>
          <text class="be-popup__row text-body">{{ $t('bookingExpertPage.popupBookDate') }}{{ popupDateLine }}</text>

          <text class="be-popup__h2 text-body">{{ $t('bookingExpertPage.popupServiceTitle') }}</text>
          <up-form
            ref="bookFormRef"
            label-position="top"
            :model="formModel"
            :rules="formRules"
            label-width="100%"
            :border-bottom="false"
            error-type="toast"
          >
            <up-form-item :label="$t('bookingExpertPage.formBooker')" prop="bookerName" required>
              <up-input v-model="formModel.bookerName" border="surround" clearable />
            </up-form-item>
            <up-form-item :label="$t('bookingExpertPage.formPhone')" prop="phone" required>
              <up-input v-model="formModel.phone" type="number" maxlength="11" border="surround" clearable />
            </up-form-item>
            <up-form-item :label="$t('bookingExpertPage.formSlot')" prop="timeSlot" required>
              <view class="be-slot-row" role="button" @tap="openTimePicker">
                <up-input
                  v-model="formModel.timeSlot"
                  readonly
                  border="surround"
                  :placeholder="$t('bookingExpertPage.formSlotPh')"
                />
                <up-icon name="arrow-right" color="#78716c" :size="18" />
              </view>
            </up-form-item>
            <up-form-item :label="$t('bookingExpertPage.formAddress')" prop="address" required>
              <up-textarea
                v-model="formModel.address"
                height="120"
                count
                maxlength="200"
                border="surround"
                :placeholder="$t('bookingExpertPage.formAddressPh')"
              />
            </up-form-item>
            <up-form-item :label="$t('bookingExpertPage.formNeed')" prop="needDesc" required>
              <up-textarea
                v-model="formModel.needDesc"
                height="120"
                count
                maxlength="300"
                border="surround"
                :placeholder="$t('bookingExpertPage.formNeedPh')"
              />
            </up-form-item>
          </up-form>
        </scroll-view>

        <view class="be-popup__actions">
          <up-button
            class="be-popup__btn be-popup__btn--cancel"
            :text="$t('bookingExpertPage.btnCancel')"
            shape="circle"
            plain
            hairline
            @click="closeBookPopup"
          />
          <up-button
            class="be-popup__btn"
            type="success"
            :loading="submitting"
            :text="submitting ? $t('bookingExpertPage.submitting') : $t('bookingExpertPage.btnSubmit')"
            shape="circle"
            @click="onSubmitBook"
          />
        </view>
      </view>
    </up-popup>

    <up-picker
      :show="timePickerShow"
      :columns="[timeSlotOptions]"
      v-model="pickerModel"
      :show-toolbar="true"
      :title="$t('bookingExpertPage.formSlot')"
      popup-mode="bottom"
      :close-on-click-overlay="true"
      :round="12"
      @update:show="timePickerShow = $event"
      @confirm="onTimePickerConfirm"
    />
  </view>
</template>

<script>
import UAvatar from 'uview-plus/components/u-avatar/u-avatar.vue'
import UButton from 'uview-plus/components/u-button/u-button.vue'
import UDivider from 'uview-plus/components/u-divider/u-divider.vue'
import UForm from 'uview-plus/components/u-form/u-form.vue'
import UFormItem from 'uview-plus/components/u-form-item/u-form-item.vue'
import UIcon from 'uview-plus/components/u-icon/u-icon.vue'
import UInput from 'uview-plus/components/u-input/u-input.vue'
import UPicker from 'uview-plus/components/u-picker/u-picker.vue'
import UPopup from 'uview-plus/components/u-popup/u-popup.vue'
import URate from 'uview-plus/components/u-rate/u-rate.vue'
import UTextarea from 'uview-plus/components/u-textarea/u-textarea.vue'
import tabPage from '@/mixins/tabPage'
import pageViewport from '@/mixins/pageViewport'
import { resolveResourceUrl } from '@/utils/resourceUrl'
import { ensureApiToken } from '@/utils/apiAuth'
import { useUserStore } from '@/store/user'
import {
  BOOKING_PROVIDER_TYPE,
  checkAppointmentBooked,
  listBookingDates,
  loadBookingResourceCache,
  submitBookingAppointment
} from '@/api/bookingService'

const EXPERT_RESOURCE_TYPE = '004005'

function pad2(n) {
  return `${n}`.padStart(2, '0')
}

const DEFAULT_TIME_SLOTS = (() => {
  const r = []
  for (let h = 0; h < 24; h += 2) {
    const start = `${pad2(h)}:00`
    const endH = h + 2
    const end = endH >= 24 ? '24:00' : `${pad2(endH)}:00`
    r.push(`${start}~${end}`)
  }
  return r
})()

function parseHourMinute(hm) {
  if (!hm || typeof hm !== 'string') return null
  const parts = hm.trim().split(':')
  if (parts.length < 2) return null
  const h = parseInt(parts[0], 10)
  const m = parseInt(parts[1], 10)
  if (!Number.isFinite(h) || !Number.isFinite(m)) return null
  return { h, m }
}

function buildTimeSlotsFromService(start, end, stepHours = 2) {
  const s = parseHourMinute(start)
  const e = parseHourMinute(end)
  if (!s || !e || e.h <= s.h) {
    return DEFAULT_TIME_SLOTS.slice()
  }
  const slots = []
  for (let h = s.h; h < e.h; h += stepHours) {
    const endH = Math.min(h + stepHours, e.h)
    if (endH <= h) break
    slots.push(`${pad2(h)}:00~${pad2(endH)}:00`)
  }
  return slots.length ? slots : DEFAULT_TIME_SLOTS.slice()
}

function parseServiceWeekdays(raw) {
  if (raw == null || String(raw).trim() === '') return null
  const set = new Set()
  for (const part of String(raw).split(',')) {
    const n = parseInt(part.trim(), 10)
    if (n >= 1 && n <= 7) set.add(n)
  }
  return set.size ? set : null
}

function slotIndexFromHour(slots) {
  const list = slots && slots.length ? slots : DEFAULT_TIME_SLOTS
  const h = new Date().getHours()
  const target = `${pad2(Math.floor(h / 2) * 2)}:00`
  const idx = list.findIndex((s) => s.startsWith(target))
  return idx >= 0 ? idx : 0
}

export default {
  components: {
    'up-avatar': UAvatar,
    'up-button': UButton,
    'up-divider': UDivider,
    'up-form': UForm,
    'up-form-item': UFormItem,
    'up-icon': UIcon,
    'up-input': UInput,
    'up-picker': UPicker,
    'up-popup': UPopup,
    'up-rate': URate,
    'up-textarea': UTextarea
  },
  mixins: [tabPage, pageViewport],
  data() {
    const slots = DEFAULT_TIME_SLOTS.slice()
    const defaultSlot = slots[slotIndexFromHour(slots)] || slots[0]
    return {
      navTitleKey: 'bookingExpertPage.navTitle',
      expertId: '',
      resourceType: EXPERT_RESOURCE_TYPE,
      resource: null,
      apiDates: [],
      bookedDateMap: {},
      selectedDateKey: '',
      bookPopupShow: false,
      timePickerShow: false,
      submitting: false,
      pickerModel: [defaultSlot],
      formModel: {
        bookerName: '',
        phone: '',
        timeSlot: defaultSlot,
        address: '',
        needDesc: ''
      },
      bookPopupStyle: {
        width: '90%',
        maxWidth: '680px',
        maxHeight: '78vh',
        overflow: 'hidden',
        display: 'flex',
        flexDirection: 'column'
      }
    }
  },
  computed: {
    allowedWeekdays() {
      return parseServiceWeekdays(this.resource && this.resource.serviceWeekdays)
    },
    timeSlotOptions() {
      const r = this.resource || {}
      return buildTimeSlotsFromService(r.serviceStartTime, r.serviceEndTime)
    },
    dateChips() {
      return (this.apiDates || []).map((d) => {
        const key = d.appointDate || ''
        const weekday = d.weekday
        const allowed = this.allowedWeekdays
        const weekdayDisabled =
          allowed != null && weekday != null && !allowed.has(Number(weekday))
        return {
          key,
          dateShort: d.dateMmDd || '',
          weekday,
          weekdayLabel: this.weekdayLabelFor(d),
          weekdayDisabled
        }
      })
    },
    photoSrc() {
      const url = this.resource && this.resource.photoFileUrl
      return url ? resolveResourceUrl(url) : ''
    },
    selectedDateBooked() {
      return !!this.bookedDateMap[this.selectedDateKey]
    },
    bookBtnDisabled() {
      const chip = this.dateChips.find((c) => c.key === this.selectedDateKey)
      if (!chip || chip.weekdayDisabled) return true
      return this.selectedDateBooked
    },
    bookBtnText() {
      if (this.selectedDateBooked) return this.$t('bookingExpertPage.btnBooked')
      return this.$t('bookingExpertPage.btnBook')
    },
    avatarText() {
      const name = (this.resource && this.resource.resourceName) || ''
      return name.slice(0, 1) || '?'
    },
    expertTitle() {
      return (this.resource && this.resource.resourceName) || this.$t('bookingExpertPage.noResource')
    },
    expertSub() {
      return (this.resource && this.resource.affiliatedUnit) || this.$t('bookingServicePage.noUnit')
    },
    introBody() {
      const intro = (this.resource && this.resource.introduction) || ''
      return intro.trim() || this.$t('bookingExpertPage.noIntro')
    },
    contactLine() {
      const phone = this.resource && this.resource.contactPhone
      if (!phone) return this.$t('bookingExpertPage.contactLabel') + '—'
      return this.$t('bookingExpertPage.contactLabel') + phone
    },
    detailAddress() {
      const addr = (this.resource && this.resource.detailAddress) || ''
      return addr.trim() || this.$t('bookingExpertPage.noAddress')
    },
    serviceHours() {
      const start = this.resource && this.resource.serviceStartTime
      const end = this.resource && this.resource.serviceEndTime
      if (start && end) {
        return this.$t('bookingExpertPage.hoursTpl', { start, end })
      }
      return this.$t('bookingExpertPage.noHours')
    },
    serviceArea() {
      const area = (this.resource && this.resource.serviceArea) || ''
      return area.trim() || this.$t('bookingExpertPage.noArea')
    },
    feeLine() {
      const fee = this.resource && this.resource.feeStandard
      if (fee == null || fee === '') return this.$t('bookingExpertPage.noFee')
      return this.$t('bookingExpertPage.feeTpl', { fee })
    },
    expertScore() {
      const raw = this.resource && this.resource.expertRating
      if (raw == null || raw === '') return 0
      const n = Number(raw)
      if (!Number.isFinite(n)) return 0
      return Math.min(5, Math.max(0, n))
    },
    expertScoreText() {
      const raw = this.resource && this.resource.expertRating
      if (raw == null || raw === '') return this.$t('bookingExpertPage.noRating')
      return this.expertScore.toFixed(1)
    },
    floorStars() {
      return Math.floor(this.expertScore)
    },
    popupDateLine() {
      const chip = this.dateChips.find((c) => c.key === this.selectedDateKey)
      if (!chip || chip.weekdayDisabled) return ''
      return this.formatMdWeekday(chip)
    },
    formRules() {
      return {
        bookerName: [
          {
            required: true,
            message: this.$t('bookingExpertPage.errBooker'),
            trigger: ['blur', 'change']
          }
        ],
        phone: [
          {
            required: true,
            message: this.$t('bookingExpertPage.errPhone'),
            trigger: ['blur', 'change']
          },
          {
            pattern: /^1[3-9]\d{9}$/,
            message: this.$t('bookingExpertPage.errPhoneFmt'),
            trigger: ['blur', 'change']
          }
        ],
        timeSlot: [
          {
            required: true,
            message: this.$t('bookingExpertPage.errSlot'),
            trigger: ['change']
          }
        ],
        address: [
          {
            required: true,
            message: this.$t('bookingExpertPage.errAddress'),
            trigger: ['blur', 'change']
          }
        ],
        needDesc: [
          {
            required: true,
            message: this.$t('bookingExpertPage.errNeed'),
            trigger: ['blur', 'change']
          }
        ]
      }
    }
  },
  onLoad(query) {
    if (!ensureApiToken()) return
    const q = query || {}
    this.expertId = q.id ? decodeURIComponent(String(q.id)) : ''
    if (q.resourceType) {
      try {
        this.resourceType = decodeURIComponent(String(q.resourceType))
      } catch (e) {
        this.resourceType = String(q.resourceType)
      }
    }
    this.loadResource()
    this.loadBookingDates()
  },
  methods: {
    weekdayLabelFor(d) {
      const w = d && d.weekday
      if (w != null && w >= 1 && w <= 7) {
        const dowKey = w === 7 ? 0 : w
        return this.$t(`bookingServicePage.wd${dowKey}`)
      }
      return (d && d.weekdayName) || ''
    },
    loadResource() {
      if (!this.expertId) {
        uni.showToast({ title: this.$t('bookingExpertPage.noResource'), icon: 'none' })
        setTimeout(() => uni.navigateBack(), 1500)
        return
      }
      this.resource = loadBookingResourceCache(this.resourceType, this.expertId)
      if (!this.resource) {
        uni.showToast({ title: this.$t('bookingExpertPage.noResource'), icon: 'none' })
        setTimeout(() => uni.navigateBack(), 1500)
        return
      }
      if (this.apiDates.length) {
        this.refreshBookedFlags()
      }
    },
    loadBookingDates() {
      listBookingDates()
        .then((res) => {
          this.apiDates = Array.isArray(res.data) ? res.data : []
          this.$nextTick(() => {
            this.ensureValidDateSelection()
            if (this.expertId) {
              this.refreshBookedFlags()
            }
          })
        })
        .catch(() => {
          this.apiDates = []
        })
    },
    refreshBookedFlags() {
      if (!this.expertId || !this.apiDates.length) return Promise.resolve()
      const providerId = Number(this.expertId) || this.expertId
      const dates = this.apiDates.map((d) => d.appointDate).filter(Boolean)
      return Promise.all(
        dates.map((appointDate) =>
          checkAppointmentBooked({
            providerType: BOOKING_PROVIDER_TYPE.EXPERT,
            providerId,
            appointDate
          })
            .then((res) => ({
              appointDate,
              booked: !!(res.data && res.data.booked)
            }))
            .catch(() => ({ appointDate, booked: false }))
        )
      ).then((results) => {
        const next = { ...this.bookedDateMap }
        results.forEach(({ appointDate, booked }) => {
          next[appointDate] = booked
        })
        this.bookedDateMap = next
        this.$nextTick(() => this.ensureValidDateSelection())
      })
    },
    fetchDateBooked(appointDate) {
      if (!this.expertId || !appointDate) return Promise.resolve(false)
      return checkAppointmentBooked({
        providerType: BOOKING_PROVIDER_TYPE.EXPERT,
        providerId: Number(this.expertId) || this.expertId,
        appointDate
      })
        .then((res) => {
          const booked = !!(res.data && res.data.booked)
          this.bookedDateMap = { ...this.bookedDateMap, [appointDate]: booked }
          return booked
        })
        .catch(() => false)
    },
    formatMdWeekday(chip) {
      if (!chip || !chip.key) return ''
      return `${chip.dateShort}（${chip.weekdayLabel}）`
    },
    ensureValidDateSelection() {
      const cur = this.dateChips.find((c) => c.key === this.selectedDateKey && !c.weekdayDisabled)
      if (cur) return
      const ok = this.dateChips.find((c) => !c.weekdayDisabled)
      this.selectedDateKey = ok ? ok.key : ''
    },
    onDateChipTap(chip) {
      if (chip.weekdayDisabled) {
        uni.showToast({
          title: this.$t('bookingExpertPage.dayNotAvailable'),
          icon: 'none'
        })
        return
      }
      this.selectedDateKey = chip.key
      this.fetchDateBooked(chip.key)
    },
    onRateSideTap() {
      if (!this.expertId) return
      const q = [
        `id=${encodeURIComponent(this.expertId)}`,
        `resourceType=${encodeURIComponent(this.resourceType)}`
      ].join('&')
      uni.navigateTo({
        url: `/package-a/review-history/index?${q}`
      })
    },
    openBookPopup() {
      if (!this.resource || !this.expertId) {
        uni.showToast({ title: this.$t('bookingExpertPage.noResource'), icon: 'none' })
        return
      }
      const sel = this.dateChips.find((c) => c.key === this.selectedDateKey)
      if (!sel || sel.weekdayDisabled) {
        uni.showToast({
          title: this.$t('bookingExpertPage.toastPickDate'),
          icon: 'none'
        })
        return
      }
      if (this.selectedDateBooked) return
      this.resetBookForm()
      this.bookPopupShow = true
    },
    closeBookPopup() {
      this.bookPopupShow = false
    },
    resetBookForm() {
      const slots = this.timeSlotOptions
      const idx = slotIndexFromHour(slots)
      const slot = slots[idx] || slots[0] || ''
      const store = useUserStore()
      const name = store.displayName()
      this.formModel = {
        bookerName: name || '',
        phone: '',
        timeSlot: slot,
        address: '',
        needDesc: ''
      }
      this.pickerModel = [slot]
      this.$nextTick(() => {
        this.$refs.bookFormRef?.clearValidate?.()
      })
    },
    openTimePicker() {
      const slots = this.timeSlotOptions
      const cur = this.formModel.timeSlot
      const ok = slots.includes(cur)
      this.pickerModel = [ok ? cur : slots[slotIndexFromHour(slots)] || slots[0]]
      this.timePickerShow = true
    },
    onTimePickerConfirm(e) {
      const v = e.value && e.value[0]
      if (v) {
        this.formModel.timeSlot = v
        this.pickerModel = [v]
      }
    },
    onSubmitBook() {
      if (this.submitting) return
      this.$refs.bookFormRef
        ?.validate?.()
        .then(() => {
          this.submitting = true
          return submitBookingAppointment({
            resourceType: this.resourceType,
            resourceId: Number(this.expertId) || this.expertId,
            appointDate: this.selectedDateKey,
            appointeeName: (this.formModel.bookerName || '').trim(),
            contactPhone: (this.formModel.phone || '').trim(),
            timeSlot: this.formModel.timeSlot,
            serviceAddress: (this.formModel.address || '').trim(),
            serviceRequirement: (this.formModel.needDesc || '').trim()
          })
        })
        .then(() => {
          this.bookedDateMap = { ...this.bookedDateMap, [this.selectedDateKey]: true }
          uni.showToast({
            title: this.$t('bookingExpertPage.toastSubmitOk'),
            icon: 'success'
          })
          this.bookPopupShow = false
        })
        .catch(() => {})
        .finally(() => {
          this.submitting = false
        })
    }
  }
}
</script>

<style lang="scss" scoped>
@import '@/styles/morandi.scss';
@import '@/styles/tab-page.scss';

.be-page {
  // display: flex;
  // flex-direction: column;
  min-width: 0;
  width: 100%;
  height: 100%;
  min-height: 100%;
  overflow: hidden;
  box-sizing: border-box;
  background: $morandi-bg-page;
}

.be-scroll {
  // flex: 1;
  // min-height: 0;
  min-width: 0;
  // height: 0;
  height: 100%;
  box-sizing: border-box;
  padding: 20rpx 24rpx 24rpx;
}

.be-card {
  background: #ffffff;
  border-radius: 16rpx;
  border: 1rpx solid $morandi-border-soft;
  padding: 24rpx;
  box-sizing: border-box;
}

.be-card--top {
  margin-bottom: 10rpx;
}

.be-hero {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 16rpx;
  min-width: 0;
  margin-bottom: 16rpx;
}

.be-hero__mid {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 8rpx;
}

.be-hero__rate {
  box-sizing: border-box;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  text-align: center;
  gap: 6rpx;
  max-width: 38%;
  background: #f3f4f6;
  padding: 10rpx;
  border-radius: 10rpx;
}

.be-hero__score {
  font-size: 36rpx;
  font-weight: 600;
  color: #111827;
  line-height: 1.2;
}

.be-hero__rate-icons {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 6rpx;
}

.be-hero__title {
  font-size: 32rpx;
  font-weight: 600;
  color: #111827;
  line-height: 1.35;
  word-break: break-word;
}

.be-hero__sub {
  font-size: 24rpx;
  color: $morandi-text-secondary;
  line-height: 1.45;
  word-break: break-word;
}

.be-hero__contact {
  font-size: 22rpx;
  color: $morandi-text-muted;
  line-height: 1.45;
  word-break: break-word;
}

.be-line--after-hero {
  margin-top: 0;
}

.be-line {
  display: block;
  font-size: 24rpx;
  line-height: 1.55;
  color: #111827;
  margin-top: 12rpx;
  word-break: break-word;
}

.be-line__k {
  color: $morandi-text-muted;
  margin-right: 4rpx;
}

.be-section-title {
  display: block;
  font-size: 28rpx;
  font-weight: 600;
  color: #111827;
  margin-bottom: 16rpx;
}

.be-date-scroll {
  width: 100%;
  white-space: nowrap;
}

.be-date-row {
  display: inline-flex;
  flex-direction: row;
  align-items: stretch;
  gap: 12rpx;
  padding: 4rpx 0 8rpx;
  min-width: min-content;
}

.be-chip {
  flex-shrink: 0;
  min-width: 96rpx;
  padding: 12rpx 16rpx;
  border-radius: 12rpx;
  border: 1rpx solid #e5e7eb;
  background: #ffffff;
  box-sizing: border-box;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
}

.be-chip--on {
  background: #22c55e;
  border-color: #16a34a;
}

.be-chip--disabled {
  opacity: 0.75;
  background: #f9fafb;
  border-color: #e5e7eb;
}

.be-chip__full {
  font-size: 22rpx;
  color: #9ca3af;
  font-weight: 500;
}

.be-chip--disabled .be-chip__name {
  color: #9ca3af;
}

.be-chip__stack {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4rpx;
}

.be-chip__name {
  font-size: 24rpx;
  color: #111827;
  font-weight: 500;
}

.be-chip__date {
  font-size: 22rpx;
  color: #374151;
}

.be-chip--on .be-chip__name,
.be-chip--on .be-chip__date {
  color: #ffffff;
  font-weight: 600;
}

.be-footer-spacer {
  height: 32rpx;
}

.be-popup {
  display: flex;
  flex-direction: column;
  min-width: 0;
  max-height: 78vh;
  padding: 24rpx 24rpx 16rpx;
  box-sizing: border-box;
}

.be-popup__scroll {
  flex: 1;
  min-height: 0;
  max-height: 56vh;
}

.be-popup__h1 {
  display: block;
  font-size: 30rpx;
  font-weight: 600;
  color: #111827;
  margin-bottom: 20rpx;
}

.be-popup__h2 {
  display: block;
  font-size: 28rpx;
  font-weight: 600;
  color: #111827;
  margin: 24rpx 0 16rpx;
}

.be-popup__row {
  display: block;
  font-size: 26rpx;
  color: #374151;
  line-height: 1.5;
  margin-bottom: 8rpx;
  word-break: break-word;
}

.be-slot-row {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 8rpx;
  min-width: 0;
}

.be-slot-row :deep(.u-input) {
  flex: 1;
  min-width: 0;
}

.be-popup__actions {
  display: flex;
  flex-direction: row;
  gap: 20rpx;
  padding-top: 16rpx;
  border-top: 1rpx solid #e5e7eb;
  margin-top: 8rpx;
}

.be-popup__btn {
  flex: 1;
  min-width: 0;
}

.be-popup__btn--cancel {
  background: #ffffff !important;
}

.be-page.lang-bo {
  .be-hero__title {
    font-size: 28rpx;
    line-height: 1.75;
  }

  .be-hero__rate {
    max-width: 44%;
  }
}
</style>
